• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2013 The Android Open Source Project
3   *
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
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
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.
15   */
16  
17  package android.view;
18  
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;
24  
25  import java.io.File;
26  import java.io.FileDescriptor;
27  import java.io.PrintWriter;
28  
29  /**
30   * Interface for rendering a view hierarchy using hardware acceleration.
31   *
32   * @hide
33   */
34  public abstract class HardwareRenderer {
35      static final String LOG_TAG = "HardwareRenderer";
36  
37      /**
38       * Name of the file that holds the shaders cache.
39       */
40      private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
41  
42      /**
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.
46       *
47       * Possible values:
48       * "true", to enable partial invalidates
49       * "false", to disable partial invalidates
50       */
51      static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions";
52  
53      /**
54       * System property used to enable or disable hardware rendering profiling.
55       * The default value of this property is assumed to be false.
56       *
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
59       * frames.
60       *
61       * Possible values:
62       * "true", to enable profiling
63       * "visual_bars", to enable profiling and visualize the results on screen
64       * "false", to disable profiling
65       *
66       * @see #PROFILE_PROPERTY_VISUALIZE_BARS
67       *
68       * @hide
69       */
70      public static final String PROFILE_PROPERTY = "debug.hwui.profile";
71  
72      /**
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.
75       *
76       * @hide
77       */
78      public static final String PROFILE_PROPERTY_VISUALIZE_BARS = "visual_bars";
79  
80      /**
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.
84       *
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
87       * frames.
88       *
89       * Possible values:
90       * "60", to set the limit of frames to 60
91       */
92      static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes";
93  
94      /**
95       * System property used to debug EGL configuration choice.
96       *
97       * Possible values:
98       * "choice", print the chosen configuration only
99       * "all", print all possible configurations
100       */
101      static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config";
102  
103      /**
104       * Turn on to draw dirty regions every other frame.
105       *
106       * Possible values:
107       * "true", to enable dirty regions debugging
108       * "false", to disable dirty regions debugging
109       *
110       * @hide
111       */
112      public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions";
113  
114      /**
115       * Turn on to flash hardware layers when they update.
116       *
117       * Possible values:
118       * "true", to enable hardware layers updates debugging
119       * "false", to disable hardware layers updates debugging
120       *
121       * @hide
122       */
123      public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
124              "debug.hwui.show_layers_updates";
125  
126      /**
127       * Controls overdraw debugging.
128       *
129       * Possible values:
130       * "false", to disable overdraw debugging
131       * "show", to show overdraw areas on screen
132       * "count", to display an overdraw counter
133       *
134       * @hide
135       */
136      public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";
137  
138      /**
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.
141       *
142       * @hide
143       */
144      public static final String OVERDRAW_PROPERTY_SHOW = "show";
145  
146      /**
147       * Turn on to debug non-rectangular clip operations.
148       *
149       * Possible values:
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
153       *
154       * @hide
155       */
156      public static final String DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY =
157              "debug.hwui.show_non_rect_clip";
158  
159      /**
160       * A process can set this flag to false to prevent the use of hardware
161       * rendering.
162       *
163       * @hide
164       */
165      public static boolean sRendererDisabled = false;
166  
167      /**
168       * Further hardware renderer disabling for the system process.
169       *
170       * @hide
171       */
172      public static boolean sSystemRendererDisabled = false;
173  
174      private boolean mEnabled;
175      private boolean mRequested = true;
176  
177      /**
178       * Invoke this method to disable hardware rendering in the current process.
179       *
180       * @hide
181       */
disable(boolean system)182      public static void disable(boolean system) {
183          sRendererDisabled = true;
184          if (system) {
185              sSystemRendererDisabled = true;
186          }
187      }
188  
189      public static boolean sTrimForeground = false;
190  
191      /**
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.
196       */
enableForegroundTrimming()197      public static void enableForegroundTrimming() {
198          sTrimForeground = true;
199      }
200  
201      /**
202       * Indicates whether hardware acceleration is available under any form for
203       * the view hierarchy.
204       *
205       * @return True if the view hierarchy can potentially be hardware accelerated,
206       *         false otherwise
207       */
isAvailable()208      public static boolean isAvailable() {
209          return GLES20Canvas.isAvailable();
210      }
211  
212      /**
213       * Destroys the hardware rendering context.
214       */
destroy()215      abstract void destroy();
216  
217      /**
218       * Initializes the hardware renderer for the specified surface.
219       *
220       * @param surface The surface to hardware accelerate
221       *
222       * @return True if the initialization was successful, false otherwise.
223       */
initialize(Surface surface)224      abstract boolean initialize(Surface surface) throws OutOfResourcesException;
225  
226      /**
227       * Updates the hardware renderer for the specified surface.
228       *
229       * @param surface The surface to hardware accelerate
230       */
updateSurface(Surface surface)231      abstract void updateSurface(Surface surface) throws OutOfResourcesException;
232  
233      /**
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
237       */
pauseSurface(Surface surface)238      abstract boolean pauseSurface(Surface surface);
239  
240      /**
241       * Destroys all hardware rendering resources associated with the specified
242       * view hierarchy.
243       *
244       * @param view The root of the view hierarchy
245       */
destroyHardwareResources(View view)246      abstract void destroyHardwareResources(View view);
247  
248      /**
249       * This method should be invoked whenever the current hardware renderer
250       * context should be reset.
251       *
252       * @param surface The surface to hardware accelerate
253       */
invalidate(Surface surface)254      abstract void invalidate(Surface surface);
255  
256      /**
257       * Detaches the layer's surface texture from the GL context and releases
258       * the texture id
259       */
detachSurfaceTexture(long hardwareLayer)260      abstract void detachSurfaceTexture(long hardwareLayer);
261  
262      /**
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)}.
265       *
266       * @return the current width of the surface
267       */
getWidth()268      abstract int getWidth();
269  
270      /**
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)}.
273       *
274       * @return the current width of the surface
275       */
getHeight()276      abstract int getHeight();
277  
278      /**
279       * Outputs extra debugging information in the specified file descriptor.
280       */
dumpGfxInfo(PrintWriter pw, FileDescriptor fd)281      abstract void dumpGfxInfo(PrintWriter pw, FileDescriptor fd);
282  
283      /**
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.
287       *
288       * @return True if a property has changed.
289       */
loadSystemProperties()290      abstract boolean loadSystemProperties();
291  
292      /**
293       * Sets the directory to use as a persistent storage for hardware rendering
294       * resources.
295       *
296       * @param cacheDir A directory the current process can write to
297       *
298       * @hide
299       */
setupDiskCache(File cacheDir)300      public static void setupDiskCache(File cacheDir) {
301          ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
302      }
303  
304      /**
305       * Indicates that the specified hardware layer needs to be updated
306       * as soon as possible.
307       *
308       * @param layer The hardware layer that needs an update
309       */
pushLayerUpdate(HardwareLayer layer)310      abstract void pushLayerUpdate(HardwareLayer layer);
311  
312      /**
313       * Tells the HardwareRenderer that the layer is destroyed. The renderer
314       * should remove the layer from any update queues.
315       */
onLayerDestroyed(HardwareLayer layer)316      abstract void onLayerDestroyed(HardwareLayer layer);
317  
318      /**
319       * Interface used to receive callbacks whenever a view is drawn by
320       * a hardware renderer instance.
321       */
322      interface HardwareDrawCallbacks {
323          /**
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.
327           *
328           * @param canvas The Canvas used to render the view.
329           */
onHardwarePreDraw(HardwareCanvas canvas)330          void onHardwarePreDraw(HardwareCanvas canvas);
331  
332          /**
333           * Invoked after a view is drawn by a hardware renderer.
334           * It is safe to invoke drawing commands from this method.
335           *
336           * @param canvas The Canvas used to render the view.
337           */
onHardwarePostDraw(HardwareCanvas canvas)338          void onHardwarePostDraw(HardwareCanvas canvas);
339      }
340  
341      /**
342       *  Indicates that the content drawn by HardwareDrawCallbacks needs to
343       *  be updated, which will be done by the next call to draw()
344       */
invalidateRoot()345      abstract void invalidateRoot();
346  
347      /**
348       * Draws the specified view.
349       *
350       * @param view The view to draw.
351       * @param attachInfo AttachInfo tied to the specified view.
352       * @param callbacks Callbacks invoked when drawing happens.
353       */
draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks)354      abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);
355  
356      /**
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.
359       *
360       * @return A hardware layer
361       */
createTextureLayer()362      abstract HardwareLayer createTextureLayer();
363  
buildLayer(RenderNode node)364      abstract void buildLayer(RenderNode node);
365  
copyLayerInto(HardwareLayer layer, Bitmap bitmap)366      abstract boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap);
367  
368      /**
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()}.
374       *
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
379       *
380       * @return true if the surface was initialized, false otherwise. Returning
381       *         false might mean that the surface was already initialized.
382       */
initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets)383      boolean initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets)
384              throws OutOfResourcesException {
385          if (isRequested()) {
386              // We lost the gl context, so recreate it.
387              if (!isEnabled()) {
388                  if (initialize(surface)) {
389                      setup(width, height, surfaceInsets);
390                      return true;
391                  }
392              }
393          }
394          return false;
395      }
396  
397      /**
398       * Sets up the renderer for drawing.
399       *
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
403       */
setup(int width, int height, Rect surfaceInsets)404      abstract void setup(int width, int height, Rect surfaceInsets);
405  
406      /**
407       * Optional, sets the name of the renderer. Useful for debugging purposes.
408       *
409       * @param name The name of this renderer, can be null
410       */
setName(String name)411      abstract void setName(String name);
412  
413      /**
414       * Change the HardwareRenderer's opacity
415       */
setOpaque(boolean opaque)416      abstract void setOpaque(boolean opaque);
417  
418      /**
419       * Creates a hardware renderer using OpenGL.
420       *
421       * @param translucent True if the surface is translucent, false otherwise
422       *
423       * @return A hardware renderer backed by OpenGL.
424       */
create(Context context, boolean translucent)425      static HardwareRenderer create(Context context, boolean translucent) {
426          HardwareRenderer renderer = null;
427          if (GLES20Canvas.isAvailable()) {
428              renderer = new ThreadedRenderer(context, translucent);
429          }
430          return renderer;
431      }
432  
433      /**
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.
437       *
438       * @param level Hint about the amount of memory that should be trimmed,
439       *              see {@link android.content.ComponentCallbacks}
440       */
trimMemory(int level)441      static void trimMemory(int level) {
442          ThreadedRenderer.trimMemory(level);
443      }
444  
445      /**
446       * Indicates whether hardware acceleration is currently enabled.
447       *
448       * @return True if hardware acceleration is in use, false otherwise.
449       */
isEnabled()450      boolean isEnabled() {
451          return mEnabled;
452      }
453  
454      /**
455       * Indicates whether hardware acceleration is currently enabled.
456       *
457       * @param enabled True if the hardware renderer is in use, false otherwise.
458       */
setEnabled(boolean enabled)459      void setEnabled(boolean enabled) {
460          mEnabled = enabled;
461      }
462  
463      /**
464       * Indicates whether hardware acceleration is currently request but not
465       * necessarily enabled yet.
466       *
467       * @return True if requested, false otherwise.
468       */
isRequested()469      boolean isRequested() {
470          return mRequested;
471      }
472  
473      /**
474       * Indicates whether hardware acceleration is currently requested but not
475       * necessarily enabled yet.
476       *
477       * @return True to request hardware acceleration, false otherwise.
478       */
setRequested(boolean requested)479      void setRequested(boolean requested) {
480          mRequested = requested;
481      }
482  
483      /**
484       * Blocks until all previously queued work has completed.
485       */
fence()486      abstract void fence();
487  
488      /**
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.
493       */
stopDrawing()494      abstract void stopDrawing();
495  
496      /**
497       * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
498       */
notifyFramePending()499      abstract void notifyFramePending();
500  
registerAnimatingRenderNode(RenderNode animator)501      abstract void registerAnimatingRenderNode(RenderNode animator);
502  }
503