frameworks/native: Add support for transparent layers

Add support for marking layers transparent, which SurfaceFlinger
can drop from composition. This is meant to be set by apps, in
situations where the window above a surfaceview is fully transparent.

Change-Id: Ide979d47489a6fc4c6f47f6dd026853d83d484c0
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 2fa6ff9..6ce4cdb 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -39,6 +39,7 @@
     enum {
         eLayerHidden        = 0x01,     // SURFACE_HIDDEN in SurfaceControl.java
         eLayerOpaque        = 0x02,     // SURFACE_OPAQUE
+        eLayerTransparent   = 0x80,     // SURFACE_TRANSPARENT
     };
 
     enum {
@@ -52,6 +53,7 @@
         eLayerStackChanged          = 0x00000080,
         eCropChanged                = 0x00000100,
         eOpacityChanged             = 0x00000200,
+        eTransparencyChanged        = 0x80000000,
     };
 
     layer_state_t()
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6446926..9e0704a 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -316,6 +316,9 @@
     if (mask & layer_state_t::eLayerHidden) {
         s->what |= layer_state_t::eVisibilityChanged;
     }
+    if (mask & layer_state_t::eLayerTransparent) {
+        s->what |= layer_state_t::eTransparencyChanged;
+    }
     s->flags &= ~mask;
     s->flags |= (flags & mask);
     s->mask |= mask;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2598d24..65f9baf 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1199,7 +1199,8 @@
 
 bool Layer::isVisible() const {
     const Layer::State& s(mDrawingState);
-    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
+    return !(s.flags & layer_state_t::eLayerHidden) &&
+            !(s.flags & layer_state_t::eLayerTransparent) && s.alpha
             && (mActiveBuffer != NULL || mSidebandStream != NULL);
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 41b8435..bb19e6a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2535,7 +2535,8 @@
                 flags |= eTraversalNeeded;
         }
         if ((what & layer_state_t::eVisibilityChanged) ||
-                (what & layer_state_t::eOpacityChanged)) {
+                (what & layer_state_t::eOpacityChanged) ||
+                (what & layer_state_t::eTransparencyChanged)) {
             // TODO: should we just use an eFlagsChanged for this?
             if (layer->setFlags(s.flags, s.mask))
                 flags |= eTraversalNeeded;