HardwareRenderer.java revision 3e8249568cc428296ac76c7ddce3f0382d40fe5b
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 17package android.view; 18 19import android.content.Context; 20import android.graphics.Bitmap; 21import android.graphics.Rect; 22import android.util.DisplayMetrics; 23import android.view.Surface.OutOfResourcesException; 24 25import java.io.File; 26import java.io.FileDescriptor; 27import java.io.PrintWriter; 28 29/** 30 * Interface for rendering a view hierarchy using hardware acceleration. 31 * 32 * @hide 33 */ 34public 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 */ 182 public static void disable(boolean system) { 183 sRendererDisabled = true; 184 if (system) { 185 sSystemRendererDisabled = true; 186 } 187 } 188 189 /** 190 * Indicates whether hardware acceleration is available under any form for 191 * the view hierarchy. 192 * 193 * @return True if the view hierarchy can potentially be hardware accelerated, 194 * false otherwise 195 */ 196 public static boolean isAvailable() { 197 return GLES20Canvas.isAvailable(); 198 } 199 200 /** 201 * Destroys the hardware rendering context. 202 */ 203 abstract void destroy(); 204 205 /** 206 * Initializes the hardware renderer for the specified surface. 207 * 208 * @param surface The surface to hardware accelerate 209 * 210 * @return True if the initialization was successful, false otherwise. 211 */ 212 abstract boolean initialize(Surface surface) throws OutOfResourcesException; 213 214 /** 215 * Updates the hardware renderer for the specified surface. 216 * 217 * @param surface The surface to hardware accelerate 218 */ 219 abstract void updateSurface(Surface surface) throws OutOfResourcesException; 220 221 /** 222 * Stops any rendering into the surface. Use this if it is unclear whether 223 * or not the surface used by the HardwareRenderer will be changing. It 224 * Suspends any rendering into the surface, but will not do any destruction 225 */ 226 abstract void pauseSurface(Surface surface); 227 228 /** 229 * Destroys all hardware rendering resources associated with the specified 230 * view hierarchy. 231 * 232 * @param view The root of the view hierarchy 233 */ 234 abstract void destroyHardwareResources(View view); 235 236 /** 237 * This method should be invoked whenever the current hardware renderer 238 * context should be reset. 239 * 240 * @param surface The surface to hardware accelerate 241 */ 242 abstract void invalidate(Surface surface); 243 244 /** 245 * Detaches the layer's surface texture from the GL context and releases 246 * the texture id 247 */ 248 abstract void detachSurfaceTexture(long hardwareLayer); 249 250 /** 251 * Gets the current width of the surface. This is the width that the surface 252 * was last set to in a call to {@link #setup(int, int, Rect)}. 253 * 254 * @return the current width of the surface 255 */ 256 abstract int getWidth(); 257 258 /** 259 * Gets the current height of the surface. This is the height that the surface 260 * was last set to in a call to {@link #setup(int, int, Rect)}. 261 * 262 * @return the current width of the surface 263 */ 264 abstract int getHeight(); 265 266 /** 267 * Outputs extra debugging information in the specified file descriptor. 268 */ 269 abstract void dumpGfxInfo(PrintWriter pw, FileDescriptor fd); 270 271 /** 272 * Loads system properties used by the renderer. This method is invoked 273 * whenever system properties are modified. Implementations can use this 274 * to trigger live updates of the renderer based on properties. 275 * 276 * @return True if a property has changed. 277 */ 278 abstract boolean loadSystemProperties(); 279 280 /** 281 * Sets the directory to use as a persistent storage for hardware rendering 282 * resources. 283 * 284 * @param cacheDir A directory the current process can write to 285 * 286 * @hide 287 */ 288 public static void setupDiskCache(File cacheDir) { 289 ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath()); 290 } 291 292 /** 293 * Indicates that the specified hardware layer needs to be updated 294 * as soon as possible. 295 * 296 * @param layer The hardware layer that needs an update 297 */ 298 abstract void pushLayerUpdate(HardwareLayer layer); 299 300 /** 301 * Tells the HardwareRenderer that the layer is destroyed. The renderer 302 * should remove the layer from any update queues. 303 */ 304 abstract void onLayerDestroyed(HardwareLayer layer); 305 306 /** 307 * Interface used to receive callbacks whenever a view is drawn by 308 * a hardware renderer instance. 309 */ 310 interface HardwareDrawCallbacks { 311 /** 312 * Invoked before a view is drawn by a hardware renderer. 313 * This method can be used to apply transformations to the 314 * canvas but no drawing command should be issued. 315 * 316 * @param canvas The Canvas used to render the view. 317 */ 318 void onHardwarePreDraw(HardwareCanvas canvas); 319 320 /** 321 * Invoked after a view is drawn by a hardware renderer. 322 * It is safe to invoke drawing commands from this method. 323 * 324 * @param canvas The Canvas used to render the view. 325 */ 326 void onHardwarePostDraw(HardwareCanvas canvas); 327 } 328 329 /** 330 * Indicates that the content drawn by HardwareDrawCallbacks needs to 331 * be updated, which will be done by the next call to draw() 332 */ 333 abstract void invalidateRoot(); 334 335 /** 336 * Draws the specified view. 337 * 338 * @param view The view to draw. 339 * @param attachInfo AttachInfo tied to the specified view. 340 * @param callbacks Callbacks invoked when drawing happens. 341 */ 342 abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks); 343 344 /** 345 * Creates a new hardware layer. A hardware layer built by calling this 346 * method will be treated as a texture layer, instead of as a render target. 347 * 348 * @return A hardware layer 349 */ 350 abstract HardwareLayer createTextureLayer(); 351 352 abstract void buildLayer(RenderNode node); 353 354 abstract boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap); 355 356 /** 357 * Initializes the hardware renderer for the specified surface and setup the 358 * renderer for drawing, if needed. This is invoked when the ViewAncestor has 359 * potentially lost the hardware renderer. The hardware renderer should be 360 * reinitialized and setup when the render {@link #isRequested()} and 361 * {@link #isEnabled()}. 362 * 363 * @param width The width of the drawing surface. 364 * @param height The height of the drawing surface. 365 * @param surface The surface to hardware accelerate 366 * @param surfaceInsets The drawing surface insets to apply 367 * 368 * @return true if the surface was initialized, false otherwise. Returning 369 * false might mean that the surface was already initialized. 370 */ 371 boolean initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets) 372 throws OutOfResourcesException { 373 if (isRequested()) { 374 // We lost the gl context, so recreate it. 375 if (!isEnabled()) { 376 if (initialize(surface)) { 377 setup(width, height, surfaceInsets); 378 return true; 379 } 380 } 381 } 382 return false; 383 } 384 385 /** 386 * Sets up the renderer for drawing. 387 * 388 * @param width The width of the drawing surface. 389 * @param height The height of the drawing surface. 390 * @param surfaceInsets The drawing surface insets to apply 391 */ 392 abstract void setup(int width, int height, Rect surfaceInsets); 393 394 /** 395 * Optional, sets the name of the renderer. Useful for debugging purposes. 396 * 397 * @param name The name of this renderer, can be null 398 */ 399 abstract void setName(String name); 400 401 /** 402 * Change the HardwareRenderer's opacity 403 */ 404 abstract void setOpaque(boolean opaque); 405 406 /** 407 * Creates a hardware renderer using OpenGL. 408 * 409 * @param translucent True if the surface is translucent, false otherwise 410 * 411 * @return A hardware renderer backed by OpenGL. 412 */ 413 static HardwareRenderer create(Context context, boolean translucent) { 414 HardwareRenderer renderer = null; 415 if (GLES20Canvas.isAvailable()) { 416 renderer = new ThreadedRenderer(context, translucent); 417 } 418 return renderer; 419 } 420 421 /** 422 * Invoke this method when the system is running out of memory. This 423 * method will attempt to recover as much memory as possible, based on 424 * the specified hint. 425 * 426 * @param level Hint about the amount of memory that should be trimmed, 427 * see {@link android.content.ComponentCallbacks} 428 */ 429 static void trimMemory(int level) { 430 ThreadedRenderer.trimMemory(level); 431 } 432 433 /** 434 * Indicates whether hardware acceleration is currently enabled. 435 * 436 * @return True if hardware acceleration is in use, false otherwise. 437 */ 438 boolean isEnabled() { 439 return mEnabled; 440 } 441 442 /** 443 * Indicates whether hardware acceleration is currently enabled. 444 * 445 * @param enabled True if the hardware renderer is in use, false otherwise. 446 */ 447 void setEnabled(boolean enabled) { 448 mEnabled = enabled; 449 } 450 451 /** 452 * Indicates whether hardware acceleration is currently request but not 453 * necessarily enabled yet. 454 * 455 * @return True if requested, false otherwise. 456 */ 457 boolean isRequested() { 458 return mRequested; 459 } 460 461 /** 462 * Indicates whether hardware acceleration is currently requested but not 463 * necessarily enabled yet. 464 * 465 * @return True to request hardware acceleration, false otherwise. 466 */ 467 void setRequested(boolean requested) { 468 mRequested = requested; 469 } 470 471 /** 472 * Blocks until all previously queued work has completed. 473 */ 474 abstract void fence(); 475 476 /** 477 * Prevents any further drawing until draw() is called. This is a signal 478 * that the contents of the RenderNode tree are no longer safe to play back. 479 * In practice this usually means that there are Functor pointers in the 480 * display list that are no longer valid. 481 */ 482 abstract void stopDrawing(); 483 484 /** 485 * Called by {@link ViewRootImpl} when a new performTraverals is scheduled. 486 */ 487 abstract void notifyFramePending(); 488} 489