Loading core/jni/android_view_Surface.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -374,6 +374,7 @@ static jlong create(JNIEnv* env, jclass clazz, jlong rootNodePtr, jlong surfaceP ContextFactory factory; RenderProxy* proxy = new RenderProxy(false, rootNode, &factory); proxy->loadSystemProperties(); proxy->setSwapBehavior(kSwap_discardBuffer); proxy->initialize(surface); // Shadows can't be used via this interface, so just set the light source // to all 0s. (and width & height are unused, TODO remove them) Loading libs/hwui/renderthread/CanvasContext.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -42,7 +42,8 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, : mRenderThread(thread) , mEglManager(thread.eglManager()) , mEglSurface(EGL_NO_SURFACE) , mDirtyRegionsEnabled(false) , mBufferPreserved(false) , mSwapBehavior(kSwap_default) , mOpaque(!translucent) , mCanvas(NULL) , mHaveNewSurface(false) Loading Loading @@ -82,7 +83,8 @@ void CanvasContext::setSurface(ANativeWindow* window) { } if (mEglSurface != EGL_NO_SURFACE) { mDirtyRegionsEnabled = mEglManager.enableDirtyRegions(mEglSurface); const bool preserveBuffer = (mSwapBehavior != kSwap_discardBuffer); mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); mHaveNewSurface = true; makeCurrent(); } else { Loading @@ -103,6 +105,10 @@ void CanvasContext::requireSurface() { makeCurrent(); } void CanvasContext::setSwapBehavior(SwapBehavior swapBehavior) { mSwapBehavior = swapBehavior; } bool CanvasContext::initialize(ANativeWindow* window) { setSurface(window); if (mCanvas) return false; Loading Loading @@ -200,7 +206,7 @@ void CanvasContext::draw() { if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { mCanvas->setViewport(width, height); dirty.setEmpty(); } else if (!mDirtyRegionsEnabled || mHaveNewSurface) { } else if (!mBufferPreserved || mHaveNewSurface) { dirty.setEmpty(); } else { if (!dirty.isEmpty() && !dirty.intersect(0, 0, width, height)) { Loading libs/hwui/renderthread/CanvasContext.h +10 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,11 @@ namespace renderthread { class EglManager; enum SwapBehavior { kSwap_default, kSwap_discardBuffer, }; // This per-renderer class manages the bridge between the global EGL context // and the render surface. // TODO: Rename to Renderer or some other per-window, top-level manager Loading @@ -57,6 +62,9 @@ public: IContextFactory* contextFactory); virtual ~CanvasContext(); // Won't take effect until next EGLSurface creation void setSwapBehavior(SwapBehavior swapBehavior); bool initialize(ANativeWindow* window); void updateSurface(ANativeWindow* window); void pauseSurface(ANativeWindow* window); Loading Loading @@ -111,7 +119,8 @@ private: EglManager& mEglManager; sp<ANativeWindow> mNativeWindow; EGLSurface mEglSurface; bool mDirtyRegionsEnabled; bool mBufferPreserved; SwapBehavior mSwapBehavior; bool mOpaque; OpenGLRenderer* mCanvas; Loading libs/hwui/renderthread/EglManager.cpp +24 −19 Original line number Diff line number Diff line Loading @@ -70,12 +70,12 @@ EglManager::EglManager(RenderThread& thread) , mEglConfig(0) , mEglContext(EGL_NO_CONTEXT) , mPBufferSurface(EGL_NO_SURFACE) , mRequestDirtyRegions(load_dirty_regions_property()) , mAllowPreserveBuffer(load_dirty_regions_property()) , mCurrentSurface(EGL_NO_SURFACE) , mAtlasMap(NULL) , mAtlasMapSize(0) { mCanSetDirtyRegions = mRequestDirtyRegions; ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); mCanSetPreserveBuffer = mAllowPreserveBuffer; ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false"); } void EglManager::initialize() { Loading Loading @@ -113,7 +113,7 @@ void EglManager::requireGlContext() { } void EglManager::loadConfig() { EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; EGLint swapBehavior = mCanSetPreserveBuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, Loading @@ -131,10 +131,10 @@ void EglManager::loadConfig() { if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs) || num_configs != 1) { // Failed to get a valid config if (mCanSetDirtyRegions) { if (mCanSetPreserveBuffer) { ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..."); // Try again without dirty regions enabled mCanSetDirtyRegions = false; mCanSetPreserveBuffer = false; loadConfig(); } else { LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str()); Loading Loading @@ -273,25 +273,30 @@ bool EglManager::swapBuffers(EGLSurface surface) { return false; } bool EglManager::enableDirtyRegions(EGLSurface surface) { if (!mRequestDirtyRegions) return false; bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) { if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false; if (mCanSetDirtyRegions) { if (!eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { bool preserved = false; if (mCanSetPreserveBuffer) { preserved = eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, preserve ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED); if (CC_UNLIKELY(!preserved)) { ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s", (void*) surface, egl_error_str()); return false; } return true; } // Perhaps it is already enabled? EGLint value; if (!eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &value)) { if (CC_UNLIKELY(!preserved)) { // Maybe it's already set? EGLint swapBehavior; if (eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &swapBehavior)) { preserved = (swapBehavior == EGL_BUFFER_PRESERVED); } else { ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p", (void*) surface, egl_error_str()); return false; } return value == EGL_BUFFER_PRESERVED; } return preserved; } } /* namespace renderthread */ Loading libs/hwui/renderthread/EglManager.h +4 −3 Original line number Diff line number Diff line Loading @@ -49,7 +49,8 @@ public: void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); bool swapBuffers(EGLSurface surface); bool enableDirtyRegions(EGLSurface surface); // Returns true iff the surface is now preserving buffers. bool setPreserveBuffer(EGLSurface surface, bool preserve); void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); Loading @@ -71,8 +72,8 @@ private: EGLContext mEglContext; EGLSurface mPBufferSurface; const bool mRequestDirtyRegions; bool mCanSetDirtyRegions; const bool mAllowPreserveBuffer; bool mCanSetPreserveBuffer; EGLSurface mCurrentSurface; Loading Loading
core/jni/android_view_Surface.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -374,6 +374,7 @@ static jlong create(JNIEnv* env, jclass clazz, jlong rootNodePtr, jlong surfaceP ContextFactory factory; RenderProxy* proxy = new RenderProxy(false, rootNode, &factory); proxy->loadSystemProperties(); proxy->setSwapBehavior(kSwap_discardBuffer); proxy->initialize(surface); // Shadows can't be used via this interface, so just set the light source // to all 0s. (and width & height are unused, TODO remove them) Loading
libs/hwui/renderthread/CanvasContext.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -42,7 +42,8 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, : mRenderThread(thread) , mEglManager(thread.eglManager()) , mEglSurface(EGL_NO_SURFACE) , mDirtyRegionsEnabled(false) , mBufferPreserved(false) , mSwapBehavior(kSwap_default) , mOpaque(!translucent) , mCanvas(NULL) , mHaveNewSurface(false) Loading Loading @@ -82,7 +83,8 @@ void CanvasContext::setSurface(ANativeWindow* window) { } if (mEglSurface != EGL_NO_SURFACE) { mDirtyRegionsEnabled = mEglManager.enableDirtyRegions(mEglSurface); const bool preserveBuffer = (mSwapBehavior != kSwap_discardBuffer); mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); mHaveNewSurface = true; makeCurrent(); } else { Loading @@ -103,6 +105,10 @@ void CanvasContext::requireSurface() { makeCurrent(); } void CanvasContext::setSwapBehavior(SwapBehavior swapBehavior) { mSwapBehavior = swapBehavior; } bool CanvasContext::initialize(ANativeWindow* window) { setSurface(window); if (mCanvas) return false; Loading Loading @@ -200,7 +206,7 @@ void CanvasContext::draw() { if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { mCanvas->setViewport(width, height); dirty.setEmpty(); } else if (!mDirtyRegionsEnabled || mHaveNewSurface) { } else if (!mBufferPreserved || mHaveNewSurface) { dirty.setEmpty(); } else { if (!dirty.isEmpty() && !dirty.intersect(0, 0, width, height)) { Loading
libs/hwui/renderthread/CanvasContext.h +10 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,11 @@ namespace renderthread { class EglManager; enum SwapBehavior { kSwap_default, kSwap_discardBuffer, }; // This per-renderer class manages the bridge between the global EGL context // and the render surface. // TODO: Rename to Renderer or some other per-window, top-level manager Loading @@ -57,6 +62,9 @@ public: IContextFactory* contextFactory); virtual ~CanvasContext(); // Won't take effect until next EGLSurface creation void setSwapBehavior(SwapBehavior swapBehavior); bool initialize(ANativeWindow* window); void updateSurface(ANativeWindow* window); void pauseSurface(ANativeWindow* window); Loading Loading @@ -111,7 +119,8 @@ private: EglManager& mEglManager; sp<ANativeWindow> mNativeWindow; EGLSurface mEglSurface; bool mDirtyRegionsEnabled; bool mBufferPreserved; SwapBehavior mSwapBehavior; bool mOpaque; OpenGLRenderer* mCanvas; Loading
libs/hwui/renderthread/EglManager.cpp +24 −19 Original line number Diff line number Diff line Loading @@ -70,12 +70,12 @@ EglManager::EglManager(RenderThread& thread) , mEglConfig(0) , mEglContext(EGL_NO_CONTEXT) , mPBufferSurface(EGL_NO_SURFACE) , mRequestDirtyRegions(load_dirty_regions_property()) , mAllowPreserveBuffer(load_dirty_regions_property()) , mCurrentSurface(EGL_NO_SURFACE) , mAtlasMap(NULL) , mAtlasMapSize(0) { mCanSetDirtyRegions = mRequestDirtyRegions; ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); mCanSetPreserveBuffer = mAllowPreserveBuffer; ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false"); } void EglManager::initialize() { Loading Loading @@ -113,7 +113,7 @@ void EglManager::requireGlContext() { } void EglManager::loadConfig() { EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; EGLint swapBehavior = mCanSetPreserveBuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, Loading @@ -131,10 +131,10 @@ void EglManager::loadConfig() { if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs) || num_configs != 1) { // Failed to get a valid config if (mCanSetDirtyRegions) { if (mCanSetPreserveBuffer) { ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..."); // Try again without dirty regions enabled mCanSetDirtyRegions = false; mCanSetPreserveBuffer = false; loadConfig(); } else { LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str()); Loading Loading @@ -273,25 +273,30 @@ bool EglManager::swapBuffers(EGLSurface surface) { return false; } bool EglManager::enableDirtyRegions(EGLSurface surface) { if (!mRequestDirtyRegions) return false; bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) { if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false; if (mCanSetDirtyRegions) { if (!eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { bool preserved = false; if (mCanSetPreserveBuffer) { preserved = eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, preserve ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED); if (CC_UNLIKELY(!preserved)) { ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s", (void*) surface, egl_error_str()); return false; } return true; } // Perhaps it is already enabled? EGLint value; if (!eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &value)) { if (CC_UNLIKELY(!preserved)) { // Maybe it's already set? EGLint swapBehavior; if (eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &swapBehavior)) { preserved = (swapBehavior == EGL_BUFFER_PRESERVED); } else { ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p", (void*) surface, egl_error_str()); return false; } return value == EGL_BUFFER_PRESERVED; } return preserved; } } /* namespace renderthread */ Loading
libs/hwui/renderthread/EglManager.h +4 −3 Original line number Diff line number Diff line Loading @@ -49,7 +49,8 @@ public: void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); bool swapBuffers(EGLSurface surface); bool enableDirtyRegions(EGLSurface surface); // Returns true iff the surface is now preserving buffers. bool setPreserveBuffer(EGLSurface surface, bool preserve); void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); Loading @@ -71,8 +72,8 @@ private: EGLContext mEglContext; EGLSurface mPBufferSurface; const bool mRequestDirtyRegions; bool mCanSetDirtyRegions; const bool mAllowPreserveBuffer; bool mCanSetPreserveBuffer; EGLSurface mCurrentSurface; Loading