2 * Copyright (C) 2013 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.graphics.Rect;
22 import android.util.DisplayMetrics;
23 import android.view.Surface.OutOfResourcesException;
26 import java.io.FileDescriptor;
27 import java.io.PrintWriter;
30 * Interface for rendering a view hierarchy using hardware acceleration.
34 public abstract class HardwareRenderer {
35 static final String LOG_TAG = "HardwareRenderer";
38 * Name of the file that holds the shaders cache.
40 private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
43 * System property used to enable or disable dirty regions invalidation.
44 * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
45 * The default value of this property is assumed to be true.
48 * "true", to enable partial invalidates
49 * "false", to disable partial invalidates
51 static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions";
54 * System property used to enable or disable hardware rendering profiling.
55 * The default value of this property is assumed to be false.
57 * When profiling is enabled, the adb shell dumpsys gfxinfo command will
58 * output extra information about the time taken to execute by the last
62 * "true", to enable profiling
63 * "visual_bars", to enable profiling and visualize the results on screen
64 * "false", to disable profiling
66 * @see #PROFILE_PROPERTY_VISUALIZE_BARS
70 public static final String PROFILE_PROPERTY = "debug.hwui.profile";
73 * Value for {@link #PROFILE_PROPERTY}. When the property is set to this
74 * value, profiling data will be visualized on screen as a bar chart.
78 public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
81 * System property used to specify the number of frames to be used
82 * when doing hardware rendering profiling.
83 * The default value of this property is #PROFILE_MAX_FRAMES.
85 * When profiling is enabled, the adb shell dumpsys gfxinfo command will
86 * output extra information about the time taken to execute by the last
90 * "60", to set the limit of frames to 60
92 static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
95 * System property used to debug EGL configuration choice.
98 * "choice", print the chosen configuration only
99 * "all", print all possible configurations
101 static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
104 * Turn on to draw dirty regions every other frame.
107 * "true", to enable dirty regions debugging
108 * "false", to disable dirty regions debugging
112 public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
115 * Turn on to flash hardware layers when they update.
118 * "true", to enable hardware layers updates debugging
119 * "false", to disable hardware layers updates debugging
123 public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
124 "debug.hwui.show_layers_updates";
127 * Controls overdraw debugging.
130 * "false", to disable overdraw debugging
131 * "show", to show overdraw areas on screen
132 * "count", to display an overdraw counter
136 public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
139 * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
140 * value, overdraw will be shown on screen by coloring pixels.
144 public static final String OVERDRAW_PROPERTY_SHOW = "show";
147 * Turn on to debug non-rectangular clip operations.
150 * "hide", to disable this debug mode
151 * "highlight", highlight drawing commands tested against a non-rectangular clip
152 * "stencil", renders the clip region on screen when set
156 public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
157 "debug.hwui.show_non_rect_clip";
160 * A process can set this flag to false to prevent the use of hardware
165 public static boolean sRendererDisabled = false;
168 * Further hardware renderer disabling for the system process.
172 public static boolean sSystemRendererDisabled = false;
174 private boolean mEnabled;
175 private boolean mRequested = true;
178 * Invoke this method to disable hardware rendering in the current process.
182 public static void disable(boolean system) {
183 sRendererDisabled = true;
185 sSystemRendererDisabled = true;
189 public static boolean sTrimForeground = false;
192 * Controls whether or not the hardware renderer should aggressively
193 * trim memory. Note that this must not be set for any process that
194 * uses WebView! This should be only used by system_process or similar
195 * that do not go into the background.
197 public static void enableForegroundTrimming() {
198 sTrimForeground = true;
202 * Indicates whether hardware acceleration is available under any form for
203 * the view hierarchy.
205 * @return True if the view hierarchy can potentially be hardware accelerated,
208 public static boolean isAvailable() {
209 return GLES20Canvas.isAvailable();
213 * Destroys the hardware rendering context.
215 abstract void destroy();
218 * Initializes the hardware renderer for the specified surface.
220 * @param surface The surface to hardware accelerate
222 * @return True if the initialization was successful, false otherwise.
224 abstract boolean initialize(Surface surface) throws OutOfResourcesException;
227 * Updates the hardware renderer for the specified surface.
229 * @param surface The surface to hardware accelerate
231 abstract void updateSurface(Surface surface) throws OutOfResourcesException;
234 * Stops any rendering into the surface. Use this if it is unclear whether
235 * or not the surface used by the HardwareRenderer will be changing. It
236 * Suspends any rendering into the surface, but will not do any destruction
238 abstract boolean pauseSurface(Surface surface);
241 * Destroys all hardware rendering resources associated with the specified
244 * @param view The root of the view hierarchy
246 abstract void destroyHardwareResources(View view);
249 * This method should be invoked whenever the current hardware renderer
250 * context should be reset.
252 * @param surface The surface to hardware accelerate
254 abstract void invalidate(Surface surface);
257 * Detaches the layer's surface texture from the GL context and releases
260 abstract void detachSurfaceTexture(long hardwareLayer);
263 * Gets the current width of the surface. This is the width that the surface
264 * was last set to in a call to {@link #setup(int, int, Rect)}.
266 * @return the current width of the surface
268 abstract int getWidth();
271 * Gets the current height of the surface. This is the height that the surface
272 * was last set to in a call to {@link #setup(int, int, Rect)}.
274 * @return the current width of the surface
276 abstract int getHeight();
279 * Outputs extra debugging information in the specified file descriptor.
281 abstract void dumpGfxInfo(PrintWriter pw, FileDescriptor fd);
284 * Loads system properties used by the renderer. This method is invoked
285 * whenever system properties are modified. Implementations can use this
286 * to trigger live updates of the renderer based on properties.
288 * @return True if a property has changed.
290 abstract boolean loadSystemProperties();
293 * Sets the directory to use as a persistent storage for hardware rendering
296 * @param cacheDir A directory the current process can write to
300 public static void setupDiskCache(File cacheDir) {
301 ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
305 * Indicates that the specified hardware layer needs to be updated
306 * as soon as possible.
308 * @param layer The hardware layer that needs an update
310 abstract void pushLayerUpdate(HardwareLayer layer);
313 * Tells the HardwareRenderer that the layer is destroyed. The renderer
314 * should remove the layer from any update queues.
316 abstract void onLayerDestroyed(HardwareLayer layer);
319 * Interface used to receive callbacks whenever a view is drawn by
320 * a hardware renderer instance.
322 interface HardwareDrawCallbacks {
324 * Invoked before a view is drawn by a hardware renderer.
325 * This method can be used to apply transformations to the
326 * canvas but no drawing command should be issued.
328 * @param canvas The Canvas used to render the view.
330 void onHardwarePreDraw(HardwareCanvas canvas);
333 * Invoked after a view is drawn by a hardware renderer.
334 * It is safe to invoke drawing commands from this method.
336 * @param canvas The Canvas used to render the view.
338 void onHardwarePostDraw(HardwareCanvas canvas);
342 * Indicates that the content drawn by HardwareDrawCallbacks needs to
343 * be updated, which will be done by the next call to draw()
345 abstract void invalidateRoot();
348 * Draws the specified view.
350 * @param view The view to draw.
351 * @param attachInfo AttachInfo tied to the specified view.
352 * @param callbacks Callbacks invoked when drawing happens.
354 abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);
357 * Creates a new hardware layer. A hardware layer built by calling this
358 * method will be treated as a texture layer, instead of as a render target.
360 * @return A hardware layer
362 abstract HardwareLayer createTextureLayer();
364 abstract void buildLayer(RenderNode node);
366 abstract boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap);
369 * Initializes the hardware renderer for the specified surface and setup the
370 * renderer for drawing, if needed. This is invoked when the ViewAncestor has
371 * potentially lost the hardware renderer. The hardware renderer should be
372 * reinitialized and setup when the render {@link #isRequested()} and
373 * {@link #isEnabled()}.
375 * @param width The width of the drawing surface.
376 * @param height The height of the drawing surface.
377 * @param surface The surface to hardware accelerate
378 * @param surfaceInsets The drawing surface insets to apply
380 * @return true if the surface was initialized, false otherwise. Returning
381 * false might mean that the surface was already initialized.
383 boolean initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets)
384 throws OutOfResourcesException {
386 // We lost the gl context, so recreate it.
388 if (initialize(surface)) {
389 setup(width, height, surfaceInsets);
398 * Sets up the renderer for drawing.
400 * @param width The width of the drawing surface.
401 * @param height The height of the drawing surface.
402 * @param surfaceInsets The drawing surface insets to apply
404 abstract void setup(int width, int height, Rect surfaceInsets);
407 * Optional, sets the name of the renderer. Useful for debugging purposes.
409 * @param name The name of this renderer, can be null
411 abstract void setName(String name);
414 * Change the HardwareRenderer's opacity
416 abstract void setOpaque(boolean opaque);
419 * Creates a hardware renderer using OpenGL.
421 * @param translucent True if the surface is translucent, false otherwise
423 * @return A hardware renderer backed by OpenGL.
425 static HardwareRenderer create(Context context, boolean translucent) {
426 HardwareRenderer renderer = null;
427 if (GLES20Canvas.isAvailable()) {
428 renderer = new ThreadedRenderer(context, translucent);
434 * Invoke this method when the system is running out of memory. This
435 * method will attempt to recover as much memory as possible, based on
436 * the specified hint.
438 * @param level Hint about the amount of memory that should be trimmed,
439 * see {@link android.content.ComponentCallbacks}
441 static void trimMemory(int level) {
442 ThreadedRenderer.trimMemory(level);
446 * Indicates whether hardware acceleration is currently enabled.
448 * @return True if hardware acceleration is in use, false otherwise.
450 boolean isEnabled() {
455 * Indicates whether hardware acceleration is currently enabled.
457 * @param enabled True if the hardware renderer is in use, false otherwise.
459 void setEnabled(boolean enabled) {
464 * Indicates whether hardware acceleration is currently request but not
465 * necessarily enabled yet.
467 * @return True if requested, false otherwise.
469 boolean isRequested() {
474 * Indicates whether hardware acceleration is currently requested but not
475 * necessarily enabled yet.
477 * @return True to request hardware acceleration, false otherwise.
479 void setRequested(boolean requested) {
480 mRequested = requested;
484 * Blocks until all previously queued work has completed.
486 abstract void fence();
489 * Prevents any further drawing until draw() is called. This is a signal
490 * that the contents of the RenderNode tree are no longer safe to play back.
491 * In practice this usually means that there are Functor pointers in the
492 * display list that are no longer valid.
494 abstract void stopDrawing();
497 * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
499 abstract void notifyFramePending();
501 abstract void registerAnimatingRenderNode(RenderNode animator);