summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2011-11-10 19:23:58 -0800
committerRomain Guy <romainguy@google.com>2011-11-10 19:23:58 -0800
commitda96f8ac2c1c35a54f3f36e6d776cb386a251d03 (patch)
tree646abfdfeee4346b422943924182162f4a3cdf84 /libs
parent50a66f0e9c5a85a6af4a99eb66656a69eba24572 (diff)
downloadframeworks_base-da96f8ac2c1c35a54f3f36e6d776cb386a251d03.zip
frameworks_base-da96f8ac2c1c35a54f3f36e6d776cb386a251d03.tar.gz
frameworks_base-da96f8ac2c1c35a54f3f36e6d776cb386a251d03.tar.bz2
Discard framebuffer rendering queues when discarding layers
Bug #5581817 Change-Id: If612846ec5f7793710fc4df152791fb32c506551
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Android.mk2
-rw-r--r--libs/hwui/Extensions.h3
-rw-r--r--libs/hwui/LayerRenderer.cpp26
-rw-r--r--libs/hwui/LayerRenderer.h1
-rw-r--r--libs/hwui/OpenGLRenderer.cpp5
5 files changed, 34 insertions, 3 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 9bfc94c..95e0a18 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -38,7 +38,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
external/skia/src/ports \
external/skia/include/utils
- LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER
+ LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DGL_GLEXT_PROTOTYPES
LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index 38d1130..48e4247 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -66,6 +66,7 @@ public:
mHasNPot = hasExtension("GL_OES_texture_npot");
mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
+ mHasDiscardFramebuffer = hasExtension("GL_EXT_discard_framebuffer");
const char* vendor = (const char*) glGetString(GL_VENDOR);
EXT_LOGD("Vendor: %s", vendor);
@@ -80,6 +81,7 @@ public:
inline bool hasNPot() const { return mHasNPot; }
inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
inline bool needsHighpTexCoords() const { return mNeedsHighpTexCoords; }
+ inline bool hasDiscardFramebuffer() const { return mHasDiscardFramebuffer; }
bool hasExtension(const char* extension) const {
const String8 s(extension);
@@ -98,6 +100,7 @@ private:
bool mHasNPot;
bool mNeedsHighpTexCoords;
bool mHasFramebufferFetch;
+ bool mHasDiscardFramebuffer;
}; // class Extensions
}; // namespace uirenderer
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e38b479..b7c079b 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -305,8 +305,10 @@ void LayerRenderer::destroyLayer(Layer* layer) {
LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d",
layer->getWidth(), layer->getHeight(), layer->getFbo());
- if (layer->getFbo()) {
- Caches::getInstance().fboCache.put(layer->getFbo());
+ GLuint fbo = layer->getFbo();
+ if (fbo) {
+ flushLayer(layer);
+ Caches::getInstance().fboCache.put(fbo);
}
if (!Caches::getInstance().layerCache.put(layer)) {
@@ -331,6 +333,26 @@ void LayerRenderer::destroyLayerDeferred(Layer* layer) {
}
}
+void LayerRenderer::flushLayer(Layer* layer) {
+#ifdef GL_EXT_discard_framebuffer
+ GLuint fbo = layer->getFbo();
+ if (layer && fbo) {
+ // If possible, discard any enqued operations on deferred
+ // rendering architectures
+ if (Caches::getInstance().extensions.hasDiscardFramebuffer()) {
+ GLuint previousFbo;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
+
+ GLenum attachments = GL_COLOR_ATTACHMENT0;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachments);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
+ }
+ }
+#endif
+}
+
bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
Caches& caches = Caches::getInstance();
if (layer && layer->isTextureLayer() && bitmap->width() <= caches.maxTextureSize &&
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 6104301..72d8d81 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -61,6 +61,7 @@ public:
bool isOpaque, GLenum renderTarget, float* transform);
ANDROID_API static void destroyLayer(Layer* layer);
ANDROID_API static void destroyLayerDeferred(Layer* layer);
+ ANDROID_API static void flushLayer(Layer* layer);
ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
private:
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 32595e4..1a8c199 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -611,6 +611,11 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
}
if (fboLayer) {
+ // Note: No need to use glDiscardFramebufferEXT() since we never
+ // create/compose layers that are not on screen with this
+ // code path
+ // See LayerRenderer::destroyLayer(Layer*)
+
// Detach the texture from the FBO
glBindFramebuffer(GL_FRAMEBUFFER, current->fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);