12d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy/* 22d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Copyright (C) 2010 The Android Open Source Project 32d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 42d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 52d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * you may not use this file except in compliance with the License. 62d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * You may obtain a copy of the License at 72d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 82d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 92d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 102d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Unless required by applicable law or agreed to in writing, software 112d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 122d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * See the License for the specific language governing permissions and 142d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * limitations under the License. 152d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 162d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 172d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 182d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guypackage android.view; 192d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 20c68c913d357e2955d4bd7ca52829071e531c7825Dianne Hackbornimport android.content.ComponentCallbacks2; 217d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guyimport android.graphics.Paint; 227d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guyimport android.graphics.Rect; 23aa6c24c21c727a196451332448d4e3b11a80be69Romain Guyimport android.graphics.SurfaceTexture; 24bd43152bda835c5a9a619a5869344a6a3af11917Romain Guyimport android.opengl.EGL14; 25407ec78b828173257b0c5dae221649a4ccd8b058Romain Guyimport android.opengl.GLUtils; 26717a25dc2a411edb548859cd6870363346c71b01Dianne Hackbornimport android.opengl.ManagedEGLContext; 27717a25dc2a411edb548859cd6870363346c71b01Dianne Hackbornimport android.os.Handler; 28717a25dc2a411edb548859cd6870363346c71b01Dianne Hackbornimport android.os.Looper; 2902ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guyimport android.os.SystemClock; 3002ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guyimport android.os.SystemProperties; 3177e67cf9055378d00bb57f458129462f33047039Romain Guyimport android.os.Trace; 32e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guyimport android.util.Log; 338ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guyimport com.google.android.gles_jni.EGLImpl; 342d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 352d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guyimport javax.microedition.khronos.egl.EGL10; 362d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guyimport javax.microedition.khronos.egl.EGL11; 372d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guyimport javax.microedition.khronos.egl.EGLConfig; 382d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guyimport javax.microedition.khronos.egl.EGLContext; 392d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guyimport javax.microedition.khronos.egl.EGLDisplay; 402d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guyimport javax.microedition.khronos.egl.EGLSurface; 41e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guyimport javax.microedition.khronos.opengles.GL; 422d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 43a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guyimport java.io.File; 44a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guyimport java.io.PrintWriter; 4577e67cf9055378d00bb57f458129462f33047039Romain Guyimport java.util.concurrent.locks.ReentrantLock; 46a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 47484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guyimport static javax.microedition.khronos.egl.EGL10.*; 48484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 492d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy/** 50c6cc0f8c19d9eccf408a443fa2bf668af261dcd0Joe Onorato * Interface for rendering a ViewAncestor using hardware acceleration. 512d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 522d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @hide 532d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 5461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guypublic abstract class HardwareRenderer { 554f6aff386045000c2c03b903c7109cb42092b7eaRomain Guy static final String LOG_TAG = "HardwareRenderer"; 56fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy 575233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy /** 58a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * Name of the file that holds the shaders cache. 59a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy */ 60a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache"; 61a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 62a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy /** 637d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy * Turn on to only refresh the parts of the screen that need updating. 64069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * When turned on the property defined by {@link #RENDER_DIRTY_REGIONS_PROPERTY} 65069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * must also have the value "true". 667d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy */ 677d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy public static final boolean RENDER_DIRTY_REGIONS = true; 687d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy 697d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy /** 70069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * System property used to enable or disable dirty regions invalidation. 71069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true. 72069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * The default value of this property is assumed to be true. 73069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * 74069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * Possible values: 75069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * "true", to enable partial invalidates 76069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * "false", to disable partial invalidates 77069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy */ 784b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy static final String RENDER_DIRTY_REGIONS_PROPERTY = "debug.hwui.render_dirty_regions"; 799ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy 809ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy /** 819ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy * System property used to enable or disable vsync. 829ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy * The default value of this property is assumed to be false. 839ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy * 849ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy * Possible values: 859ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy * "true", to disable vsync 869ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy * "false", to enable vsync 879ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy */ 884b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy static final String DISABLE_VSYNC_PROPERTY = "debug.hwui.disable_vsync"; 89069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy 90069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy /** 91a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * System property used to enable or disable hardware rendering profiling. 92a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * The default value of this property is assumed to be false. 9309280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * 94a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * When profiling is enabled, the adb shell dumpsys gfxinfo command will 95a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * output extra information about the time taken to execute by the last 96a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * frames. 97a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * 98a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * Possible values: 99a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * "true", to enable profiling 100a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * "false", to disable profiling 1014b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy * 1024b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy * @hide 103a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy */ 1044b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy public static final String PROFILE_PROPERTY = "debug.hwui.profile"; 105a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 106a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy /** 10709280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * System property used to specify the number of frames to be used 10809280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * when doing hardware rendering profiling. 10909280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * The default value of this property is #PROFILE_MAX_FRAMES. 11009280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * 11109280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * When profiling is enabled, the adb shell dumpsys gfxinfo command will 11209280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * output extra information about the time taken to execute by the last 11309280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * frames. 11409280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * 11509280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * Possible values: 11609280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase * "60", to set the limit of frames to 60 11709280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase */ 1184b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy static final String PROFILE_MAXFRAMES_PROPERTY = "debug.hwui.profile.maxframes"; 11909280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase 12009280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase /** 121484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy * System property used to debug EGL configuration choice. 122484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy * 123484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy * Possible values: 124484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy * "choice", print the chosen configuration only 125484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy * "all", print all possible configurations 126484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy */ 1274b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy static final String PRINT_CONFIG_PROPERTY = "debug.hwui.print_config"; 128484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 129484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy /** 1307d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy * Turn on to draw dirty regions every other frame. 131b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy * 132b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy * Possible values: 133b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy * "true", to enable dirty regions debugging 134b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy * "false", to disable dirty regions debugging 1354b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy * 1364b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy * @hide 1377d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy */ 1384b8c4f886b3d57e6ffe1a4650487c67334674a40Romain Guy public static final String DEBUG_DIRTY_REGIONS_PROPERTY = "debug.hwui.show_dirty_regions"; 1394ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy 1404ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy /** 1414ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy * Turn on to flash hardware layers when they update. 1424ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy * 1434ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy * Possible values: 1444ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy * "true", to enable hardware layers updates debugging 1454ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy * "false", to disable hardware layers updates debugging 1464ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy * 1474ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy * @hide 1484ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy */ 1494ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY = 1504ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy "debug.hwui.show_layers_updates"; 1514ff0cf4b83605bff630c4e6f1fabe4f72a3f93a1Romain Guy 1527d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy /** 1537c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy * Turn on to show overdraw level. 1547c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy * 1557c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy * Possible values: 1567c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy * "true", to enable overdraw debugging 1577c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy * "false", to disable overdraw debugging 1587c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy * 1597c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy * @hide 1607c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy */ 1617c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy public static final String DEBUG_SHOW_OVERDRAW_PROPERTY = "debug.hwui.show_overdraw"; 1627c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy 1637c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy /** 1645233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy * A process can set this flag to false to prevent the use of hardware 1655233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy * rendering. 1665233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy * 1675233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy * @hide 1685233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy */ 1695233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy public static boolean sRendererDisabled = false; 1705233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy 1715d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn /** 1725d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn * Further hardware renderer disabling for the system process. 1735d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn * 1745d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn * @hide 1755d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn */ 1765d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn public static boolean sSystemRendererDisabled = false; 1775d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn 178a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy /** 179a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * Number of frames to profile. 180a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy */ 181a21f877434dd25a93869b8641e3c38618bf317a9Romain Guy private static final int PROFILE_MAX_FRAMES = 128; 182a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 183a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy /** 184a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * Number of floats per profiled frame. 185a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy */ 186a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy private static final int PROFILE_FRAME_DATA_COUNT = 3; 187a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 1882d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy private boolean mEnabled; 1892d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy private boolean mRequested = true; 1902d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 1912d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 19267f27952c1bcb2230beef9b5ca0bf42edad436a9Romain Guy * Invoke this method to disable hardware rendering in the current process. 1935233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy * 1945233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy * @hide 1955233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy */ 1965d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn public static void disable(boolean system) { 1975233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy sRendererDisabled = true; 1985d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn if (system) { 1995d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn sSystemRendererDisabled = true; 2005d927c2d8e832fcfcb0154c8741f896001141ef4Dianne Hackborn } 2015233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy } 2025233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy 2035233920a216302b4aa03b100c32e8b3efe33cbc6Romain Guy /** 20461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy * Indicates whether hardware acceleration is available under any form for 20561c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy * the view hierarchy. 20661c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy * 20761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy * @return True if the view hierarchy can potentially be hardware accelerated, 20861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy * false otherwise 20961c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy */ 21061c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy public static boolean isAvailable() { 21161c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy return GLES20Canvas.isAvailable(); 21261c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy } 21361c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy 21461c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy /** 2152d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Destroys the hardware rendering context. 2164caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy * 2174caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy * @param full If true, destroys all associated resources. 2182d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 2194caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy abstract void destroy(boolean full); 2202d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 2212d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 2222d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Initializes the hardware renderer for the specified surface. 2232d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 224786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy * @param surface The surface to hardware accelerate 2252d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 2262d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @return True if the initialization was successful, false otherwise. 2272d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 228786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy abstract boolean initialize(Surface surface) throws Surface.OutOfResourcesException; 2292a83f001fdb189f945e82e81e717ba204824b112Romain Guy 2302a83f001fdb189f945e82e81e717ba204824b112Romain Guy /** 2312a83f001fdb189f945e82e81e717ba204824b112Romain Guy * Updates the hardware renderer for the specified surface. 232786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy * 233786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy * @param surface The surface to hardware accelerate 2342a83f001fdb189f945e82e81e717ba204824b112Romain Guy */ 235786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy abstract void updateSurface(Surface surface) throws Surface.OutOfResourcesException; 2362d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 2372d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 23831f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy * Destroys the layers used by the specified view hierarchy. 2396d7475d666baefaa3ba9f0dcee25238739454241Romain Guy * 2406d7475d666baefaa3ba9f0dcee25238739454241Romain Guy * @param view The root of the view hierarchy 2416d7475d666baefaa3ba9f0dcee25238739454241Romain Guy */ 2426d7475d666baefaa3ba9f0dcee25238739454241Romain Guy abstract void destroyLayers(View view); 2436d7475d666baefaa3ba9f0dcee25238739454241Romain Guy 2446d7475d666baefaa3ba9f0dcee25238739454241Romain Guy /** 24531f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy * Destroys all hardware rendering resources associated with the specified 24631f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy * view hierarchy. 24731f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy * 24831f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy * @param view The root of the view hierarchy 24931f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy */ 25031f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy abstract void destroyHardwareResources(View view); 25131f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy 25231f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy /** 253039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * This method should be invoked whenever the current hardware renderer 254cf15efba0792b052dca5baa350d9fb00e6a60667Romain Guy * context should be reset. 255786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy * 256786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy * @param surface The surface to hardware accelerate 2577e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy */ 258786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy abstract void invalidate(Surface surface); 259039857520b1a03a52051b966d87d587225bdfcc3Romain Guy 260039857520b1a03a52051b966d87d587225bdfcc3Romain Guy /** 261039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * This method should be invoked to ensure the hardware renderer is in 262039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * valid state (for instance, to ensure the correct EGL context is bound 263039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * to the current thread.) 264039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * 265039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * @return true if the renderer is now valid, false otherwise 266039857520b1a03a52051b966d87d587225bdfcc3Romain Guy */ 267039857520b1a03a52051b966d87d587225bdfcc3Romain Guy abstract boolean validate(); 2687e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy 2697e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy /** 2701ac4765e959c79101f64b1279887ed469334c268Romain Guy * This method ensures the hardware renderer is in a valid state 2711ac4765e959c79101f64b1279887ed469334c268Romain Guy * before executing the specified action. 2721ac4765e959c79101f64b1279887ed469334c268Romain Guy * 2731ac4765e959c79101f64b1279887ed469334c268Romain Guy * This method will attempt to set a valid state even if the window 2741ac4765e959c79101f64b1279887ed469334c268Romain Guy * the renderer is attached to was destroyed. 2751ac4765e959c79101f64b1279887ed469334c268Romain Guy * 2761ac4765e959c79101f64b1279887ed469334c268Romain Guy * @return true if the action was run 2771ac4765e959c79101f64b1279887ed469334c268Romain Guy */ 2781ac4765e959c79101f64b1279887ed469334c268Romain Guy abstract boolean safelyRun(Runnable action); 2791ac4765e959c79101f64b1279887ed469334c268Romain Guy 2801ac4765e959c79101f64b1279887ed469334c268Romain Guy /** 2817e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy * Setup the hardware renderer for drawing. This is called whenever the 2827e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy * size of the target surface changes or when the surface is first created. 2832d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 2842d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @param width Width of the drawing surface. 2852d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @param height Height of the drawing surface. 2862d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 287fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy abstract void setup(int width, int height); 2882d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 289069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy /** 29040e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase * Gets the current width of the surface. This is the width that the surface 29140e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase * was last set to in a call to {@link #setup(int, int)}. 29240e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase * 29340e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase * @return the current width of the surface 29440e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase */ 29540e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase abstract int getWidth(); 29640e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase 29740e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase /** 29840e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase * Gets the current height of the surface. This is the height that the surface 29940e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase * was last set to in a call to {@link #setup(int, int)}. 30040e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase * 30140e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase * @return the current width of the surface 30240e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase */ 30340e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase abstract int getHeight(); 30440e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase 30540e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase /** 30608837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase * Gets the current canvas associated with this HardwareRenderer. 30708837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase * 30808837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase * @return the current HardwareCanvas 30908837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase */ 31008837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase abstract HardwareCanvas getCanvas(); 31108837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase 31208837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase /** 313a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * Outputs extra debugging information in the specified file descriptor. 314a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy * @param pw 315a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy */ 316a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy abstract void dumpGfxInfo(PrintWriter pw); 317a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka 318a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka /** 319a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka * Outputs the total number of frames rendered (used for fps calculations) 320a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka * 321a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka * @return the number of frames rendered 322a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka */ 323a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka abstract long getFrameCount(); 324a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka 325a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy /** 326a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * Sets the directory to use as a persistent storage for hardware rendering 327a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * resources. 328a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * 329a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy * @param cacheDir A directory the current process can write to 330a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy */ 331a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy public static void setupDiskCache(File cacheDir) { 332a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy nSetupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath()); 333a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy } 334a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 335a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy private static native void nSetupShadersDiskCache(String cacheFile); 336a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy 337a95826582773a194ed7fb66bc29c9b82fe9bb8d1Romain Guy /** 338b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis * Notifies EGL that the frame is about to be rendered. 3397687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy * @param size 340b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis */ 3417687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy private static void beginFrame(int[] size) { 3427687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy nBeginFrame(size); 343b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis } 344b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis 3457687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy private static native void nBeginFrame(int[] size); 346b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis 347b335fad4705348ff78d764fb4be53dcbe6b67abeJamie Gennis /** 348244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * Preserves the back buffer of the current surface after a buffer swap. 349244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current 350244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL 351244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT. 352244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * 353244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * @return True if the swap behavior was successfully changed, 354244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * false otherwise. 355244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy */ 356244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy static boolean preserveBackBuffer() { 357244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy return nPreserveBackBuffer(); 358244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy } 359244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 360244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy private static native boolean nPreserveBackBuffer(); 361244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 362244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy /** 363244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * Indicates whether the current surface preserves its back buffer 364244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * after a buffer swap. 365244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * 366244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED, 367244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * false otherwise 368244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy */ 369244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy static boolean isBackBufferPreserved() { 370244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy return nIsBackBufferPreserved(); 371244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy } 372244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 373244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy private static native boolean nIsBackBufferPreserved(); 374244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 375244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy /** 376244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy * Disables v-sync. For performance testing only. 377244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy */ 378244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy static void disableVsync() { 379244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy nDisableVsync(); 380244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy } 381244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 382244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy private static native void nDisableVsync(); 383244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 384244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy /** 38511cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy * Indicates that the specified hardware layer needs to be updated 38611cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy * as soon as possible. 38711cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy * 38811cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy * @param layer The hardware layer that needs an update 38911cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy */ 39011cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy abstract void pushLayerUpdate(HardwareLayer layer); 39111cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy 39211cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy /** 393069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * Interface used to receive callbacks whenever a view is drawn by 394069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * a hardware renderer instance. 395069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy */ 3960f761d6b8f5d5a607c87dbcdca6fe0ec7911970eDianne Hackborn interface HardwareDrawCallbacks { 397069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy /** 398069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * Invoked before a view is drawn by a hardware renderer. 399069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * 400069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * @param canvas The Canvas used to render the view. 401069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy */ 4027d70fbf0b5672bada8b25f065bc292796c3d4812Romain Guy void onHardwarePreDraw(HardwareCanvas canvas); 403069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy 404069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy /** 405069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * Invoked after a view is drawn by a hardware renderer. 406069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * 407069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy * @param canvas The Canvas used to render the view. 408069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy */ 4097d70fbf0b5672bada8b25f065bc292796c3d4812Romain Guy void onHardwarePostDraw(HardwareCanvas canvas); 4100f761d6b8f5d5a607c87dbcdca6fe0ec7911970eDianne Hackborn } 4110f761d6b8f5d5a607c87dbcdca6fe0ec7911970eDianne Hackborn 4122d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 4132d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Draws the specified view. 4147d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy * 4152d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @param view The view to draw. 4162d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @param attachInfo AttachInfo tied to the specified view. 4177d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy * @param callbacks Callbacks invoked when drawing happens. 4187d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy * @param dirty The dirty rectangle to update, can be null. 41950d133e290468fd149b5c03e46549afca2ee05f8Romain Guy * 42050d133e290468fd149b5c03e46549afca2ee05f8Romain Guy * @return true if the dirty rect was ignored, false otherwise 4212d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 42250d133e290468fd149b5c03e46549afca2ee05f8Romain Guy abstract boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks, 4237d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy Rect dirty); 4242d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 4252d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 42653ca03d9a3a6a95286302802173c4820b16328ceRomain Guy * Creates a new display list that can be used to record batches of 42753ca03d9a3a6a95286302802173c4820b16328ceRomain Guy * drawing operations. 428b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy * 42913631f3da855f200a151e7837ed9f6b079622b58Romain Guy * @param name The name of the display list, used for debugging purpose. 43013631f3da855f200a151e7837ed9f6b079622b58Romain Guy * May be null 43113631f3da855f200a151e7837ed9f6b079622b58Romain Guy * 43253ca03d9a3a6a95286302802173c4820b16328ceRomain Guy * @return A new display list. 433b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy */ 43413631f3da855f200a151e7837ed9f6b079622b58Romain Guy public abstract DisplayList createDisplayList(String name); 435b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy 436b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy /** 437aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Creates a new hardware layer. A hardware layer built by calling this 438aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * method will be treated as a texture layer, instead of as a render target. 439aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 440a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy * @param isOpaque Whether the layer should be opaque or not 441a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy * 442aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @return A hardware layer 4432af3524beb75150d347accc925022daa53b4a789Jamie Gennis */ 444a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy abstract HardwareLayer createHardwareLayer(boolean isOpaque); 4452af3524beb75150d347accc925022daa53b4a789Jamie Gennis 446aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 4476c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * Creates a new hardware layer. 4486c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * 4496c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * @param width The minimum width of the layer 4506c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * @param height The minimum height of the layer 4516c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * @param isOpaque Whether the layer should be opaque or not 4526c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * 4536c319ca1275c8db892c39b48fc54864c949f9171Romain Guy * @return A hardware layer 4546c319ca1275c8db892c39b48fc54864c949f9171Romain Guy */ 4556c319ca1275c8db892c39b48fc54864c949f9171Romain Guy abstract HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque); 456aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 457aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 458aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * Creates a new {@link SurfaceTexture} that can be used to render into the 459aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * specified hardware layer. 460aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 461aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 462aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @param layer The layer to render into using a {@link android.graphics.SurfaceTexture} 463aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * 464aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy * @return A {@link SurfaceTexture} 465aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy */ 466e5e0c50f7dfaccc220725c5595080e921ffda1e4Romain Guy abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer); 467aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 468aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy /** 4692af3524beb75150d347accc925022daa53b4a789Jamie Gennis * Sets the {@link android.graphics.SurfaceTexture} that will be used to 4702af3524beb75150d347accc925022daa53b4a789Jamie Gennis * render into the specified hardware layer. 4712af3524beb75150d347accc925022daa53b4a789Jamie Gennis * 4722af3524beb75150d347accc925022daa53b4a789Jamie Gennis * @param layer The layer to render into using a {@link android.graphics.SurfaceTexture} 4732af3524beb75150d347accc925022daa53b4a789Jamie Gennis * @param surfaceTexture The {@link android.graphics.SurfaceTexture} to use for the layer 4742af3524beb75150d347accc925022daa53b4a789Jamie Gennis */ 4752af3524beb75150d347accc925022daa53b4a789Jamie Gennis abstract void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture); 4762af3524beb75150d347accc925022daa53b4a789Jamie Gennis 4772af3524beb75150d347accc925022daa53b4a789Jamie Gennis /** 478ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * Detaches the specified functor from the current functor execution queue. 479ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * 480ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * @param functor The native functor to remove from the execution queue. 481ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * 482ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * @see HardwareCanvas#callDrawGLFunction(int) 483ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * @see #attachFunctor(android.view.View.AttachInfo, int) 484ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy */ 485ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy abstract void detachFunctor(int functor); 486ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 487ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy /** 488ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * Schedules the specified functor in the functors execution queue. 489ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * 490ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * @param attachInfo AttachInfo tied to this renderer. 491ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * @param functor The native functor to insert in the execution queue. 492ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * 493ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy * @see HardwareCanvas#callDrawGLFunction(int) 49441ee465734d0006797a8fd36e88976c1e85d161cChris Craik * @see #detachFunctor(int) 49541ee465734d0006797a8fd36e88976c1e85d161cChris Craik * 49641ee465734d0006797a8fd36e88976c1e85d161cChris Craik * @return true if the functor was attached successfully 497ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy */ 49841ee465734d0006797a8fd36e88976c1e85d161cChris Craik abstract boolean attachFunctor(View.AttachInfo attachInfo, int functor); 499ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 500ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy /** 5012d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Initializes the hardware renderer for the specified surface and setup the 502c6cc0f8c19d9eccf408a443fa2bf668af261dcd0Joe Onorato * renderer for drawing, if needed. This is invoked when the ViewAncestor has 5032d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * potentially lost the hardware renderer. The hardware renderer should be 5042d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * reinitialized and setup when the render {@link #isRequested()} and 5052d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * {@link #isEnabled()}. 50644d79747b5e434e8f43928b5548442c65e40e5c3Romain Guy * 5072d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @param width The width of the drawing surface. 5082d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @param height The height of the drawing surface. 509786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy * @param surface The surface to hardware accelerate 510dfab363807b3b44be4032e410f016e0a0d018426Romain Guy * 511dfab363807b3b44be4032e410f016e0a0d018426Romain Guy * @return true if the surface was initialized, false otherwise. Returning 512dfab363807b3b44be4032e410f016e0a0d018426Romain Guy * false might mean that the surface was already initialized. 5132d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 514dfab363807b3b44be4032e410f016e0a0d018426Romain Guy boolean initializeIfNeeded(int width, int height, Surface surface) 51544d79747b5e434e8f43928b5548442c65e40e5c3Romain Guy throws Surface.OutOfResourcesException { 5162d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy if (isRequested()) { 5172d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy // We lost the gl context, so recreate it. 5182d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy if (!isEnabled()) { 519786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy if (initialize(surface)) { 520fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy setup(width, height); 521dfab363807b3b44be4032e410f016e0a0d018426Romain Guy return true; 5222d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 5232d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 524dfab363807b3b44be4032e410f016e0a0d018426Romain Guy } 525dfab363807b3b44be4032e410f016e0a0d018426Romain Guy return false; 5262d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 5272d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 5282d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 5292d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Creates a hardware renderer using OpenGL. 5302d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 5312d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @param glVersion The version of OpenGL to use (1 for OpenGL 1, 11 for OpenGL 1.1, etc.) 532e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * @param translucent True if the surface is translucent, false otherwise 5332d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 5342d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @return A hardware renderer backed by OpenGL. 5352d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 536e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy static HardwareRenderer createGlRenderer(int glVersion, boolean translucent) { 5372d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy switch (glVersion) { 538e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy case 2: 539163935113919a184122b8b3bd672ef08c8df65dcRomain Guy return Gl20Renderer.create(translucent); 5402d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 5412d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy throw new IllegalArgumentException("Unknown GL version: " + glVersion); 5422d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 5432d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 5442d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 545bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy * Invoke this method when the system is running out of memory. This 546bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy * method will attempt to recover as much memory as possible, based on 547bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy * the specified hint. 548bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy * 549bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy * @param level Hint about the amount of memory that should be trimmed, 550bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy * see {@link android.content.ComponentCallbacks} 551bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy */ 552bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy static void trimMemory(int level) { 55319f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy startTrimMemory(level); 55419f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy endTrimMemory(); 55519f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy } 55619f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy 55719f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy /** 55819f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy * Starts the process of trimming memory. Usually this call will setup 55919f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy * hardware rendering context and reclaim memory.Extra cleanup might 56019f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy * be required by calling {@link #endTrimMemory()}. 56119f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy * 56219f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy * @param level Hint about the amount of memory that should be trimmed, 56319f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy * see {@link android.content.ComponentCallbacks} 56419f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy */ 56519f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy static void startTrimMemory(int level) { 56619f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy Gl20Renderer.startTrimMemory(level); 56719f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy } 56819f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy 56919f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy /** 57019f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy * Finishes the process of trimming memory. This method will usually 57119f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy * cleanup special resources used by the memory trimming process. 57219f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy */ 57319f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy static void endTrimMemory() { 57419f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy Gl20Renderer.endTrimMemory(); 575bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy } 576bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy 577bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy /** 5782d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Indicates whether hardware acceleration is currently enabled. 5792d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 5802d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @return True if hardware acceleration is in use, false otherwise. 5812d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 5822d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy boolean isEnabled() { 5832d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy return mEnabled; 5842d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 5852d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 5862d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 5872d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Indicates whether hardware acceleration is currently enabled. 5882d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 5892d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @param enabled True if the hardware renderer is in use, false otherwise. 5902d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 5912d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy void setEnabled(boolean enabled) { 5922d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy mEnabled = enabled; 5932d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 5942d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 5952d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 5962d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * Indicates whether hardware acceleration is currently request but not 5972d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * necessarily enabled yet. 5982d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 5992d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @return True if requested, false otherwise. 6002d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 6012d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy boolean isRequested() { 6022d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy return mRequested; 6032d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 6042d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 6052d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy /** 6069745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy * Indicates whether hardware acceleration is currently requested but not 6072d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * necessarily enabled yet. 6082d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * 6092d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy * @return True to request hardware acceleration, false otherwise. 6102d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy */ 6112d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy void setRequested(boolean requested) { 6122d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy mRequested = requested; 6132d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 6142d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 6152d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy @SuppressWarnings({"deprecation"}) 616e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy static abstract class GlRenderer extends HardwareRenderer { 61716260e73f6c1c9dc94acf0d328a3c564426b8711Romain Guy static final int SURFACE_STATE_ERROR = 0; 61816260e73f6c1c9dc94acf0d328a3c564426b8711Romain Guy static final int SURFACE_STATE_SUCCESS = 1; 61916260e73f6c1c9dc94acf0d328a3c564426b8711Romain Guy static final int SURFACE_STATE_UPDATED = 2; 6208f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy 62165924a3e56c2e7ac863f8e25e9f9a58b9db7d513Chris Craik static final int FUNCTOR_PROCESS_DELAY = 4; 6228f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy 623fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy static EGL10 sEgl; 624fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy static EGLDisplay sEglDisplay; 625fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy static EGLConfig sEglConfig; 626566b3efb25299d2a9c8ae827522802bad965426aRomain Guy static final Object[] sEglLock = new Object[0]; 62740e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase int mWidth = -1, mHeight = -1; 628e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 6295d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy static final ThreadLocal<ManagedEGLContext> sEglContextStorage 6305d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy = new ThreadLocal<ManagedEGLContext>(); 631566b3efb25299d2a9c8ae827522802bad965426aRomain Guy 632566b3efb25299d2a9c8ae827522802bad965426aRomain Guy EGLContext mEglContext; 633566b3efb25299d2a9c8ae827522802bad965426aRomain Guy Thread mEglThread; 634fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy 635fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy EGLSurface mEglSurface; 636fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy 637e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy GL mGl; 63867f27952c1bcb2230beef9b5ca0bf42edad436a9Romain Guy HardwareCanvas mCanvas; 639a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 640a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka long mFrameCount; 6417d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy Paint mDebugPaint; 6427d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy 6437e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy static boolean sDirtyRegions; 6447e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy static final boolean sDirtyRegionsRequested; 6457e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy static { 6467e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true"); 6477e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy //noinspection PointlessBooleanExpression,ConstantConditions 6487e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy sDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty); 6497e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy sDirtyRegionsRequested = sDirtyRegions; 6507e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy } 6517e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy 6527e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy boolean mDirtyRegionsEnabled; 6539477c6e6581ce97976250951f33e1297604ac777Romain Guy boolean mUpdateDirtyRegions; 6549477c6e6581ce97976250951f33e1297604ac777Romain Guy 6559ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy final boolean mVsyncDisabled; 6562d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 657a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy final boolean mProfileEnabled; 658a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy final float[] mProfileData; 65977e67cf9055378d00bb57f458129462f33047039Romain Guy final ReentrantLock mProfileLock; 660a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT; 661b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy 662b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy final boolean mDebugDirtyRegions; 6637c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy final boolean mShowOverdraw; 664a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 665e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy final int mGlVersion; 666e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy final boolean mTranslucent; 6672d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 668fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy private boolean mDestroyed; 669566b3efb25299d2a9c8ae827522802bad965426aRomain Guy 670cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy private final Rect mRedrawClip = new Rect(); 6718f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy 6727687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy private final int[] mSurfaceSize = new int[2]; 6738f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy private final FunctorsRunnable mFunctorsRunnable = new FunctorsRunnable(); 674fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy 675e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy GlRenderer(int glVersion, boolean translucent) { 676e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy mGlVersion = glVersion; 677e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy mTranslucent = translucent; 678b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy 679b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy String property; 6809ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy 681b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy property = SystemProperties.get(DISABLE_VSYNC_PROPERTY, "false"); 682b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy mVsyncDisabled = "true".equalsIgnoreCase(property); 6839ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy if (mVsyncDisabled) { 6849ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy Log.d(LOG_TAG, "Disabling v-sync"); 6859ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy } 686a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 68713b907353f18215b52b5ceda24bbf520d91d72a1Romain Guy property = SystemProperties.get(PROFILE_PROPERTY, "false"); 68813b907353f18215b52b5ceda24bbf520d91d72a1Romain Guy mProfileEnabled = "true".equalsIgnoreCase(property); 68913b907353f18215b52b5ceda24bbf520d91d72a1Romain Guy if (mProfileEnabled) { 69013b907353f18215b52b5ceda24bbf520d91d72a1Romain Guy Log.d(LOG_TAG, "Profiling hardware renderer"); 691a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy } 692a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 693a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy if (mProfileEnabled) { 69409280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase property = SystemProperties.get(PROFILE_MAXFRAMES_PROPERTY, 69509280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase Integer.toString(PROFILE_MAX_FRAMES)); 69609280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase int maxProfileFrames = Integer.valueOf(property); 69709280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase mProfileData = new float[maxProfileFrames * PROFILE_FRAME_DATA_COUNT]; 69809280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) { 69909280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1; 70009280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase } 70177e67cf9055378d00bb57f458129462f33047039Romain Guy 70277e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileLock = new ReentrantLock(); 703a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy } else { 704a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy mProfileData = null; 70577e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileLock = null; 706a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy } 707b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy 708b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy property = SystemProperties.get(DEBUG_DIRTY_REGIONS_PROPERTY, "false"); 709b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy mDebugDirtyRegions = "true".equalsIgnoreCase(property); 710b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy if (mDebugDirtyRegions) { 711b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy Log.d(LOG_TAG, "Debugging dirty regions"); 712b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy } 7137c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy 7147c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy mShowOverdraw = SystemProperties.getBoolean( 7157c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy HardwareRenderer.DEBUG_SHOW_OVERDRAW_PROPERTY, false); 716a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy } 717a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 718a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy @Override 719a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy void dumpGfxInfo(PrintWriter pw) { 720a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy if (mProfileEnabled) { 721a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy pw.printf("\n\tDraw\tProcess\tExecute\n"); 72277e67cf9055378d00bb57f458129462f33047039Romain Guy 72377e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileLock.lock(); 72477e67cf9055378d00bb57f458129462f33047039Romain Guy try { 72577e67cf9055378d00bb57f458129462f33047039Romain Guy for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) { 72677e67cf9055378d00bb57f458129462f33047039Romain Guy if (mProfileData[i] < 0) { 72777e67cf9055378d00bb57f458129462f33047039Romain Guy break; 72877e67cf9055378d00bb57f458129462f33047039Romain Guy } 72977e67cf9055378d00bb57f458129462f33047039Romain Guy pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1], 73077e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileData[i + 2]); 73177e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1; 73209280606dc5dc1b8f12f9317cf6922772b7d10a7Chet Haase } 73377e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileCurrentFrame = mProfileData.length; 73477e67cf9055378d00bb57f458129462f33047039Romain Guy } finally { 73577e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileLock.unlock(); 736a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy } 737a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy } 7382d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 7392d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 740a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka @Override 741a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka long getFrameCount() { 742a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka return mFrameCount; 743a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka } 744a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka 745e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy /** 74602ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy * Indicates whether this renderer instance can track and update dirty regions. 74702ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy */ 74802ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy boolean hasDirtyRegions() { 7497e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy return mDirtyRegionsEnabled; 75002ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy } 75102ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy 75202ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy /** 7534caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy * Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)} 754e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy * is invoked and the requested flag is turned off. The error code is 755e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy * also logged as a warning. 756e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy */ 757b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy void checkEglErrors() { 758e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy if (isEnabled()) { 759740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy checkEglErrorsForced(); 760740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy } 761740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy } 762740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy 763740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy private void checkEglErrorsForced() { 764740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy int error = sEgl.eglGetError(); 765740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy if (error != EGL_SUCCESS) { 766740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy // something bad has happened revert to 767740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy // normal rendering. 768740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error)); 769740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy fallback(error != EGL11.EGL_CONTEXT_LOST); 7702d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 7712d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 77267f27952c1bcb2230beef9b5ca0bf42edad436a9Romain Guy 7739745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy private void fallback(boolean fallback) { 7749745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy destroy(true); 7759745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy if (fallback) { 7769745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy // we'll try again if it was context lost 7779745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy setRequested(false); 7789745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy Log.w(LOG_TAG, "Mountain View, we've had a problem here. " 7799745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy + "Switching back to software rendering."); 7809745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy } 7819745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy } 7829745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy 783e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy @Override 784786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy boolean initialize(Surface surface) throws Surface.OutOfResourcesException { 785e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy if (isRequested() && !isEnabled()) { 786e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy initializeEgl(); 787786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy mGl = createEglSurface(surface); 788fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy mDestroyed = false; 7892d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 790e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy if (mGl != null) { 791fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy int err = sEgl.eglGetError(); 792484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy if (err != EGL_SUCCESS) { 7934caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy destroy(true); 794e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy setRequested(false); 795e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } else { 7964caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy if (mCanvas == null) { 7974caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy mCanvas = createCanvas(); 798fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy } 799e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy if (mCanvas != null) { 800e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy setEnabled(true); 801e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } else { 802e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy Log.w(LOG_TAG, "Hardware accelerated Canvas could not be created"); 803e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 804e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 805e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 806e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy return mCanvas != null; 807e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 808e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 809e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy return false; 810e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 8112a83f001fdb189f945e82e81e717ba204824b112Romain Guy 8122a83f001fdb189f945e82e81e717ba204824b112Romain Guy @Override 813786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy void updateSurface(Surface surface) throws Surface.OutOfResourcesException { 8142a83f001fdb189f945e82e81e717ba204824b112Romain Guy if (isRequested() && isEnabled()) { 815786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy createEglSurface(surface); 8162a83f001fdb189f945e82e81e717ba204824b112Romain Guy } 8172a83f001fdb189f945e82e81e717ba204824b112Romain Guy } 818e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 8195d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy abstract HardwareCanvas createCanvas(); 8202d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 82129d23ecfd8612ecd4a7b2140acd344934b73a558Romain Guy abstract int[] getConfig(boolean dirtyRegions); 82229d23ecfd8612ecd4a7b2140acd344934b73a558Romain Guy 823e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy void initializeEgl() { 824566b3efb25299d2a9c8ae827522802bad965426aRomain Guy synchronized (sEglLock) { 825566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (sEgl == null && sEglConfig == null) { 826566b3efb25299d2a9c8ae827522802bad965426aRomain Guy sEgl = (EGL10) EGLContext.getEGL(); 827566b3efb25299d2a9c8ae827522802bad965426aRomain Guy 828566b3efb25299d2a9c8ae827522802bad965426aRomain Guy // Get to the default display. 829484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY); 830566b3efb25299d2a9c8ae827522802bad965426aRomain Guy 831484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy if (sEglDisplay == EGL_NO_DISPLAY) { 832566b3efb25299d2a9c8ae827522802bad965426aRomain Guy throw new RuntimeException("eglGetDisplay failed " 833407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy + GLUtils.getEGLErrorString(sEgl.eglGetError())); 834566b3efb25299d2a9c8ae827522802bad965426aRomain Guy } 835566b3efb25299d2a9c8ae827522802bad965426aRomain Guy 836566b3efb25299d2a9c8ae827522802bad965426aRomain Guy // We can now initialize EGL for that display 837566b3efb25299d2a9c8ae827522802bad965426aRomain Guy int[] version = new int[2]; 838566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (!sEgl.eglInitialize(sEglDisplay, version)) { 839566b3efb25299d2a9c8ae827522802bad965426aRomain Guy throw new RuntimeException("eglInitialize failed " + 840407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(sEgl.eglGetError())); 841566b3efb25299d2a9c8ae827522802bad965426aRomain Guy } 842740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy 843740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy checkEglErrorsForced(); 844740ee65d460401c266a7108c9aa4c6e7fbe58489Romain Guy 845e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy sEglConfig = chooseEglConfig(); 846069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy if (sEglConfig == null) { 847566b3efb25299d2a9c8ae827522802bad965426aRomain Guy // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without 848566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (sDirtyRegions) { 849566b3efb25299d2a9c8ae827522802bad965426aRomain Guy sDirtyRegions = false; 850566b3efb25299d2a9c8ae827522802bad965426aRomain Guy sEglConfig = chooseEglConfig(); 851566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (sEglConfig == null) { 852566b3efb25299d2a9c8ae827522802bad965426aRomain Guy throw new RuntimeException("eglConfig not initialized"); 853566b3efb25299d2a9c8ae827522802bad965426aRomain Guy } 854566b3efb25299d2a9c8ae827522802bad965426aRomain Guy } else { 855566b3efb25299d2a9c8ae827522802bad965426aRomain Guy throw new RuntimeException("eglConfig not initialized"); 856566b3efb25299d2a9c8ae827522802bad965426aRomain Guy } 857069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy } 858069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy } 859069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy } 860566b3efb25299d2a9c8ae827522802bad965426aRomain Guy 8615d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy ManagedEGLContext managedContext = sEglContextStorage.get(); 862717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn mEglContext = managedContext != null ? managedContext.getContext() : null; 863566b3efb25299d2a9c8ae827522802bad965426aRomain Guy mEglThread = Thread.currentThread(); 864566b3efb25299d2a9c8ae827522802bad965426aRomain Guy 865566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (mEglContext == null) { 866566b3efb25299d2a9c8ae827522802bad965426aRomain Guy mEglContext = createContext(sEgl, sEglDisplay, sEglConfig); 8675d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy sEglContextStorage.set(createManagedContext(mEglContext)); 868566b3efb25299d2a9c8ae827522802bad965426aRomain Guy } 869e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 870e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 8715d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy abstract ManagedEGLContext createManagedContext(EGLContext eglContext); 8725d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy 873e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy private EGLConfig chooseEglConfig() { 874e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy EGLConfig[] configs = new EGLConfig[1]; 875484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy int[] configsCount = new int[1]; 8767e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy int[] configSpec = getConfig(sDirtyRegions); 877484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 878484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy // Debug 87929d23ecfd8612ecd4a7b2140acd344934b73a558Romain Guy final String debug = SystemProperties.get(PRINT_CONFIG_PROPERTY, ""); 880484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy if ("all".equalsIgnoreCase(debug)) { 881484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglChooseConfig(sEglDisplay, configSpec, null, 0, configsCount); 882484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 883484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy EGLConfig[] debugConfigs = new EGLConfig[configsCount[0]]; 884484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglChooseConfig(sEglDisplay, configSpec, debugConfigs, 885484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy configsCount[0], configsCount); 886484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 887484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy for (EGLConfig config : debugConfigs) { 888484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy printConfig(config); 889484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy } 890484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy } 891484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 892e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) { 893e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy throw new IllegalArgumentException("eglChooseConfig failed " + 894407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(sEgl.eglGetError())); 895e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy } else if (configsCount[0] > 0) { 896484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy if ("choice".equalsIgnoreCase(debug)) { 897484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy printConfig(configs[0]); 898484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy } 899e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy return configs[0]; 900e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy } 901484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 902e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy return null; 903e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy } 904e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy 905e979e62ac7313b7cffe9b131bb8a99c356068b45Romain Guy private static void printConfig(EGLConfig config) { 906484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy int[] value = new int[1]; 907484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 908484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy Log.d(LOG_TAG, "EGL configuration " + config + ":"); 909484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 910484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value); 911484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy Log.d(LOG_TAG, " RED_SIZE = " + value[0]); 912484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 913484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value); 914484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy Log.d(LOG_TAG, " GREEN_SIZE = " + value[0]); 915484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 916484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value); 917484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy Log.d(LOG_TAG, " BLUE_SIZE = " + value[0]); 918484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 919484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value); 920484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy Log.d(LOG_TAG, " ALPHA_SIZE = " + value[0]); 921484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 922484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value); 923484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy Log.d(LOG_TAG, " DEPTH_SIZE = " + value[0]); 924484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 925484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value); 926484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy Log.d(LOG_TAG, " STENCIL_SIZE = " + value[0]); 927484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 9288efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value); 9298efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy Log.d(LOG_TAG, " SAMPLE_BUFFERS = " + value[0]); 9308efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy 9318efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value); 9328efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy Log.d(LOG_TAG, " SAMPLES = " + value[0]); 9338efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy 934484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value); 93529d23ecfd8612ecd4a7b2140acd344934b73a558Romain Guy Log.d(LOG_TAG, " SURFACE_TYPE = 0x" + Integer.toHexString(value[0])); 9368efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy 9378efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value); 9388efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy Log.d(LOG_TAG, " CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0])); 939484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy } 940484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy 941786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy GL createEglSurface(Surface surface) throws Surface.OutOfResourcesException { 942e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy // Check preconditions. 943fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy if (sEgl == null) { 944e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy throw new RuntimeException("egl not initialized"); 945e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 946fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy if (sEglDisplay == null) { 947e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy throw new RuntimeException("eglDisplay not initialized"); 948e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 949fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy if (sEglConfig == null) { 950069ea0e31a0aa283c83fae79f31a1798a6d85ddeRomain Guy throw new RuntimeException("eglConfig not initialized"); 951e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 952566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (Thread.currentThread() != mEglThread) { 953fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy throw new IllegalStateException("HardwareRenderer cannot be used " 954fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy + "from multiple threads"); 955fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy } 956e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 9576d7475d666baefaa3ba9f0dcee25238739454241Romain Guy // In case we need to destroy an existing surface 9586d7475d666baefaa3ba9f0dcee25238739454241Romain Guy destroySurface(); 959e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 960e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy // Create an EGL surface we can render into. 961786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy if (!createSurface(surface)) { 9621d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy return null; 963e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 964e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 9658ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy initCaches(); 9666f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy 9679477c6e6581ce97976250951f33e1297604ac777Romain Guy return mEglContext.getGL(); 9689477c6e6581ce97976250951f33e1297604ac777Romain Guy } 9699477c6e6581ce97976250951f33e1297604ac777Romain Guy 9709477c6e6581ce97976250951f33e1297604ac777Romain Guy private void enableDirtyRegions() { 9716f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy // If mDirtyRegions is set, this means we have an EGL configuration 9726f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set 9737e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy if (sDirtyRegions) { 974244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy if (!(mDirtyRegionsEnabled = preserveBackBuffer())) { 9757d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy Log.w(LOG_TAG, "Backbuffer cannot be preserved"); 9767d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy } 9777e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy } else if (sDirtyRegionsRequested) { 9786f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy // If mDirtyRegions is not set, our EGL configuration does not 9796f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy // have EGL_SWAP_BEHAVIOR_PRESERVED_BIT; however, the default 9806f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy // swap behavior might be EGL_BUFFER_PRESERVED, which means we 9816f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy // want to set mDirtyRegions. We try to do this only if dirty 9826f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy // regions were initially requested as part of the device 9836f7d9394ec69e9fb38ca5fc2caf6d2aef6f7442dRomain Guy // configuration (see RENDER_DIRTY_REGIONS) 984244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy mDirtyRegionsEnabled = isBackBufferPreserved(); 9857d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy } 9862d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 9872d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 9888ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy abstract void initCaches(); 9898ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy 990e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { 991bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE }; 992e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 993c002936e4bd042db3024202b3e9696835a730cfaRomain Guy EGLContext context = egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, 994c002936e4bd042db3024202b3e9696835a730cfaRomain Guy mGlVersion != 0 ? attribs : null); 995ed1b6f4fc0af836624b2edc2830eb918bf04cf3cRomain Guy if (context == null || context == EGL_NO_CONTEXT) { 996c002936e4bd042db3024202b3e9696835a730cfaRomain Guy //noinspection ConstantConditions 997c002936e4bd042db3024202b3e9696835a730cfaRomain Guy throw new IllegalStateException( 998c002936e4bd042db3024202b3e9696835a730cfaRomain Guy "Could not create an EGL context. eglCreateContext failed with error: " + 999c002936e4bd042db3024202b3e9696835a730cfaRomain Guy GLUtils.getEGLErrorString(sEgl.eglGetError())); 1000c002936e4bd042db3024202b3e9696835a730cfaRomain Guy } 1001c002936e4bd042db3024202b3e9696835a730cfaRomain Guy return context; 1002e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 1003e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 1004e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy @Override 10054caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy void destroy(boolean full) { 10064caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy if (full && mCanvas != null) { 10074caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy mCanvas = null; 10084caa4ed120a86e855d4d3b6b455c6fb9ca22e365Romain Guy } 1009fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy 1010357c942462e4eb1d0b2e91b3fe8ec9ac7524bbedRomain Guy if (!isEnabled() || mDestroyed) { 1011357c942462e4eb1d0b2e91b3fe8ec9ac7524bbedRomain Guy setEnabled(false); 1012357c942462e4eb1d0b2e91b3fe8ec9ac7524bbedRomain Guy return; 1013357c942462e4eb1d0b2e91b3fe8ec9ac7524bbedRomain Guy } 1014e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 10156d7475d666baefaa3ba9f0dcee25238739454241Romain Guy destroySurface(); 1016357c942462e4eb1d0b2e91b3fe8ec9ac7524bbedRomain Guy setEnabled(false); 10172d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 1018357c942462e4eb1d0b2e91b3fe8ec9ac7524bbedRomain Guy mDestroyed = true; 1019e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy mGl = null; 1020fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy } 1021fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy 10226d7475d666baefaa3ba9f0dcee25238739454241Romain Guy void destroySurface() { 10236d7475d666baefaa3ba9f0dcee25238739454241Romain Guy if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) { 10246d7475d666baefaa3ba9f0dcee25238739454241Romain Guy sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 10256d7475d666baefaa3ba9f0dcee25238739454241Romain Guy sEgl.eglDestroySurface(sEglDisplay, mEglSurface); 10266d7475d666baefaa3ba9f0dcee25238739454241Romain Guy mEglSurface = null; 10276d7475d666baefaa3ba9f0dcee25238739454241Romain Guy } 10286d7475d666baefaa3ba9f0dcee25238739454241Romain Guy } 10296d7475d666baefaa3ba9f0dcee25238739454241Romain Guy 10302d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy @Override 1031786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy void invalidate(Surface surface) { 10327e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy // Cancels any existing buffer to ensure we'll get a buffer 10337e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy // of the right size before we call eglSwapBuffers 1034cf15efba0792b052dca5baa350d9fb00e6a60667Romain Guy sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 10351d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy 1036d3facf341bf106588aade72c0164532cd4bf941fRomain Guy if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) { 1037d3facf341bf106588aade72c0164532cd4bf941fRomain Guy sEgl.eglDestroySurface(sEglDisplay, mEglSurface); 10381d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy mEglSurface = null; 10391d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy setEnabled(false); 1040d3facf341bf106588aade72c0164532cd4bf941fRomain Guy } 1041cf15efba0792b052dca5baa350d9fb00e6a60667Romain Guy 1042786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy if (surface.isValid()) { 1043786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy if (!createSurface(surface)) { 10441d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy return; 1045cf15efba0792b052dca5baa350d9fb00e6a60667Romain Guy } 10469477c6e6581ce97976250951f33e1297604ac777Romain Guy 10479477c6e6581ce97976250951f33e1297604ac777Romain Guy mUpdateDirtyRegions = true; 10489477c6e6581ce97976250951f33e1297604ac777Romain Guy 104986e3e22ba81fb75a5c7e5e007ca1c0cacfda3afbRomain Guy if (mCanvas != null) { 105086e3e22ba81fb75a5c7e5e007ca1c0cacfda3afbRomain Guy setEnabled(true); 105186e3e22ba81fb75a5c7e5e007ca1c0cacfda3afbRomain Guy } 10521d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy } 10531d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy } 10541d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy 1055786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy private boolean createSurface(Surface surface) { 1056786fc93d71b833ab6b02b0c7ea5e30f25cceeedfRomain Guy mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, surface, null); 10571d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy 10581d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) { 10591d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy int error = sEgl.eglGetError(); 10601d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy if (error == EGL_BAD_NATIVE_WINDOW) { 10611d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); 10621d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy return false; 10631d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy } 10641d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy throw new RuntimeException("createWindowSurface failed " 1065407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy + GLUtils.getEGLErrorString(error)); 1066cf15efba0792b052dca5baa350d9fb00e6a60667Romain Guy } 1067bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy 1068bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 1069bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy throw new IllegalStateException("eglMakeCurrent failed " + 1070bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy GLUtils.getEGLErrorString(sEgl.eglGetError())); 1071bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy } 1072bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy 1073bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy enableDirtyRegions(); 1074bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy 10751d0c708961f824ac5171238c205a7bf328d5d8a5Romain Guy return true; 1076039857520b1a03a52051b966d87d587225bdfcc3Romain Guy } 1077cf15efba0792b052dca5baa350d9fb00e6a60667Romain Guy 1078039857520b1a03a52051b966d87d587225bdfcc3Romain Guy @Override 1079039857520b1a03a52051b966d87d587225bdfcc3Romain Guy boolean validate() { 1080039857520b1a03a52051b966d87d587225bdfcc3Romain Guy return checkCurrent() != SURFACE_STATE_ERROR; 10817e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy } 10827e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy 10837e1160e8664a9c5c79367f4ba3c2266a39bbcef5Romain Guy @Override 1084fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy void setup(int width, int height) { 1085eca9b1f53c2c291cbfb89b5f3cc45db7bdca6c7dRomain Guy if (validate()) { 1086eca9b1f53c2c291cbfb89b5f3cc45db7bdca6c7dRomain Guy mCanvas.setViewport(width, height); 108740e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase mWidth = width; 108840e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase mHeight = height; 1089eca9b1f53c2c291cbfb89b5f3cc45db7bdca6c7dRomain Guy } 1090e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 10917d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy 109240e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase @Override 109340e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase int getWidth() { 109440e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase return mWidth; 109540e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase } 109640e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase 109740e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase @Override 109840e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase int getHeight() { 109940e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase return mHeight; 110040e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase } 110140e0383dce630ed9b2b1aa0e497709b89dfab6efChet Haase 110208837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase @Override 110308837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase HardwareCanvas getCanvas() { 110408837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase return mCanvas; 110508837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase } 110608837c246c9c27902c59b41c8661c2f27a4aa2bcChet Haase 1107e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy boolean canDraw() { 1108e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy return mGl != null && mCanvas != null; 1109e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 1110e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 111144b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase int onPreDraw(Rect dirty) { 111244b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase return DisplayList.STATUS_DONE; 1113e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 1114e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 1115b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy void onPostDraw() { 1116b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy } 11172d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy 11188f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy class FunctorsRunnable implements Runnable { 11198f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy View.AttachInfo attachInfo; 11208f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy 11218f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy @Override 11228f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy public void run() { 11238f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy final HardwareRenderer renderer = attachInfo.mHardwareRenderer; 11248f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy if (renderer == null || !renderer.isEnabled() || renderer != GlRenderer.this) { 11258f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy return; 11268f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } 11278f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy 11288f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy final int surfaceState = checkCurrent(); 11298f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy if (surfaceState != SURFACE_STATE_ERROR) { 11308f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy int status = mCanvas.invokeFunctors(mRedrawClip); 11318f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy handleFunctorStatus(attachInfo, status); 11328f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } 11338f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } 11348f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } 11358f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy 11362d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy @Override 113750d133e290468fd149b5c03e46549afca2ee05f8Romain Guy boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks, 11387d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy Rect dirty) { 1139e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy if (canDraw()) { 114002ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy if (!hasDirtyRegions()) { 11417d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy dirty = null; 11427d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy } 11432d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy attachInfo.mIgnoreDirtyState = true; 114402ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy attachInfo.mDrawingTime = SystemClock.uptimeMillis(); 114502ccac69fd1c0a03c24c5f3ace0ad4bed337b1fdRomain Guy 11464702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn view.mPrivateFlags |= View.PFLAG_DRAWN; 1147039857520b1a03a52051b966d87d587225bdfcc3Romain Guy 1148d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy final int surfaceState = checkCurrent(); 1149d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy if (surfaceState != SURFACE_STATE_ERROR) { 11507687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy HardwareCanvas canvas = mCanvas; 11517687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy attachInfo.mHardwareCanvas = canvas; 115277e67cf9055378d00bb57f458129462f33047039Romain Guy 115377e67cf9055378d00bb57f458129462f33047039Romain Guy if (mProfileEnabled) { 115477e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileLock.lock(); 115577e67cf9055378d00bb57f458129462f33047039Romain Guy } 115677e67cf9055378d00bb57f458129462f33047039Romain Guy 1157d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy // We had to change the current surface and/or context, redraw everything 1158d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy if (surfaceState == SURFACE_STATE_UPDATED) { 1159d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy dirty = null; 11607687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy beginFrame(null); 11617687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy } else { 11627687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy int[] size = mSurfaceSize; 11637687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy beginFrame(size); 11647687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 11657687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy if (size[1] != mHeight || size[0] != mWidth) { 11667687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy mWidth = size[0]; 11677687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy mHeight = size[1]; 11687687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 11697687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy canvas.setViewport(mWidth, mHeight); 11707687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy 11717687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy dirty = null; 11727687882800f49e3fc3a14f1d7540412f77d6bd4dRomain Guy } 1173d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy } 1174d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy 11752b7028eabac80cec170572bc0e945a1d4224e595Romain Guy int saveCount = 0; 11762b7028eabac80cec170572bc0e945a1d4224e595Romain Guy int status = DisplayList.STATUS_DONE; 1177daf98e941e140e8739458126640183b9f296a2abChet Haase 1178b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy try { 11794702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED) 11804702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn == View.PFLAG_INVALIDATED; 11814702a856973a553deb82f71b1d3b6c3db5dbf4baDianne Hackborn view.mPrivateFlags &= ~View.PFLAG_INVALIDATED; 11827d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy 1183a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy long getDisplayListStartTime = 0; 1184a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy if (mProfileEnabled) { 1185a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy mProfileCurrentFrame += PROFILE_FRAME_DATA_COUNT; 1186a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy if (mProfileCurrentFrame >= mProfileData.length) { 1187a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy mProfileCurrentFrame = 0; 1188a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy } 1189a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy 119095db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown getDisplayListStartTime = System.nanoTime(); 119195db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown } 119295db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown 119311cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy canvas.clearLayerUpdates(); 119477e67cf9055378d00bb57f458129462f33047039Romain Guy 119511cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy DisplayList displayList; 119677e67cf9055378d00bb57f458129462f33047039Romain Guy Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList"); 119777e67cf9055378d00bb57f458129462f33047039Romain Guy try { 119877e67cf9055378d00bb57f458129462f33047039Romain Guy displayList = view.getDisplayList(); 119977e67cf9055378d00bb57f458129462f33047039Romain Guy } finally { 120077e67cf9055378d00bb57f458129462f33047039Romain Guy Trace.traceEnd(Trace.TRACE_TAG_VIEW); 120177e67cf9055378d00bb57f458129462f33047039Romain Guy } 120295db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown 12037c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame"); 12047c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy try { 12057c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy status = onPreDraw(dirty); 12067c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy } finally { 12077c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy Trace.traceEnd(Trace.TRACE_TAG_VIEW); 12087c25aab491707f7324f9941b8cfa9bd2b4b97e76Romain Guy } 12092b7028eabac80cec170572bc0e945a1d4224e595Romain Guy saveCount = canvas.save(); 12102b7028eabac80cec170572bc0e945a1d4224e595Romain Guy callbacks.onHardwarePreDraw(canvas); 12112b7028eabac80cec170572bc0e945a1d4224e595Romain Guy 1212a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy if (mProfileEnabled) { 121395db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown long now = System.nanoTime(); 1214a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy float total = (now - getDisplayListStartTime) * 0.000001f; 1215a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy //noinspection PointlessArithmeticExpression 1216a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy mProfileData[mProfileCurrentFrame] = total; 121795db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown } 121895db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown 1219daf98e941e140e8739458126640183b9f296a2abChet Haase if (displayList != null) { 1220a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy long drawDisplayListStartTime = 0; 1221a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy if (mProfileEnabled) { 122295db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown drawDisplayListStartTime = System.nanoTime(); 122395db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown } 122495db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown 122577e67cf9055378d00bb57f458129462f33047039Romain Guy Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList"); 122677e67cf9055378d00bb57f458129462f33047039Romain Guy try { 122777e67cf9055378d00bb57f458129462f33047039Romain Guy status |= canvas.drawDisplayList(displayList, mRedrawClip, 122877e67cf9055378d00bb57f458129462f33047039Romain Guy DisplayList.FLAG_CLIP_CHILDREN); 122977e67cf9055378d00bb57f458129462f33047039Romain Guy } finally { 123077e67cf9055378d00bb57f458129462f33047039Romain Guy Trace.traceEnd(Trace.TRACE_TAG_VIEW); 123177e67cf9055378d00bb57f458129462f33047039Romain Guy } 123295db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown 1233a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy if (mProfileEnabled) { 123495db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown long now = System.nanoTime(); 1235a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy float total = (now - drawDisplayListStartTime) * 0.000001f; 1236a676ad7e34c9afbaafaeca8c3fe96e95c518828eRomain Guy mProfileData[mProfileCurrentFrame + 1] = total; 123795db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown } 123895db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown 12398f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy handleFunctorStatus(attachInfo, status); 1240daf98e941e140e8739458126640183b9f296a2abChet Haase } else { 1241daf98e941e140e8739458126640183b9f296a2abChet Haase // Shouldn't reach here 1242daf98e941e140e8739458126640183b9f296a2abChet Haase view.draw(canvas); 1243daf98e941e140e8739458126640183b9f296a2abChet Haase } 1244b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy } finally { 1245b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy callbacks.onHardwarePostDraw(canvas); 1246b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy canvas.restoreToCount(saveCount); 1247b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy view.mRecreateDisplayList = false; 124819f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy 1249a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka mFrameCount++; 125019f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy 1251b04f7e9438e8f73081f9be3fda166098042263a5Romain Guy if (mDebugDirtyRegions) { 12527d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy if (mDebugPaint == null) { 12537d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy mDebugPaint = new Paint(); 12547d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy mDebugPaint.setColor(0x7fff0000); 12557d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy } 125619f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy 1257a3fabff98590d26f0c362cb09dc378fece66215cMichael Jurka if (dirty != null && (mFrameCount & 1) == 0) { 12587d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy canvas.drawRect(dirty, mDebugPaint); 12597d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy } 12607d7b5490a0b0763e831b31bc11f17d8159b5914aRomain Guy } 1261b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy } 1262daf98e941e140e8739458126640183b9f296a2abChet Haase 1263b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy onPostDraw(); 1264daf98e941e140e8739458126640183b9f296a2abChet Haase 1265b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy attachInfo.mIgnoreDirtyState = false; 1266486590963e2207d68eebd6944fec70d50d41116aChet Haase 1267486590963e2207d68eebd6944fec70d50d41116aChet Haase if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) { 1268486590963e2207d68eebd6944fec70d50d41116aChet Haase long eglSwapBuffersStartTime = 0; 1269486590963e2207d68eebd6944fec70d50d41116aChet Haase if (mProfileEnabled) { 1270486590963e2207d68eebd6944fec70d50d41116aChet Haase eglSwapBuffersStartTime = System.nanoTime(); 1271486590963e2207d68eebd6944fec70d50d41116aChet Haase } 1272486590963e2207d68eebd6944fec70d50d41116aChet Haase 1273486590963e2207d68eebd6944fec70d50d41116aChet Haase sEgl.eglSwapBuffers(sEglDisplay, mEglSurface); 1274486590963e2207d68eebd6944fec70d50d41116aChet Haase 1275486590963e2207d68eebd6944fec70d50d41116aChet Haase if (mProfileEnabled) { 1276486590963e2207d68eebd6944fec70d50d41116aChet Haase long now = System.nanoTime(); 1277486590963e2207d68eebd6944fec70d50d41116aChet Haase float total = (now - eglSwapBuffersStartTime) * 0.000001f; 1278486590963e2207d68eebd6944fec70d50d41116aChet Haase mProfileData[mProfileCurrentFrame + 2] = total; 1279486590963e2207d68eebd6944fec70d50d41116aChet Haase } 1280486590963e2207d68eebd6944fec70d50d41116aChet Haase 1281486590963e2207d68eebd6944fec70d50d41116aChet Haase checkEglErrors(); 128295db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown } 128395db2b20d7bc0aaf00b1d4418124f5cf0a755d74Jeff Brown 128477e67cf9055378d00bb57f458129462f33047039Romain Guy if (mProfileEnabled) { 128577e67cf9055378d00bb57f458129462f33047039Romain Guy mProfileLock.unlock(); 128677e67cf9055378d00bb57f458129462f33047039Romain Guy } 128777e67cf9055378d00bb57f458129462f33047039Romain Guy 128850d133e290468fd149b5c03e46549afca2ee05f8Romain Guy return dirty == null; 12899a40babc62416259d18783ce8c03c00042ec317bRomain Guy } 12902d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 129150d133e290468fd149b5c03e46549afca2ee05f8Romain Guy 129250d133e290468fd149b5c03e46549afca2ee05f8Romain Guy return false; 12932d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 1294039857520b1a03a52051b966d87d587225bdfcc3Romain Guy 12958f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy private void handleFunctorStatus(View.AttachInfo attachInfo, int status) { 12968f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy // If the draw flag is set, functors will be invoked while executing 12978f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy // the tree of display lists 12988f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy if ((status & DisplayList.STATUS_DRAW) != 0) { 12998f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy if (mRedrawClip.isEmpty()) { 13008f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy attachInfo.mViewRootImpl.invalidate(); 13018f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } else { 13028f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy attachInfo.mViewRootImpl.invalidateChildInParent(null, mRedrawClip); 13038f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy mRedrawClip.setEmpty(); 13048f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } 13058f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } 13068f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy 13078f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy if ((status & DisplayList.STATUS_INVOKE) != 0) { 1308cb82b942c89bf69b6c03e2f4951f519c1be115dcChris Craik scheduleFunctors(attachInfo, true); 1309ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 1310ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 1311ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 1312cb82b942c89bf69b6c03e2f4951f519c1be115dcChris Craik private void scheduleFunctors(View.AttachInfo attachInfo, boolean delayed) { 1313ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy mFunctorsRunnable.attachInfo = attachInfo; 1314ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (!attachInfo.mHandler.hasCallbacks(mFunctorsRunnable)) { 13158f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy // delay the functor callback by a few ms so it isn't polled constantly 1316cb82b942c89bf69b6c03e2f4951f519c1be115dcChris Craik attachInfo.mHandler.postDelayed(mFunctorsRunnable, 1317cb82b942c89bf69b6c03e2f4951f519c1be115dcChris Craik delayed ? FUNCTOR_PROCESS_DELAY : 0); 13188f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } 13198f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy } 13208f3b8e32993d190a26c70c839a63d8ce4c3b16d9Romain Guy 1321ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy @Override 1322ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy void detachFunctor(int functor) { 1323ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (mCanvas != null) { 1324ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy mCanvas.detachFunctor(functor); 1325932b7f6765968bd526c03512f3805fbc3924dc29Chris Craik } 1326ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 1327ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 1328ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy @Override 132941ee465734d0006797a8fd36e88976c1e85d161cChris Craik boolean attachFunctor(View.AttachInfo attachInfo, int functor) { 1330ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy if (mCanvas != null) { 1331ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy mCanvas.attachFunctor(functor); 1332cb82b942c89bf69b6c03e2f4951f519c1be115dcChris Craik scheduleFunctors(attachInfo, false); 133341ee465734d0006797a8fd36e88976c1e85d161cChris Craik return true; 1334ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 133541ee465734d0006797a8fd36e88976c1e85d161cChris Craik return false; 1336ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy } 1337ba6be8a62dcdb3ffd210cd36b9af4e3a658eac47Romain Guy 1338039857520b1a03a52051b966d87d587225bdfcc3Romain Guy /** 1339566b3efb25299d2a9c8ae827522802bad965426aRomain Guy * Ensures the current EGL context is the one we expect. 1340039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * 1341039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current, 1342039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or 1343039857520b1a03a52051b966d87d587225bdfcc3Romain Guy * {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one 1344039857520b1a03a52051b966d87d587225bdfcc3Romain Guy */ 1345912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy int checkCurrent() { 1346566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (mEglThread != Thread.currentThread()) { 1347039857520b1a03a52051b966d87d587225bdfcc3Romain Guy throw new IllegalStateException("Hardware acceleration can only be used with a " + 1348566b3efb25299d2a9c8ae827522802bad965426aRomain Guy "single UI thread.\nOriginal thread: " + mEglThread + "\n" + 1349039857520b1a03a52051b966d87d587225bdfcc3Romain Guy "Current thread: " + Thread.currentThread()); 1350039857520b1a03a52051b966d87d587225bdfcc3Romain Guy } 1351039857520b1a03a52051b966d87d587225bdfcc3Romain Guy 1352566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (!mEglContext.equals(sEgl.eglGetCurrentContext()) || 1353484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy !mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW))) { 1354566b3efb25299d2a9c8ae827522802bad965426aRomain Guy if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 13559745fae73b584f3e9a9c304098ed9b11f506e93bRomain Guy Log.e(LOG_TAG, "eglMakeCurrent failed " + 1356407ec78b828173257b0c5dae221649a4ccd8b058Romain Guy GLUtils.getEGLErrorString(sEgl.eglGetError())); 1357eca9b1f53c2c291cbfb89b5f3cc45db7bdca6c7dRomain Guy fallback(true); 1358d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy return SURFACE_STATE_ERROR; 1359d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy } else { 13609477c6e6581ce97976250951f33e1297604ac777Romain Guy if (mUpdateDirtyRegions) { 13619477c6e6581ce97976250951f33e1297604ac777Romain Guy enableDirtyRegions(); 13629477c6e6581ce97976250951f33e1297604ac777Romain Guy mUpdateDirtyRegions = false; 13639477c6e6581ce97976250951f33e1297604ac777Romain Guy } 1364d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy return SURFACE_STATE_UPDATED; 1365fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy } 1366fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy } 1367d88f54c5c4ce59585b8b9e6009836f14c00be743Romain Guy return SURFACE_STATE_SUCCESS; 1368fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy } 1369e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 1370fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy 1371e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy /** 1372e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy * Hardware renderer using OpenGL ES 2.0. 1373e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy */ 1374e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy static class Gl20Renderer extends GlRenderer { 1375e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy private GLES20Canvas mGlCanvas; 1376e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 1377912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy private static EGLSurface sPbuffer; 1378912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy private static final Object[] sPbufferLock = new Object[0]; 1379912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy 138031f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy static class Gl20RendererEglContext extends ManagedEGLContext { 1381717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn final Handler mHandler = new Handler(); 1382717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 138331f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy public Gl20RendererEglContext(EGLContext context) { 1384717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn super(context); 1385717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn } 1386717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 1387717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn @Override 1388717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn public void onTerminate(final EGLContext eglContext) { 1389717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn // Make sure we do this on the correct thread. 1390717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn if (mHandler.getLooper() != Looper.myLooper()) { 1391717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn mHandler.post(new Runnable() { 13925d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy @Override 13935d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy public void run() { 1394717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn onTerminate(eglContext); 1395717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn } 1396717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn }); 1397717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn return; 1398717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn } 1399717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 1400717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn synchronized (sEglLock) { 1401717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn if (sEgl == null) return; 1402717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 1403717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn if (EGLImpl.getInitCount(sEglDisplay) == 1) { 1404717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn usePbufferSurface(eglContext); 1405717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn GLES20Canvas.terminateCaches(); 1406717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 1407717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sEgl.eglDestroyContext(sEglDisplay, eglContext); 1408a998dff5d49a423aaf7097aa8f96bf5bdc681d25Romain Guy sEglContextStorage.set(null); 1409717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sEglContextStorage.remove(); 1410717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 1411717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sEgl.eglDestroySurface(sEglDisplay, sPbuffer); 141231f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, 141331f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy EGL_NO_SURFACE, EGL_NO_CONTEXT); 1414717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 1415717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sEgl.eglReleaseThread(); 1416717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sEgl.eglTerminate(sEglDisplay); 1417717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 1418717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sEgl = null; 1419717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sEglDisplay = null; 1420717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sEglConfig = null; 1421717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn sPbuffer = null; 1422717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn } 1423717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn } 1424717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn } 1425717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn } 1426717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn 1427e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy Gl20Renderer(boolean translucent) { 1428e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy super(2, translucent); 1429e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 1430e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 14312d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy @Override 14325d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy HardwareCanvas createCanvas() { 14336b7bd24659fb175fe1f0e97c86c18969918b496aRomain Guy return mGlCanvas = new GLES20Canvas(mTranslucent); 1434e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy } 1435e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy 1436e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy @Override 14375d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy ManagedEGLContext createManagedContext(EGLContext eglContext) { 14385d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy return new Gl20Renderer.Gl20RendererEglContext(mEglContext); 14395d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy } 14405d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy 14415d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy @Override 1442e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy int[] getConfig(boolean dirtyRegions) { 1443e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy return new int[] { 1444bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, 1445484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy EGL_RED_SIZE, 8, 1446484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy EGL_GREEN_SIZE, 8, 1447484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy EGL_BLUE_SIZE, 8, 1448484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy EGL_ALPHA_SIZE, 8, 1449484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy EGL_DEPTH_SIZE, 0, 14508efca54693b1fa956eede0367fffe8bb0d3531f0Romain Guy EGL_CONFIG_CAVEAT, EGL_NONE, 14517c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy // TODO: Find a better way to choose the stencil size 14527c450aaa3caac2a05fcb20a177483d0e92378426Romain Guy EGL_STENCIL_SIZE, mShowOverdraw ? GLES20Canvas.getStencilSize() : 0, 1453484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy EGL_SURFACE_TYPE, EGL_WINDOW_BIT | 1454bd43152bda835c5a9a619a5869344a6a3af11917Romain Guy (dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0), 1455484c719c1c4a86d10d7be821782a808d0e12ea4eRomain Guy EGL_NONE 1456e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy }; 1457e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy } 14588ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy 14598ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy @Override 14608ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy void initCaches() { 14618ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy GLES20Canvas.initCaches(); 14628ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy } 1463e91a9c7ab075c43e983fdeb9af80447caa501337Romain Guy 1464b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy @Override 1465b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy boolean canDraw() { 1466b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy return super.canDraw() && mGlCanvas != null; 1467b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy } 1468e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 1469e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy @Override 147044b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase int onPreDraw(Rect dirty) { 147144b2fe3fc114ee5f7273c6b0fee2cc999bf244a2Chet Haase return mGlCanvas.onPreDraw(dirty); 1472e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy } 1473e3924992733234fd7d7a614c165a94e0a2cd6b84Romain Guy 1474b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy @Override 1475b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy void onPostDraw() { 1476b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy mGlCanvas.onPostDraw(); 1477b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy } 1478b025b9c8b4efefadb01937db61a1f8ee7d2452bfRomain Guy 1479b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy @Override 148067f27952c1bcb2230beef9b5ca0bf42edad436a9Romain Guy void destroy(boolean full) { 1481b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy try { 1482b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy super.destroy(full); 1483b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy } finally { 1484b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy if (full && mGlCanvas != null) { 1485b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy mGlCanvas = null; 1486b8c0de2c2726f4e8f0029710047efe0c8e6661edRomain Guy } 148767f27952c1bcb2230beef9b5ca0bf42edad436a9Romain Guy } 148867f27952c1bcb2230beef9b5ca0bf42edad436a9Romain Guy } 148967f27952c1bcb2230beef9b5ca0bf42edad436a9Romain Guy 149067f27952c1bcb2230beef9b5ca0bf42edad436a9Romain Guy @Override 14919ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy void setup(int width, int height) { 14929ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy super.setup(width, height); 14939ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy if (mVsyncDisabled) { 1494244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy disableVsync(); 14959ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy } 14969ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy } 14979ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy 14989ace8f5e79e76893fe4ca9e4d10f6c4056330485Romain Guy @Override 149911cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy void pushLayerUpdate(HardwareLayer layer) { 150011cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy mGlCanvas.pushLayerUpdate(layer); 150111cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy } 150211cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy 150311cb642756093a4af901b1525375b1eb2b5c3e2bRomain Guy @Override 150413631f3da855f200a151e7837ed9f6b079622b58Romain Guy public DisplayList createDisplayList(String name) { 150513631f3da855f200a151e7837ed9f6b079622b58Romain Guy return new GLES20DisplayList(name); 1506b051e895ccb696604349c6c5efe7c4747e1d1ab6Romain Guy } 1507aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 1508aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 1509a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy HardwareLayer createHardwareLayer(boolean isOpaque) { 1510a9489274d67b540804aafb587a226f7c2ae4464dRomain Guy return new GLES20TextureLayer(isOpaque); 1511aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 1512aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 15136c319ca1275c8db892c39b48fc54864c949f9171Romain Guy @Override 15146c319ca1275c8db892c39b48fc54864c949f9171Romain Guy HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque) { 1515aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return new GLES20RenderLayer(width, height, isOpaque); 1516aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 1517aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 1518aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy @Override 1519e5e0c50f7dfaccc220725c5595080e921ffda1e4Romain Guy SurfaceTexture createSurfaceTexture(HardwareLayer layer) { 1520aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy return ((GLES20TextureLayer) layer).getSurfaceTexture(); 1521aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy } 1522aa6c24c21c727a196451332448d4e3b11a80be69Romain Guy 15236d7475d666baefaa3ba9f0dcee25238739454241Romain Guy @Override 15242af3524beb75150d347accc925022daa53b4a789Jamie Gennis void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) { 15252af3524beb75150d347accc925022daa53b4a789Jamie Gennis ((GLES20TextureLayer) layer).setSurfaceTexture(surfaceTexture); 15262af3524beb75150d347accc925022daa53b4a789Jamie Gennis } 15272af3524beb75150d347accc925022daa53b4a789Jamie Gennis 15282af3524beb75150d347accc925022daa53b4a789Jamie Gennis @Override 15291ac4765e959c79101f64b1279887ed469334c268Romain Guy boolean safelyRun(Runnable action) { 15301ac4765e959c79101f64b1279887ed469334c268Romain Guy boolean needsContext = true; 15311ac4765e959c79101f64b1279887ed469334c268Romain Guy if (isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) needsContext = false; 15321ac4765e959c79101f64b1279887ed469334c268Romain Guy 15331ac4765e959c79101f64b1279887ed469334c268Romain Guy if (needsContext) { 15341ac4765e959c79101f64b1279887ed469334c268Romain Guy Gl20RendererEglContext managedContext = 15351ac4765e959c79101f64b1279887ed469334c268Romain Guy (Gl20RendererEglContext) sEglContextStorage.get(); 15361ac4765e959c79101f64b1279887ed469334c268Romain Guy if (managedContext == null) return false; 15371ac4765e959c79101f64b1279887ed469334c268Romain Guy usePbufferSurface(managedContext.getContext()); 15381ac4765e959c79101f64b1279887ed469334c268Romain Guy } 15390872b370422eb1f9007b4717b8796543873e6390Jesse Hall 15401ac4765e959c79101f64b1279887ed469334c268Romain Guy try { 15411ac4765e959c79101f64b1279887ed469334c268Romain Guy action.run(); 15421ac4765e959c79101f64b1279887ed469334c268Romain Guy } finally { 15430872b370422eb1f9007b4717b8796543873e6390Jesse Hall if (needsContext) { 15440872b370422eb1f9007b4717b8796543873e6390Jesse Hall sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, 15450872b370422eb1f9007b4717b8796543873e6390Jesse Hall EGL_NO_SURFACE, EGL_NO_CONTEXT); 15460872b370422eb1f9007b4717b8796543873e6390Jesse Hall } 154731f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy } 15481ac4765e959c79101f64b1279887ed469334c268Romain Guy 15491ac4765e959c79101f64b1279887ed469334c268Romain Guy return true; 15501ac4765e959c79101f64b1279887ed469334c268Romain Guy } 15511ac4765e959c79101f64b1279887ed469334c268Romain Guy 15521ac4765e959c79101f64b1279887ed469334c268Romain Guy @Override 1553bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy void destroyLayers(final View view) { 1554bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy if (view != null) { 1555bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy safelyRun(new Runnable() { 1556bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy @Override 1557bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy public void run() { 1558bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy if (mCanvas != null) { 1559bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy mCanvas.clearLayerUpdates(); 1560bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy } 1561bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy destroyHardwareLayer(view); 1562bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS); 1563bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy } 1564bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy }); 1565bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy } 1566bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy } 1567bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy 1568bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy private static void destroyHardwareLayer(View view) { 1569bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy view.destroyLayer(true); 1570bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy 1571bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy if (view instanceof ViewGroup) { 1572bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy ViewGroup group = (ViewGroup) view; 1573bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy 1574bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy int count = group.getChildCount(); 1575bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy for (int i = 0; i < count; i++) { 1576bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy destroyHardwareLayer(group.getChildAt(i)); 1577bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy } 1578bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy } 1579bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy } 1580bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy 1581bd17bd34311ba5af4b6ac9ddc4b8c71888f2e6f1Romain Guy @Override 15821ac4765e959c79101f64b1279887ed469334c268Romain Guy void destroyHardwareResources(final View view) { 15831ac4765e959c79101f64b1279887ed469334c268Romain Guy if (view != null) { 15841ac4765e959c79101f64b1279887ed469334c268Romain Guy safelyRun(new Runnable() { 15851ac4765e959c79101f64b1279887ed469334c268Romain Guy @Override 15861ac4765e959c79101f64b1279887ed469334c268Romain Guy public void run() { 15876a2d17f71342f981c9df1dc5beff33e30eb3ae2bChet Haase if (mCanvas != null) { 15886a2d17f71342f981c9df1dc5beff33e30eb3ae2bChet Haase mCanvas.clearLayerUpdates(); 15896a2d17f71342f981c9df1dc5beff33e30eb3ae2bChet Haase } 15901ac4765e959c79101f64b1279887ed469334c268Romain Guy destroyResources(view); 15911ac4765e959c79101f64b1279887ed469334c268Romain Guy GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS); 15921ac4765e959c79101f64b1279887ed469334c268Romain Guy } 15931ac4765e959c79101f64b1279887ed469334c268Romain Guy }); 15941ac4765e959c79101f64b1279887ed469334c268Romain Guy } 159531f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy } 1596244ada1d35419b7be9de0fc833bb03955b725ffaRomain Guy 159731f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy private static void destroyResources(View view) { 159831f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy view.destroyHardwareResources(); 159931f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy 160031f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy if (view instanceof ViewGroup) { 160131f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy ViewGroup group = (ViewGroup) view; 160231f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy 160331f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy int count = group.getChildCount(); 160431f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy for (int i = 0; i < count; i++) { 160531f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy destroyResources(group.getChildAt(i)); 160631f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy } 160731f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy } 160831f2c2e94656530fbf6282803e62edb47e9a894dRomain Guy } 16096d7475d666baefaa3ba9f0dcee25238739454241Romain Guy 16106d7475d666baefaa3ba9f0dcee25238739454241Romain Guy static HardwareRenderer create(boolean translucent) { 16116d7475d666baefaa3ba9f0dcee25238739454241Romain Guy if (GLES20Canvas.isAvailable()) { 16126d7475d666baefaa3ba9f0dcee25238739454241Romain Guy return new Gl20Renderer(translucent); 16136d7475d666baefaa3ba9f0dcee25238739454241Romain Guy } 16146d7475d666baefaa3ba9f0dcee25238739454241Romain Guy return null; 16156d7475d666baefaa3ba9f0dcee25238739454241Romain Guy } 16166d7475d666baefaa3ba9f0dcee25238739454241Romain Guy 161719f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy static void startTrimMemory(int level) { 1618912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy if (sEgl == null || sEglConfig == null) return; 1619912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy 16205d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy Gl20RendererEglContext managedContext = 16215d6999e1ca457948e06792ea6259ffa947c9fa81Romain Guy (Gl20RendererEglContext) sEglContextStorage.get(); 1622912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy // We do not have OpenGL objects 1623717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn if (managedContext == null) { 1624912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy return; 1625912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy } else { 1626717a25dc2a411edb548859cd6870363346c71b01Dianne Hackborn usePbufferSurface(managedContext.getContext()); 16272d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 1628912a7b32d0c59ba38265c5dd6ff84ce93f909a7fRomain Guy 162927ff913d56de8400083a13fc572e2812b32c890cDianne Hackborn if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { 163027ff913d56de8400083a13fc572e2812b32c890cDianne Hackborn GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL); 163127ff913d56de8400083a13fc572e2812b32c890cDianne Hackborn } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) { 163227ff913d56de8400083a13fc572e2812b32c890cDianne Hackborn GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE); 1633bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy } 163419f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy } 16350872b370422eb1f9007b4717b8796543873e6390Jesse Hall 163619f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy static void endTrimMemory() { 163719f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy if (sEgl != null && sEglDisplay != null) { 163819f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 163919f86e831ee0629b24385b0bb51d27ff91961dd2Romain Guy } 1640bdf7609867a3f886455c51dba91623a86cceb6e2Romain Guy } 16418ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy 16428ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy private static void usePbufferSurface(EGLContext eglContext) { 16438ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy synchronized (sPbufferLock) { 16448ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy // Create a temporary 1x1 pbuffer so we have a context 16458ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy // to clear our OpenGL objects 16468ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy if (sPbuffer == null) { 16478ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy sPbuffer = sEgl.eglCreatePbufferSurface(sEglDisplay, sEglConfig, new int[] { 16488ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE 16498ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy }); 16508ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy } 16518ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy } 16528ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext); 16538ff6b9ebeeb24a6161ec6098e6bfdf8790ee5695Romain Guy } 16542d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy } 16552d6145993e19d2bb664766dbaf3c1e9ad3d12cdcRomain Guy} 1656