Skip to content

Commit 2858749

Browse files
pixelflingerAndroid (Google) Code Review
authored andcommitted
Merge "Discard framebuffer rendering queues when discarding layers Bug #5581817" into ics-mr1
2 parents 2af9f21 + da96f8a commit 2858749

File tree

11 files changed

+80
-5
lines changed

11 files changed

+80
-5
lines changed

core/java/android/view/GLES20Canvas.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ static native void nUpdateTextureLayer(int layerId, int width, int height, boole
154154
static native void nSetTextureLayerTransform(int layerId, int matrix);
155155
static native void nDestroyLayer(int layerId);
156156
static native void nDestroyLayerDeferred(int layerId);
157+
static native void nFlushLayer(int layerId);
157158
static native boolean nCopyLayer(int layerId, int bitmap);
158159

159160
///////////////////////////////////////////////////////////////////////////

core/java/android/view/GLES20Layer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ void destroy() {
6060
}
6161
mLayer = 0;
6262
}
63+
64+
@Override
65+
void flush() {
66+
if (mLayer != 0) {
67+
GLES20Canvas.nFlushLayer(mLayer);
68+
}
69+
}
6370

6471
static class Finalizer {
6572
private int mLayerId;

core/java/android/view/HardwareLayer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ boolean isOpaque() {
115115
*/
116116
abstract void destroy();
117117

118+
/**
119+
* Flush the render queue associated with this layer.
120+
*/
121+
abstract void flush();
122+
118123
/**
119124
* This must be invoked before drawing onto this layer.
120125
* @param currentCanvas

core/java/android/view/View.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10146,6 +10146,12 @@ public void buildLayer() {
1014610146
break;
1014710147
}
1014810148
}
10149+
10150+
void flushLayer() {
10151+
if (mLayerType == LAYER_TYPE_HARDWARE && mHardwareLayer != null) {
10152+
mHardwareLayer.flush();
10153+
}
10154+
}
1014910155

1015010156
/**
1015110157
* <p>Returns a hardware layer that can be used to draw this view again
@@ -10158,6 +10164,9 @@ HardwareLayer getHardwareLayer() {
1015810164
!mAttachInfo.mHardwareRenderer.isEnabled()) {
1015910165
return null;
1016010166
}
10167+
10168+
if (!mAttachInfo.mHardwareRenderer.validate()) return null;
10169+
1016110170

1016210171
final int width = mRight - mLeft;
1016310172
final int height = mBottom - mTop;
@@ -10232,8 +10241,14 @@ HardwareLayer getHardwareLayer() {
1023210241
*/
1023310242
boolean destroyLayer() {
1023410243
if (mHardwareLayer != null) {
10235-
mHardwareLayer.destroy();
10236-
mHardwareLayer = null;
10244+
AttachInfo info = mAttachInfo;
10245+
if (info != null && info.mHardwareRenderer != null &&
10246+
info.mHardwareRenderer.isEnabled()) {
10247+
if (!info.mHardwareRenderer.validate()) {
10248+
mHardwareLayer.destroy();
10249+
mHardwareLayer = null;
10250+
}
10251+
}
1023710252
return true;
1023810253
}
1023910254
return false;

core/java/android/view/ViewGroup.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2957,6 +2957,16 @@ public void setChildrenLayersEnabled(boolean enabled) {
29572957
if (enabled != mDrawLayers) {
29582958
mDrawLayers = enabled;
29592959
invalidate(true);
2960+
2961+
AttachInfo info = mAttachInfo;
2962+
if (info != null && info.mHardwareRenderer != null &&
2963+
info.mHardwareRenderer.isEnabled()) {
2964+
if (!info.mHardwareRenderer.validate()) {
2965+
enabled = false;
2966+
}
2967+
} else {
2968+
enabled = false;
2969+
}
29602970

29612971
// We need to invalidate any child with a layer. For instance,
29622972
// if a child is backed by a hardware layer and we disable layers
@@ -2968,6 +2978,7 @@ public void setChildrenLayersEnabled(boolean enabled) {
29682978
for (int i = 0; i < mChildrenCount; i++) {
29692979
View child = mChildren[i];
29702980
if (child.mLayerType != LAYER_TYPE_NONE) {
2981+
if (!enabled) child.flushLayer();
29712982
child.invalidate(true);
29722983
}
29732984
}

core/jni/android_view_GLES20Canvas.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,10 @@ static void android_view_GLES20Canvas_destroyLayerDeferred(JNIEnv* env,
718718
LayerRenderer::destroyLayerDeferred(layer);
719719
}
720720

721+
static void android_view_GLES20Canvas_flushLayer(JNIEnv* env, jobject clazz, Layer* layer) {
722+
LayerRenderer::flushLayer(layer);
723+
}
724+
721725
static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
722726
OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
723727
renderer->drawLayer(layer, x, y, paint);
@@ -860,6 +864,7 @@ static JNINativeMethod gMethods[] = {
860864
{ "nSetTextureLayerTransform", "(II)V", (void*) android_view_GLES20Canvas_setTextureLayerTransform },
861865
{ "nDestroyLayer", "(I)V", (void*) android_view_GLES20Canvas_destroyLayer },
862866
{ "nDestroyLayerDeferred", "(I)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred },
867+
{ "nFlushLayer", "(I)V", (void*) android_view_GLES20Canvas_flushLayer },
863868
{ "nDrawLayer", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawLayer },
864869
{ "nCopyLayer", "(II)Z", (void*) android_view_GLES20Canvas_copyLayer },
865870

libs/hwui/Android.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
3838
external/skia/src/ports \
3939
external/skia/include/utils
4040

41-
LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER
41+
LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DGL_GLEXT_PROTOTYPES
4242
LOCAL_CFLAGS += -fvisibility=hidden
4343
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
4444
LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui

libs/hwui/Extensions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class Extensions {
6666

6767
mHasNPot = hasExtension("GL_OES_texture_npot");
6868
mHasFramebufferFetch = hasExtension("GL_NV_shader_framebuffer_fetch");
69+
mHasDiscardFramebuffer = hasExtension("GL_EXT_discard_framebuffer");
6970

7071
const char* vendor = (const char*) glGetString(GL_VENDOR);
7172
EXT_LOGD("Vendor: %s", vendor);
@@ -80,6 +81,7 @@ class Extensions {
8081
inline bool hasNPot() const { return mHasNPot; }
8182
inline bool hasFramebufferFetch() const { return mHasFramebufferFetch; }
8283
inline bool needsHighpTexCoords() const { return mNeedsHighpTexCoords; }
84+
inline bool hasDiscardFramebuffer() const { return mHasDiscardFramebuffer; }
8385

8486
bool hasExtension(const char* extension) const {
8587
const String8 s(extension);
@@ -98,6 +100,7 @@ class Extensions {
98100
bool mHasNPot;
99101
bool mNeedsHighpTexCoords;
100102
bool mHasFramebufferFetch;
103+
bool mHasDiscardFramebuffer;
101104
}; // class Extensions
102105

103106
}; // namespace uirenderer

libs/hwui/LayerRenderer.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,10 @@ void LayerRenderer::destroyLayer(Layer* layer) {
305305
LAYER_RENDERER_LOGD("Recycling layer, %dx%d fbo = %d",
306306
layer->getWidth(), layer->getHeight(), layer->getFbo());
307307

308-
if (layer->getFbo()) {
309-
Caches::getInstance().fboCache.put(layer->getFbo());
308+
GLuint fbo = layer->getFbo();
309+
if (fbo) {
310+
flushLayer(layer);
311+
Caches::getInstance().fboCache.put(fbo);
310312
}
311313

312314
if (!Caches::getInstance().layerCache.put(layer)) {
@@ -331,6 +333,26 @@ void LayerRenderer::destroyLayerDeferred(Layer* layer) {
331333
}
332334
}
333335

336+
void LayerRenderer::flushLayer(Layer* layer) {
337+
#ifdef GL_EXT_discard_framebuffer
338+
GLuint fbo = layer->getFbo();
339+
if (layer && fbo) {
340+
// If possible, discard any enqued operations on deferred
341+
// rendering architectures
342+
if (Caches::getInstance().extensions.hasDiscardFramebuffer()) {
343+
GLuint previousFbo;
344+
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &previousFbo);
345+
346+
GLenum attachments = GL_COLOR_ATTACHMENT0;
347+
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
348+
glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachments);
349+
350+
glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
351+
}
352+
}
353+
#endif
354+
}
355+
334356
bool LayerRenderer::copyLayer(Layer* layer, SkBitmap* bitmap) {
335357
Caches& caches = Caches::getInstance();
336358
if (layer && layer->isTextureLayer() && bitmap->width() <= caches.maxTextureSize &&

libs/hwui/LayerRenderer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class LayerRenderer: public OpenGLRenderer {
6161
bool isOpaque, GLenum renderTarget, float* transform);
6262
ANDROID_API static void destroyLayer(Layer* layer);
6363
ANDROID_API static void destroyLayerDeferred(Layer* layer);
64+
ANDROID_API static void flushLayer(Layer* layer);
6465
ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
6566

6667
private:

0 commit comments

Comments
 (0)