diff options
author | John Reck <jreck@google.com> | 2015-12-02 15:08:07 -0800 |
---|---|---|
committer | John Reck <jreck@google.com> | 2015-12-02 15:46:11 -0800 |
commit | 51aaf906f9f5fb2f117f5ccfae8be6974f7cb903 (patch) | |
tree | f9f453d32d8fe3ea29a459535d0a215b7dafefdc | |
parent | 35fc197caaecf22e8e5642963aa4807f1b43d88f (diff) |
Nuke HardwareRenderer abstract base
Bug: 17303292
Change-Id: I4a272ea4f695f4f9993e8be640fdd8530b691be0
-rw-r--r-- | core/java/android/app/ActivityThread.java | 10 | ||||
-rw-r--r-- | core/java/android/view/HardwareLayer.java | 6 | ||||
-rw-r--r-- | core/java/android/view/HardwareRenderer.java | 510 | ||||
-rw-r--r-- | core/java/android/view/ThreadedRenderer.java | 483 | ||||
-rw-r--r-- | core/java/android/view/View.java | 6 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 14 | ||||
-rw-r--r-- | core/java/android/view/WindowManagerGlobal.java | 14 | ||||
-rw-r--r-- | tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java | 4 | ||||
-rw-r--r-- | tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java | 1 |
9 files changed, 467 insertions, 581 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 802880dc7ebc..74f0c0e0e1e3 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -92,7 +92,7 @@ import android.util.Slog; import android.util.SparseIntArray; import android.util.SuperNotCalledException; import android.view.Display; -import android.view.HardwareRenderer; +import android.view.ThreadedRenderer; import android.view.View; import android.view.ViewDebug; import android.view.ViewManager; @@ -4612,7 +4612,7 @@ public final class ActivityThread { // If there are several packages in this application we won't // initialize the graphics disk caches if (packages != null && packages.length == 1) { - HardwareRenderer.setupDiskCache(cacheDir); + ThreadedRenderer.setupDiskCache(cacheDir); RenderScriptCacheDir.setupDiskCache(cacheDir); } } catch (RemoteException e) { @@ -4659,7 +4659,7 @@ public final class ActivityThread { // use hardware accelerated drawing, since this can add too much // overhead to the process. if (!ActivityManager.isHighEndGfx()) { - HardwareRenderer.disable(false); + ThreadedRenderer.disable(false); } } @@ -5529,9 +5529,9 @@ public final class ActivityThread { // accelerated drawing, since this can add too much overhead to the // process. if (!ActivityManager.isHighEndGfx()) { - HardwareRenderer.disable(true); + ThreadedRenderer.disable(true); } else { - HardwareRenderer.enableForegroundTrimming(); + ThreadedRenderer.enableForegroundTrimming(); } ActivityThread thread = new ActivityThread(); thread.attach(true); diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java index 692ca7ba99cf..a12434c0835e 100644 --- a/core/java/android/view/HardwareLayer.java +++ b/core/java/android/view/HardwareLayer.java @@ -33,10 +33,10 @@ import com.android.internal.util.VirtualRefBasePtr; * @hide */ final class HardwareLayer { - private HardwareRenderer mRenderer; + private ThreadedRenderer mRenderer; private VirtualRefBasePtr mFinalizer; - private HardwareLayer(HardwareRenderer renderer, long deferredUpdater) { + private HardwareLayer(ThreadedRenderer renderer, long deferredUpdater) { if (renderer == null || deferredUpdater == 0) { throw new IllegalArgumentException("Either hardware renderer: " + renderer + " or deferredUpdater: " + deferredUpdater + " is invalid"); @@ -140,7 +140,7 @@ final class HardwareLayer { mRenderer.pushLayerUpdate(this); } - static HardwareLayer adoptTextureLayer(HardwareRenderer renderer, long layer) { + static HardwareLayer adoptTextureLayer(ThreadedRenderer renderer, long layer) { return new HardwareLayer(renderer, layer); } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java deleted file mode 100644 index 5e5825049ed2..000000000000 --- a/core/java/android/view/HardwareRenderer.java +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.view; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Rect; -import android.view.Surface.OutOfResourcesException; - -import java.io.File; -import java.io.FileDescriptor; -import java.io.PrintWriter; - -/** - * Interface for rendering a view hierarchy using hardware acceleration. - * - * @hide - */ -public abstract class HardwareRenderer { - static final String LOG_TAG = "HardwareRenderer"; - - /** - * Name of the file that holds the shaders cache. - */ - private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache"; - - /** - * System property used to enable or disable dirty regions invalidation. - * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true. - * The default value of this property is assumed to be true. - * - * Possible values: - * "true", to enable partial invalidates - * "false", to disable partial invalidates - */ - static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions"; - - /** - * System property used to enable or disable hardware rendering profiling. - * The default value of this property is assumed to be false. - * - * When profiling is enabled, the adb shell dumpsys gfxinfo command will - * output extra information about the time taken to execute by the last - * frames. - * - * Possible values: - * "true", to enable profiling - * "visual_bars", to enable profiling and visualize the results on screen - * "false", to disable profiling - * - * @see #PROFILE_PROPERTY_VISUALIZE_BARS - * - * @hide - */ - public static final String PROFILE_PROPERTY = "debug.hwui.profile"; - - /** - * Value for {@link #PROFILE_PROPERTY}. When the property is set to this - * value, profiling data will be visualized on screen as a bar chart. - * - * @hide - */ - public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars"; - - /** - * System property used to specify the number of frames to be used - * when doing hardware rendering profiling. - * The default value of this property is #PROFILE_MAX_FRAMES. - * - * When profiling is enabled, the adb shell dumpsys gfxinfo command will - * output extra information about the time taken to execute by the last - * frames. - * - * Possible values: - * "60", to set the limit of frames to 60 - */ - static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes"; - - /** - * System property used to debug EGL configuration choice. - * - * Possible values: - * "choice", print the chosen configuration only - * "all", print all possible configurations - */ - static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config"; - - /** - * Turn on to draw dirty regions every other frame. - * - * Possible values: - * "true", to enable dirty regions debugging - * "false", to disable dirty regions debugging - * - * @hide - */ - public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions"; - - /** - * Turn on to flash hardware layers when they update. - * - * Possible values: - * "true", to enable hardware layers updates debugging - * "false", to disable hardware layers updates debugging - * - * @hide - */ - public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY = - "debug.hwui.show_layers_updates"; - - /** - * Controls overdraw debugging. - * - * Possible values: - * "false", to disable overdraw debugging - * "show", to show overdraw areas on screen - * "count", to display an overdraw counter - * - * @hide - */ - public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw"; - - /** - * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this - * value, overdraw will be shown on screen by coloring pixels. - * - * @hide - */ - public static final String OVERDRAW_PROPERTY_SHOW = "show"; - - /** - * Turn on to debug non-rectangular clip operations. - * - * Possible values: - * "hide", to disable this debug mode - * "highlight", highlight drawing commands tested against a non-rectangular clip - * "stencil", renders the clip region on screen when set - * - * @hide - */ - public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY = - "debug.hwui.show_non_rect_clip"; - - /** - * A process can set this flag to false to prevent the use of hardware - * rendering. - * - * @hide - */ - public static boolean sRendererDisabled = false; - - /** - * Further hardware renderer disabling for the system process. - * - * @hide - */ - public static boolean sSystemRendererDisabled = false; - - private boolean mEnabled; - private boolean mRequested = true; - - /** - * Invoke this method to disable hardware rendering in the current process. - * - * @hide - */ - public static void disable(boolean system) { - sRendererDisabled = true; - if (system) { - sSystemRendererDisabled = true; - } - } - - public static boolean sTrimForeground = false; - - /** - * Controls whether or not the hardware renderer should aggressively - * trim memory. Note that this must not be set for any process that - * uses WebView! This should be only used by system_process or similar - * that do not go into the background. - */ - public static void enableForegroundTrimming() { - sTrimForeground = true; - } - - /** - * Indicates whether hardware acceleration is available under any form for - * the view hierarchy. - * - * @return True if the view hierarchy can potentially be hardware accelerated, - * false otherwise - */ - public static boolean isAvailable() { - return DisplayListCanvas.isAvailable(); - } - - /** - * Destroys the hardware rendering context. - */ - abstract void destroy(); - - /** - * Initializes the hardware renderer for the specified surface. - * - * @param surface The surface to hardware accelerate - * - * @return True if the initialization was successful, false otherwise. - */ - abstract boolean initialize(Surface surface) throws OutOfResourcesException; - - /** - * Updates the hardware renderer for the specified surface. - * - * @param surface The surface to hardware accelerate - */ - abstract void updateSurface(Surface surface) throws OutOfResourcesException; - - /** - * Stops any rendering into the surface. Use this if it is unclear whether - * or not the surface used by the HardwareRenderer will be changing. It - * Suspends any rendering into the surface, but will not do any destruction - */ - abstract boolean pauseSurface(Surface surface); - - /** - * Destroys all hardware rendering resources associated with the specified - * view hierarchy. - * - * @param view The root of the view hierarchy - */ - abstract void destroyHardwareResources(View view); - - /** - * This method should be invoked whenever the current hardware renderer - * context should be reset. - * - * @param surface The surface to hardware accelerate - */ - abstract void invalidate(Surface surface); - - /** - * Detaches the layer's surface texture from the GL context and releases - * the texture id - */ - abstract void detachSurfaceTexture(long hardwareLayer); - - /** - * Gets the current width of the surface. This is the width that the surface - * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}. - * - * @return the current width of the surface - */ - abstract int getWidth(); - - /** - * Gets the current height of the surface. This is the height that the surface - * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}. - * - * @return the current width of the surface - */ - abstract int getHeight(); - - /** - * Outputs extra debugging information in the specified file descriptor. - */ - abstract void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args); - - /** - * Loads system properties used by the renderer. This method is invoked - * whenever system properties are modified. Implementations can use this - * to trigger live updates of the renderer based on properties. - * - * @return True if a property has changed. - */ - abstract boolean loadSystemProperties(); - - /** - * Sets the directory to use as a persistent storage for hardware rendering - * resources. - * - * @param cacheDir A directory the current process can write to - * - * @hide - */ - public static void setupDiskCache(File cacheDir) { - ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath()); - } - - /** - * Indicates that the specified hardware layer needs to be updated - * as soon as possible. - * - * @param layer The hardware layer that needs an update - */ - abstract void pushLayerUpdate(HardwareLayer layer); - - /** - * Tells the HardwareRenderer that the layer is destroyed. The renderer - * should remove the layer from any update queues. - */ - abstract void onLayerDestroyed(HardwareLayer layer); - - /** - * Interface used to receive callbacks whenever a view is drawn by - * a hardware renderer instance. - */ - interface HardwareDrawCallbacks { - /** - * Invoked before a view is drawn by a hardware renderer. - * This method can be used to apply transformations to the - * canvas but no drawing command should be issued. - * - * @param canvas The Canvas used to render the view. - */ - void onHardwarePreDraw(DisplayListCanvas canvas); - - /** - * Invoked after a view is drawn by a hardware renderer. - * It is safe to invoke drawing commands from this method. - * - * @param canvas The Canvas used to render the view. - */ - void onHardwarePostDraw(DisplayListCanvas canvas); - } - - /** - * Indicates that the content drawn by HardwareDrawCallbacks needs to - * be updated, which will be done by the next call to draw() - */ - abstract void invalidateRoot(); - - /** - * Draws the specified view. - * - * @param view The view to draw. - * @param attachInfo AttachInfo tied to the specified view. - * @param callbacks Callbacks invoked when drawing happens. - */ - abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks); - - /** - * Creates a new hardware layer. A hardware layer built by calling this - * method will be treated as a texture layer, instead of as a render target. - * - * @return A hardware layer - */ - abstract HardwareLayer createTextureLayer(); - - abstract void buildLayer(RenderNode node); - - abstract boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap); - - /** - * Initializes the hardware renderer for the specified surface and setup the - * renderer for drawing, if needed. This is invoked when the ViewAncestor has - * potentially lost the hardware renderer. The hardware renderer should be - * reinitialized and setup when the render {@link #isRequested()} and - * {@link #isEnabled()}. - * - * @param width The width of the drawing surface. - * @param height The height of the drawing surface. - * @param attachInfo Information about the window. - * @param surface The surface to hardware accelerate - * @param surfaceInsets The drawing surface insets to apply - * - * @return true if the surface was initialized, false otherwise. Returning - * false might mean that the surface was already initialized. - */ - boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo, - Surface surface, Rect surfaceInsets) throws OutOfResourcesException { - if (isRequested()) { - // We lost the gl context, so recreate it. - if (!isEnabled()) { - if (initialize(surface)) { - setup(width, height, attachInfo, surfaceInsets); - return true; - } - } - } - return false; - } - - /** - * Sets up the renderer for drawing. - * - * @param width The width of the drawing surface. - * @param height The height of the drawing surface. - * @param attachInfo Information about the window. - * @param surfaceInsets The drawing surface insets to apply - */ - abstract void setup(int width, int height, View.AttachInfo attachInfo, Rect surfaceInsets); - - /** - * Updates the light position based on the position of the window. - * - * @param attachInfo Information about the window. - */ - abstract void setLightCenter(View.AttachInfo attachInfo); - - /** - * Optional, sets the name of the renderer. Useful for debugging purposes. - * - * @param name The name of this renderer, can be null - */ - abstract void setName(String name); - - /** - * Change the HardwareRenderer's opacity - */ - abstract void setOpaque(boolean opaque); - - /** - * Creates a hardware renderer using OpenGL. - * - * @param translucent True if the surface is translucent, false otherwise - * - * @return A hardware renderer backed by OpenGL. - */ - static HardwareRenderer create(Context context, boolean translucent) { - HardwareRenderer renderer = null; - if (DisplayListCanvas.isAvailable()) { - renderer = new ThreadedRenderer(context, translucent); - } - return renderer; - } - - /** - * Invoke this method when the system is running out of memory. This - * method will attempt to recover as much memory as possible, based on - * the specified hint. - * - * @param level Hint about the amount of memory that should be trimmed, - * see {@link android.content.ComponentCallbacks} - */ - static void trimMemory(int level) { - ThreadedRenderer.trimMemory(level); - } - - /** - * Indicates whether hardware acceleration is currently enabled. - * - * @return True if hardware acceleration is in use, false otherwise. - */ - boolean isEnabled() { - return mEnabled; - } - - /** - * Indicates whether hardware acceleration is currently enabled. - * - * @param enabled True if the hardware renderer is in use, false otherwise. - */ - void setEnabled(boolean enabled) { - mEnabled = enabled; - } - - /** - * Indicates whether hardware acceleration is currently request but not - * necessarily enabled yet. - * - * @return True if requested, false otherwise. - */ - boolean isRequested() { - return mRequested; - } - - /** - * Indicates whether hardware acceleration is currently requested but not - * necessarily enabled yet. - * - * @return True to request hardware acceleration, false otherwise. - */ - void setRequested(boolean requested) { - mRequested = requested; - } - - /** - * Blocks until all previously queued work has completed. - */ - abstract void fence(); - - /** - * Prevents any further drawing until draw() is called. This is a signal - * that the contents of the RenderNode tree are no longer safe to play back. - * In practice this usually means that there are Functor pointers in the - * display list that are no longer valid. - */ - abstract void stopDrawing(); - - /** - * Called by {@link ViewRootImpl} when a new performTraverals is scheduled. - */ - abstract void notifyFramePending(); - - abstract void registerAnimatingRenderNode(RenderNode animator); -} diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 304e9c048b60..f2a4d7bb78fd 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -35,6 +35,7 @@ import android.view.View.AttachInfo; import com.android.internal.R; +import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; @@ -59,8 +60,230 @@ import java.lang.annotation.RetentionPolicy; * * @hide */ -public class ThreadedRenderer extends HardwareRenderer { - private static final String LOGTAG = "ThreadedRenderer"; +public final class ThreadedRenderer { + private static final String LOG_TAG = "ThreadedRenderer"; + + /** + * Name of the file that holds the shaders cache. + */ + private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache"; + + /** + * System property used to enable or disable dirty regions invalidation. + * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true. + * The default value of this property is assumed to be true. + * + * Possible values: + * "true", to enable partial invalidates + * "false", to disable partial invalidates + */ + static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions"; + + /** + * System property used to enable or disable hardware rendering profiling. + * The default value of this property is assumed to be false. + * + * When profiling is enabled, the adb shell dumpsys gfxinfo command will + * output extra information about the time taken to execute by the last + * frames. + * + * Possible values: + * "true", to enable profiling + * "visual_bars", to enable profiling and visualize the results on screen + * "false", to disable profiling + * + * @see #PROFILE_PROPERTY_VISUALIZE_BARS + * + * @hide + */ + public static final String PROFILE_PROPERTY = "debug.hwui.profile"; + + /** + * Value for {@link #PROFILE_PROPERTY}. When the property is set to this + * value, profiling data will be visualized on screen as a bar chart. + * + * @hide + */ + public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars"; + + /** + * System property used to specify the number of frames to be used + * when doing hardware rendering profiling. + * The default value of this property is #PROFILE_MAX_FRAMES. + * + * When profiling is enabled, the adb shell dumpsys gfxinfo command will + * output extra information about the time taken to execute by the last + * frames. + * + * Possible values: + * "60", to set the limit of frames to 60 + */ + static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes"; + + /** + * System property used to debug EGL configuration choice. + * + * Possible values: + * "choice", print the chosen configuration only + * "all", print all possible configurations + */ + static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config"; + + /** + * Turn on to draw dirty regions every other frame. + * + * Possible values: + * "true", to enable dirty regions debugging + * "false", to disable dirty regions debugging + * + * @hide + */ + public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions"; + + /** + * Turn on to flash hardware layers when they update. + * + * Possible values: + * "true", to enable hardware layers updates debugging + * "false", to disable hardware layers updates debugging + * + * @hide + */ + public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY = + "debug.hwui.show_layers_updates"; + + /** + * Controls overdraw debugging. + * + * Possible values: + * "false", to disable overdraw debugging + * "show", to show overdraw areas on screen + * "count", to display an overdraw counter + * + * @hide + */ + public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw"; + + /** + * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this + * value, overdraw will be shown on screen by coloring pixels. + * + * @hide + */ + public static final String OVERDRAW_PROPERTY_SHOW = "show"; + + /** + * Turn on to debug non-rectangular clip operations. + * + * Possible values: + * "hide", to disable this debug mode + * "highlight", highlight drawing commands tested against a non-rectangular clip + * "stencil", renders the clip region on screen when set + * + * @hide + */ + public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY = + "debug.hwui.show_non_rect_clip"; + + /** + * A process can set this flag to false to prevent the use of hardware + * rendering. + * + * @hide + */ + public static boolean sRendererDisabled = false; + + /** + * Further hardware renderer disabling for the system process. + * + * @hide + */ + public static boolean sSystemRendererDisabled = false; + + /** + * Invoke this method to disable hardware rendering in the current process. + * + * @hide + */ + public static void disable(boolean system) { + sRendererDisabled = true; + if (system) { + sSystemRendererDisabled = true; + } + } + + public static boolean sTrimForeground = false; + + /** + * Controls whether or not the hardware renderer should aggressively + * trim memory. Note that this must not be set for any process that + * uses WebView! This should be only used by system_process or similar + * that do not go into the background. + */ + public static void enableForegroundTrimming() { + sTrimForeground = true; + } + + /** + * Indicates whether hardware acceleration is available under any form for + * the view hierarchy. + * + * @return True if the view hierarchy can potentially be hardware accelerated, + * false otherwise + */ + public static boolean isAvailable() { + return DisplayListCanvas.isAvailable(); + } + + /** + * Sets the directory to use as a persistent storage for hardware rendering + * resources. + * + * @param cacheDir A directory the current process can write to + * + * @hide + */ + public static void setupDiskCache(File cacheDir) { + ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath()); + } + + /** + * Creates a hardware renderer using OpenGL. + * + * @param translucent True if the surface is translucent, false otherwise + * + * @return A hardware renderer backed by OpenGL. + */ + public static ThreadedRenderer create(Context context, boolean translucent) { + ThreadedRenderer renderer = null; + if (DisplayListCanvas.isAvailable()) { + renderer = new ThreadedRenderer(context, translucent); + } + return renderer; + } + + /** + * Invoke this method when the system is running out of memory. This + * method will attempt to recover as much memory as possible, based on + * the specified hint. + * + * @param level Hint about the amount of memory that should be trimmed, + * see {@link android.content.ComponentCallbacks} + */ + public static void trimMemory(int level) { + nTrimMemory(level); + } + + public static void overrideProperty(@NonNull String name, @NonNull String value) { + if (name == null || value == null) { + throw new IllegalArgumentException("name and value must be non-null"); + } + nOverrideProperty(name, value); + } + + public static void dumpProfileData(byte[] data, FileDescriptor fd) { + nDumpProfileData(data, fd); + } // Keep in sync with DrawFrameTask.h SYNC_* flags // Nothing interesting to report @@ -113,6 +336,9 @@ public class ThreadedRenderer extends HardwareRenderer { private final Rect mCurrentContentBounds = new Rect(); private final Rect mStagedContentBounds = new Rect(); + private boolean mEnabled; + private boolean mRequested = true; + ThreadedRenderer(Context context, boolean translucent) { final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0); mLightY = a.getDimension(R.styleable.Lighting_lightY, 0); @@ -133,13 +359,53 @@ public class ThreadedRenderer extends HardwareRenderer { loadSystemProperties(); } - @Override + /** + * Destroys the hardware rendering context. + */ void destroy() { mInitialized = false; updateEnabledState(null); nDestroy(mNativeProxy); } + /** + * Indicates whether hardware acceleration is currently enabled. + * + * @return True if hardware acceleration is in use, false otherwise. + */ + boolean isEnabled() { + return mEnabled; + } + + /** + * Indicates whether hardware acceleration is currently enabled. + * + * @param enabled True if the hardware renderer is in use, false otherwise. + */ + void setEnabled(boolean enabled) { + mEnabled = enabled; + } + + /** + * Indicates whether hardware acceleration is currently request but not + * necessarily enabled yet. + * + * @return True if requested, false otherwise. + */ + boolean isRequested() { + return mRequested; + } + + /** + * Indicates whether hardware acceleration is currently requested but not + * necessarily enabled yet. + * + * @return True to request hardware acceleration, false otherwise. + */ + void setRequested(boolean requested) { + mRequested = requested; + } + private void updateEnabledState(Surface surface) { if (surface == null || !surface.isValid()) { setEnabled(false); @@ -148,7 +414,13 @@ public class ThreadedRenderer extends HardwareRenderer { } } - @Override + /** + * Initializes the hardware renderer for the specified surface. + * + * @param surface The surface to hardware accelerate + * + * @return True if the initialization was successful, false otherwise. + */ boolean initialize(Surface surface) throws OutOfResourcesException { mInitialized = true; updateEnabledState(surface); @@ -156,18 +428,61 @@ public class ThreadedRenderer extends HardwareRenderer { return status; } - @Override + /** + * Initializes the hardware renderer for the specified surface and setup the + * renderer for drawing, if needed. This is invoked when the ViewAncestor has + * potentially lost the hardware renderer. The hardware renderer should be + * reinitialized and setup when the render {@link #isRequested()} and + * {@link #isEnabled()}. + * + * @param width The width of the drawing surface. + * @param height The height of the drawing surface. + * @param attachInfo Information about the window. + * @param surface The surface to hardware accelerate + * @param surfaceInsets The drawing surface insets to apply + * + * @return true if the surface was initialized, false otherwise. Returning + * false might mean that the surface was already initialized. + */ + boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo, + Surface surface, Rect surfaceInsets) throws OutOfResourcesException { + if (isRequested()) { + // We lost the gl context, so recreate it. + if (!isEnabled()) { + if (initialize(surface)) { + setup(width, height, attachInfo, surfaceInsets); + return true; + } + } + } + return false; + } + + /** + * Updates the hardware renderer for the specified surface. + * + * @param surface The surface to hardware accelerate + */ void updateSurface(Surface surface) throws OutOfResourcesException { updateEnabledState(surface); nUpdateSurface(mNativeProxy, surface); } - @Override + /** + * Stops any rendering into the surface. Use this if it is unclear whether + * or not the surface used by the HardwareRenderer will be changing. It + * Suspends any rendering into the surface, but will not do any destruction + */ boolean pauseSurface(Surface surface) { return nPauseSurface(mNativeProxy, surface); } - @Override + /** + * Destroys all hardware rendering resources associated with the specified + * view hierarchy. + * + * @param view The root of the view hierarchy + */ void destroyHardwareResources(View view) { destroyResources(view); nDestroyHardwareResources(mNativeProxy); @@ -186,17 +501,32 @@ public class ThreadedRenderer extends HardwareRenderer { } } - @Override + /** + * This method should be invoked whenever the current hardware renderer + * context should be reset. + * + * @param surface The surface to hardware accelerate + */ void invalidate(Surface surface) { updateSurface(surface); } - @Override + /** + * Detaches the layer's surface texture from the GL context and releases + * the texture id + */ void detachSurfaceTexture(long hardwareLayer) { nDetachSurfaceTexture(mNativeProxy, hardwareLayer); } - @Override + /** + * Sets up the renderer for drawing. + * + * @param width The width of the drawing surface. + * @param height The height of the drawing surface. + * @param attachInfo Information about the window. + * @param surfaceInsets The drawing surface insets to apply + */ void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) { mWidth = width; mHeight = height; @@ -226,7 +556,11 @@ public class ThreadedRenderer extends HardwareRenderer { setLightCenter(attachInfo); } - @Override + /** + * Updates the light position based on the position of the window. + * + * @param attachInfo Information about the window. + */ void setLightCenter(AttachInfo attachInfo) { // Adjust light position for window offsets. final Point displaySize = attachInfo.mPoint; @@ -237,22 +571,36 @@ public class ThreadedRenderer extends HardwareRenderer { nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ); } - @Override + /** + * Change the HardwareRenderer's opacity + */ void setOpaque(boolean opaque) { nSetOpaque(mNativeProxy, opaque && !mHasInsets); } - @Override + /** + * Gets the current width of the surface. This is the width that the surface + * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}. + * + * @return the current width of the surface + */ int getWidth() { return mWidth; } - @Override + /** + * Gets the current height of the surface. This is the height that the surface + * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}. + * + * @return the current width of the surface + */ int getHeight() { return mHeight; } - @Override + /** + * Outputs extra debugging information in the specified file descriptor. + */ void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) { pw.flush(); int flags = 0; @@ -269,7 +617,13 @@ public class ThreadedRenderer extends HardwareRenderer { nDumpProfileInfo(mNativeProxy, fd, flags); } - @Override + /** + * Loads system properties used by the renderer. This method is invoked + * whenever system properties are modified. Implementations can use this + * to trigger live updates of the renderer based on properties. + * + * @return True if a property has changed. + */ boolean loadSystemProperties() { boolean changed = nLoadSystemProperties(mNativeProxy); if (changed) { @@ -353,12 +707,44 @@ public class ThreadedRenderer extends HardwareRenderer { mStagedContentBounds.set(left, top, right, bottom); } - @Override + /** + * Interface used to receive callbacks whenever a view is drawn by + * a hardware renderer instance. + */ + interface HardwareDrawCallbacks { + /** + * Invoked before a view is drawn by a hardware renderer. + * This method can be used to apply transformations to the + * canvas but no drawing command should be issued. + * + * @param canvas The Canvas used to render the view. + */ + void onHardwarePreDraw(DisplayListCanvas canvas); + + /** + * Invoked after a view is drawn by a hardware renderer. + * It is safe to invoke drawing commands from this method. + * + * @param canvas The Canvas used to render the view. + */ + void onHardwarePostDraw(DisplayListCanvas canvas); + } + + /** + * Indicates that the content drawn by HardwareDrawCallbacks needs to + * be updated, which will be done by the next call to draw() + */ void invalidateRoot() { mRootNodeNeedsUpdate = true; } - @Override + /** + * Draws the specified view. + * + * @param view The view to draw. + * @param attachInfo AttachInfo tied to the specified view. + * @param callbacks Callbacks invoked when drawing happens. + */ void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) { attachInfo.mIgnoreDirtyState = true; @@ -409,54 +795,80 @@ public class ThreadedRenderer extends HardwareRenderer { nInvokeFunctor(functor, waitForCompletion); } - @Override + /** + * Creates a new hardware layer. A hardware layer built by calling this + * method will be treated as a texture layer, instead of as a render target. + * + * @return A hardware layer + */ HardwareLayer createTextureLayer() { long layer = nCreateTextureLayer(mNativeProxy); return HardwareLayer.adoptTextureLayer(this, layer); } - @Override + void buildLayer(RenderNode node) { nBuildLayer(mNativeProxy, node.getNativeDisplayList()); } - @Override + boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) { return nCopyLayerInto(mNativeProxy, layer.getDeferredLayerUpdater(), bitmap); } - @Override + /** + * Indicates that the specified hardware layer needs to be updated + * as soon as possible. + * + * @param layer The hardware layer that needs an update + */ void pushLayerUpdate(HardwareLayer layer) { nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater()); } - @Override + /** + * Tells the HardwareRenderer that the layer is destroyed. The renderer + * should remove the layer from any update queues. + */ void onLayerDestroyed(HardwareLayer layer) { nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater()); } - @Override + /** + * Optional, sets the name of the renderer. Useful for debugging purposes. + * + * @param name The name of this renderer, can be null + */ void setName(String name) { nSetName(mNativeProxy, name); } - @Override + /** + * Blocks until all previously queued work has completed. + */ void fence() { nFence(mNativeProxy); } - @Override + /** + * Prevents any further drawing until draw() is called. This is a signal + * that the contents of the RenderNode tree are no longer safe to play back. + * In practice this usually means that there are Functor pointers in the + * display list that are no longer valid. + */ void stopDrawing() { nStopDrawing(mNativeProxy); } - @Override + /** + * Called by {@link ViewRootImpl} when a new performTraverals is scheduled. + */ public void notifyFramePending() { nNotifyFramePending(mNativeProxy); } - @Override + void registerAnimatingRenderNode(RenderNode animator) { nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode); } @@ -475,21 +887,6 @@ public class ThreadedRenderer extends HardwareRenderer { } } - static void trimMemory(int level) { - nTrimMemory(level); - } - - public static void overrideProperty(@NonNull String name, @NonNull String value) { - if (name == null || value == null) { - throw new IllegalArgumentException("name and value must be non-null"); - } - nOverrideProperty(name, value); - } - - public static void dumpProfileData(byte[] data, FileDescriptor fd) { - nDumpProfileData(data, fd); - } - private static class ProcessInitializer { static ProcessInitializer sInstance = new ProcessInitializer(); private static IBinder sProcToken; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index da66f97c8e81..1b8ef9e8c5e7 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -13270,7 +13270,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, /** * @hide */ - public HardwareRenderer getHardwareRenderer() { + public ThreadedRenderer getHardwareRenderer() { return mAttachInfo != null ? mAttachInfo.mHardwareRenderer : null; } @@ -17436,7 +17436,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (hasWindowFocus()) viewStateIndex |= StateSet.VIEW_STATE_WINDOW_FOCUSED; if ((privateFlags & PFLAG_ACTIVATED) != 0) viewStateIndex |= StateSet.VIEW_STATE_ACTIVATED; if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested && - HardwareRenderer.isAvailable()) { + ThreadedRenderer.isAvailable()) { // This is set if HW acceleration is requested, even if the current // process doesn't allow it. This is just to allow app preview // windows to better match their app. @@ -22054,7 +22054,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, boolean mHardwareAccelerated; boolean mHardwareAccelerationRequested; - HardwareRenderer mHardwareRenderer; + ThreadedRenderer mHardwareRenderer; List<RenderNode> mPendingAnimatingRenderNodes; /** diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 3c9310da6f8b..b7bb9a3b983f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -102,7 +102,7 @@ import java.util.List; */ @SuppressWarnings({"EmptyCatchBlock", "PointlessBooleanExpression"}) public final class ViewRootImpl implements ViewParent, - View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks { + View.AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks { private static final String TAG = "ViewRootImpl"; private static final boolean DBG = false; private static final boolean LOCAL_LOGV = false; @@ -761,7 +761,7 @@ public final class ViewRootImpl implements ViewParent, (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0; if (hardwareAccelerated) { - if (!HardwareRenderer.isAvailable()) { + if (!ThreadedRenderer.isAvailable()) { return; } @@ -784,8 +784,8 @@ public final class ViewRootImpl implements ViewParent, // shows for launching applications, so they will look more like // the app being launched. mAttachInfo.mHardwareAccelerationRequested = true; - } else if (!HardwareRenderer.sRendererDisabled - || (HardwareRenderer.sSystemRendererDisabled && forceHwAccelerated)) { + } else if (!ThreadedRenderer.sRendererDisabled + || (ThreadedRenderer.sSystemRendererDisabled && forceHwAccelerated)) { if (mAttachInfo.mHardwareRenderer != null) { mAttachInfo.mHardwareRenderer.destroy(); } @@ -794,7 +794,7 @@ public final class ViewRootImpl implements ViewParent, final boolean hasSurfaceInsets = insets.left != 0 || insets.right != 0 || insets.top != 0 || insets.bottom != 0; final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets; - mAttachInfo.mHardwareRenderer = HardwareRenderer.create(mContext, translucent); + mAttachInfo.mHardwareRenderer = ThreadedRenderer.create(mContext, translucent); if (mAttachInfo.mHardwareRenderer != null) { mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString()); mAttachInfo.mHardwareAccelerated = @@ -1865,7 +1865,7 @@ public final class ViewRootImpl implements ViewParent, } } - final HardwareRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer; + final ThreadedRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer; if (hardwareRenderer != null && hardwareRenderer.isEnabled()) { if (hwInitialized || mWidth != hardwareRenderer.getWidth() @@ -5733,7 +5733,7 @@ public final class ViewRootImpl implements ViewParent, } private void destroyHardwareRenderer() { - HardwareRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer; + ThreadedRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer; if (hardwareRenderer != null) { if (mView != null) { diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index c08e1b5803c4..8c68e922b951 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -425,7 +425,7 @@ public final class WindowManagerGlobal { mDyingViews.remove(view); } } - if (HardwareRenderer.sTrimForeground && HardwareRenderer.isAvailable()) { + if (ThreadedRenderer.sTrimForeground && ThreadedRenderer.isAvailable()) { doTrimForeground(); } } @@ -452,7 +452,7 @@ public final class WindowManagerGlobal { } public void trimMemory(int level) { - if (HardwareRenderer.isAvailable()) { + if (ThreadedRenderer.isAvailable()) { if (shouldDestroyEglContext(level)) { // Destroy all hardware surfaces and resources associated to // known windows @@ -465,16 +465,16 @@ public final class WindowManagerGlobal { level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; } - HardwareRenderer.trimMemory(level); + ThreadedRenderer.trimMemory(level); - if (HardwareRenderer.sTrimForeground) { + if (ThreadedRenderer.sTrimForeground) { doTrimForeground(); } } } public static void trimForeground() { - if (HardwareRenderer.sTrimForeground && HardwareRenderer.isAvailable()) { + if (ThreadedRenderer.sTrimForeground && ThreadedRenderer.isAvailable()) { WindowManagerGlobal wm = WindowManagerGlobal.getInstance(); wm.doTrimForeground(); } @@ -494,7 +494,7 @@ public final class WindowManagerGlobal { } } if (!hasVisibleWindows) { - HardwareRenderer.trimMemory( + ThreadedRenderer.trimMemory( ComponentCallbacks2.TRIM_MEMORY_COMPLETE); } } @@ -513,7 +513,7 @@ public final class WindowManagerGlobal { String name = getWindowName(root); pw.printf("\n\t%s (visibility=%d)", name, root.getHostVisibility()); - HardwareRenderer renderer = + ThreadedRenderer renderer = root.getView().mAttachInfo.mHardwareRenderer; if (renderer != null) { renderer.dumpGfxInfo(pw, fd, args); diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java index 7628c5c24941..63fa3f921560 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java @@ -25,7 +25,7 @@ import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.DisplayListCanvas; -import android.view.HardwareRenderer; +import android.view.ThreadedRenderer; import android.view.RenderNode; import android.view.ThreadedRenderer; import android.view.View; @@ -120,7 +120,7 @@ public class MultiProducerActivity extends Activity implements OnClickListener { if (view == null) { view.postDelayed(mSetup, 50); } - HardwareRenderer renderer = view.getHardwareRenderer(); + ThreadedRenderer renderer = view.getHardwareRenderer(); if (renderer == null || view.getWidth() == 0) { view.postDelayed(mSetup, 50); } diff --git a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java index fc5426c79240..ee4c8343d9e9 100644 --- a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java +++ b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java @@ -6,7 +6,6 @@ import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.util.Log; -import android.view.HardwareRenderer; import android.view.RenderNodeAnimator; import android.view.View; import android.widget.AdapterView; |