Discard framebuffer rendering queues when discarding layers
Bug #5581817
Change-Id: Ie30700a29059d2ea60eb7bd3f8bd20ac48a149ab
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index aa0bfd2..43a451d 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -154,6 +154,7 @@
static native void nSetTextureLayerTransform(int layerId, int matrix);
static native void nDestroyLayer(int layerId);
static native void nDestroyLayerDeferred(int layerId);
+ static native void nFlushLayer(int layerId);
static native boolean nCopyLayer(int layerId, int bitmap);
///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index fd3b9e5..4f25792 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -60,6 +60,13 @@
}
mLayer = 0;
}
+
+ @Override
+ void flush() {
+ if (mLayer != 0) {
+ GLES20Canvas.nFlushLayer(mLayer);
+ }
+ }
static class Finalizer {
private int mLayerId;
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 28389ab..d5666f3 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -116,6 +116,11 @@
abstract void destroy();
/**
+ * Flush the render queue associated with this layer.
+ */
+ abstract void flush();
+
+ /**
* This must be invoked before drawing onto this layer.
* @param currentCanvas
*/
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 304a9a1..af8f8cb 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10207,6 +10207,13 @@
break;
}
}
+
+ // Make sure the HardwareRenderer.validate() was invoked before calling this method
+ void flushLayer() {
+ if (mLayerType == LAYER_TYPE_HARDWARE && mHardwareLayer != null) {
+ mHardwareLayer.flush();
+ }
+ }
/**
* <p>Returns a hardware layer that can be used to draw this view again
@@ -10219,6 +10226,8 @@
!mAttachInfo.mHardwareRenderer.isEnabled()) {
return null;
}
+
+ if (!mAttachInfo.mHardwareRenderer.validate()) return null;
final int width = mRight - mLeft;
final int height = mBottom - mTop;
@@ -10293,12 +10302,15 @@
*/
boolean destroyLayer() {
if (mHardwareLayer != null) {
- mHardwareLayer.destroy();
- mHardwareLayer = null;
+ AttachInfo info = mAttachInfo;
+ if (info != null && info.mHardwareRenderer != null &&
+ info.mHardwareRenderer.isEnabled() && info.mHardwareRenderer.validate()) {
+ mHardwareLayer.destroy();
+ mHardwareLayer = null;
- invalidate(true);
- invalidateParentCaches();
-
+ invalidate(true);
+ invalidateParentCaches();
+ }
return true;
}
return false;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 2a041f7..5035cae 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -2958,6 +2958,17 @@
mDrawLayers = enabled;
invalidate(true);
+ boolean flushLayers = !enabled;
+ AttachInfo info = mAttachInfo;
+ if (info != null && info.mHardwareRenderer != null &&
+ info.mHardwareRenderer.isEnabled()) {
+ if (!info.mHardwareRenderer.validate()) {
+ flushLayers = false;
+ }
+ } else {
+ flushLayers = false;
+ }
+
// We need to invalidate any child with a layer. For instance,
// if a child is backed by a hardware layer and we disable layers
// the child is marked as not dirty (flags cleared the last time
@@ -2968,6 +2979,7 @@
for (int i = 0; i < mChildrenCount; i++) {
View child = mChildren[i];
if (child.mLayerType != LAYER_TYPE_NONE) {
+ if (flushLayers) child.flushLayer();
child.invalidate(true);
}
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 426f4f7..9c7b108 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -719,6 +719,10 @@
LayerRenderer::destroyLayerDeferred(layer);
}
+static void android_view_GLES20Canvas_flushLayer(JNIEnv* env, jobject clazz, Layer* layer) {
+ LayerRenderer::flushLayer(layer);
+}
+
static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
renderer->drawLayer(layer, x, y, paint);
@@ -869,6 +873,7 @@
{ "nSetTextureLayerTransform", "(II)V", (void*) android_view_GLES20Canvas_setTextureLayerTransform },
{ "nDestroyLayer", "(I)V", (void*) android_view_GLES20Canvas_destroyLayer },
{ "nDestroyLayerDeferred", "(I)V", (void*) android_view_GLES20Canvas_destroyLayerDeferred },
+ { "nFlushLayer", "(I)V", (void*) android_view_GLES20Canvas_flushLayer },
{ "nDrawLayer", "(IIFFI)V", (void*) android_view_GLES20Canvas_drawLayer },
{ "nCopyLayer", "(II)Z", (void*) android_view_GLES20Canvas_copyLayer },