Update layers' opaque property when needed
Before this change, changing a View's opacity would not be reflected
by hardware layers. This could cause layers to retain their previous
opacity.
Change-Id: Iba2c8b4242deca021651df9324cc7c585a64653d
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 055aee3..fba56d0 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -151,6 +151,7 @@
static native int nCreateTextureLayer(boolean opaque, int[] layerInfo);
static native int nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
static native void nResizeLayer(int layerId, int width, int height, int[] layerInfo);
+ static native void nSetOpaqueLayer(int layerId, boolean isOpaque);
static native void nUpdateTextureLayer(int layerId, int width, int height, boolean opaque,
SurfaceTexture surface);
static native void nSetTextureLayerTransform(int layerId, int matrix);
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index 4f25792..a7d9267 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -46,11 +46,6 @@
boolean copyInto(Bitmap bitmap) {
return GLES20Canvas.nCopyLayer(mLayer, bitmap.mNativeBitmap);
}
-
- @Override
- void update(int width, int height, boolean isOpaque) {
- super.update(width, height, isOpaque);
- }
@Override
void destroy() {
diff --git a/core/java/android/view/GLES20RenderLayer.java b/core/java/android/view/GLES20RenderLayer.java
index c727a36..a77425a 100644
--- a/core/java/android/view/GLES20RenderLayer.java
+++ b/core/java/android/view/GLES20RenderLayer.java
@@ -71,6 +71,12 @@
}
@Override
+ void setOpaque(boolean isOpaque) {
+ mOpaque = isOpaque;
+ GLES20Canvas.nSetOpaqueLayer(mLayer, isOpaque);
+ }
+
+ @Override
HardwareCanvas getCanvas() {
return mCanvas;
}
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
index 16a13cf..e198ef6 100644
--- a/core/java/android/view/GLES20TextureLayer.java
+++ b/core/java/android/view/GLES20TextureLayer.java
@@ -42,12 +42,6 @@
}
}
- GLES20TextureLayer(SurfaceTexture surface, boolean isOpaque) {
- this(isOpaque);
- mSurface = surface;
- mSurface.attachToGLContext(mTexture);
- }
-
@Override
boolean isValid() {
return mLayer != 0 && mTexture != 0;
@@ -93,6 +87,11 @@
}
@Override
+ void setOpaque(boolean isOpaque) {
+ throw new UnsupportedOperationException("Use update(int, int, boolean) instead");
+ }
+
+ @Override
void setTransform(Matrix matrix) {
GLES20Canvas.nSetTextureLayerTransform(mLayer, matrix.native_instance);
}
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index e73f7bf..67c7a19 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -107,6 +107,13 @@
}
/**
+ * Sets whether or not this layer should be considered opaque.
+ *
+ * @param isOpaque True if the layer is opaque, false otherwise
+ */
+ abstract void setOpaque(boolean isOpaque);
+
+ /**
* Indicates whether this layer can be rendered.
*
* @return True if the layer can be rendered into, false otherwise
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c269ea3..22b307c 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -11928,9 +11928,24 @@
mHardwareLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
width, height, isOpaque());
mLocalDirtyRect.set(0, 0, width, height);
- } else if (mHardwareLayer.getWidth() != width || mHardwareLayer.getHeight() != height) {
- mHardwareLayer.resize(width, height);
- mLocalDirtyRect.set(0, 0, width, height);
+ } else {
+ if (mHardwareLayer.getWidth() != width || mHardwareLayer.getHeight() != height) {
+ mHardwareLayer.resize(width, height);
+ mLocalDirtyRect.set(0, 0, width, height);
+ }
+
+ // This should not be necessary but applications that change
+ // the parameters of their background drawable without calling
+ // this.setBackground(Drawable) can leave the view in a bad state
+ // (for instance isOpaque() returns true, but the background is
+ // not opaque.)
+ computeOpaqueFlags();
+
+ final boolean opaque = isOpaque();
+ if (mHardwareLayer.isOpaque() != opaque) {
+ mHardwareLayer.setOpaque(opaque);
+ mLocalDirtyRect.set(0, 0, width, height);
+ }
}
// The layer is not valid if the underlying GPU resources cannot be allocated
@@ -13989,6 +14004,8 @@
*/
@Deprecated
public void setBackgroundDrawable(Drawable background) {
+ computeOpaqueFlags();
+
if (background == mBackground) {
return;
}
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a51b77e..3a05103 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -769,6 +769,13 @@
env->ReleaseIntArrayElements(layerInfo, storage, 0);
}
+static void android_view_GLES20Canvas_setOpaqueLayer(JNIEnv* env, jobject clazz,
+ Layer* layer, jboolean isOpaque) {
+ if (layer) {
+ layer->setBlend(!isOpaque);
+ }
+}
+
static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject clazz,
Layer* layer, jint width, jint height, jboolean isOpaque, jobject surface) {
float transform[16];
@@ -969,6 +976,7 @@
{ "nCreateLayerRenderer", "(I)I", (void*) android_view_GLES20Canvas_createLayerRenderer },
{ "nCreateLayer", "(IIZ[I)I", (void*) android_view_GLES20Canvas_createLayer },
{ "nResizeLayer", "(III[I)V" , (void*) android_view_GLES20Canvas_resizeLayer },
+ { "nSetOpaqueLayer", "(IZ)V", (void*) android_view_GLES20Canvas_setOpaqueLayer },
{ "nCreateTextureLayer", "(Z[I)I", (void*) android_view_GLES20Canvas_createTextureLayer },
{ "nUpdateTextureLayer", "(IIIZLandroid/graphics/SurfaceTexture;)V",
(void*) android_view_GLES20Canvas_updateTextureLayer },