mVisibleLayersSortedByZ is now maintained per display

Change-Id: Idcdb77eba1a3f99b3e4b2150128a82acaffcd2a8
diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp
index eb64c9f..fdde15a 100644
--- a/services/surfaceflinger/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware.cpp
@@ -97,7 +97,7 @@
         const sp<SurfaceFlinger>& flinger,
         uint32_t dpy)
     : DisplayHardwareBase(flinger, dpy),
-      mFlinger(flinger), mFlags(0), mHwc(0)
+      mFlinger(flinger), mFlags(0), mHwc(0), mSecureLayerVisible(false)
 {
     init(dpy);
 }
@@ -512,6 +512,26 @@
 
 // ----------------------------------------------------------------------------
 
+void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
+    mVisibleLayersSortedByZ = layers;
+    size_t count = layers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        if (layers[i]->isSecure()) {
+            mSecureLayerVisible = true;
+        }
+    }
+}
+
+Vector< sp<LayerBase> > DisplayHardware::getVisibleLayersSortedByZ() const {
+    return mVisibleLayersSortedByZ;
+}
+
+bool DisplayHardware::getSecureLayerVisible() const {
+    return mSecureLayerVisible;
+}
+
+// ----------------------------------------------------------------------------
+
 status_t DisplayHardware::orientationToTransfrom(
         int orientation, int w, int h, Transform* tr)
 {
diff --git a/services/surfaceflinger/DisplayHardware.h b/services/surfaceflinger/DisplayHardware.h
index 3da9f16..86500a6 100644
--- a/services/surfaceflinger/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware.h
@@ -85,6 +85,11 @@
     nsecs_t     getRefreshTimestamp() const;
     void        makeCurrent() const;
 
+
+    void                    setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers);
+    Vector< sp<LayerBase> > getVisibleLayersSortedByZ() const;
+    bool                    getSecureLayerVisible() const;
+
     status_t                setOrientation(int orientation);
     int                     getOrientation() const { return mOrientation; }
     const Transform&        getTransform() const { return mGlobalTransform; }
@@ -145,6 +150,13 @@
     HWComposer*     mHwc;
     PowerHAL        mPowerHAL;
 
+    // Can only accessed from the main thread, these members
+    // don't need synchronization
+    // list of visible layers on that display
+    Vector< sp<LayerBase> > mVisibleLayersSortedByZ;
+    // Whether we have a visible secure layer on this display
+    bool mSecureLayerVisible;
+
 
     // this used to be in GraphicPlane
     static status_t orientationToTransfrom(int orientation, int w, int h,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6c900be..46a711d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -98,7 +98,6 @@
         mDebugInTransaction(0),
         mLastTransactionTime(0),
         mBootFinished(false),
-        mSecureFrameBuffer(0),
         mExternalDisplaySurface(EGL_NO_SURFACE)
 {
     init();
@@ -465,6 +464,40 @@
 void SurfaceFlinger::handleMessageRefresh() {
     handleRefresh();
 
+    if (mVisibleRegionsDirty) {
+        Region opaqueRegion;
+        Region dirtyRegion;
+        const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
+        computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion);
+        mDirtyRegion.orSelf(dirtyRegion);
+
+        /*
+         *  rebuild the visible layer list per screen
+         */
+
+        // TODO: iterate through all displays
+        DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
+
+        Vector< sp<LayerBase> > layersSortedByZ;
+        const size_t count = currentLayers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            if (!currentLayers[i]->visibleRegion.isEmpty()) {
+                // TODO: also check that this layer is associated to this display
+                layersSortedByZ.add(currentLayers[i]);
+            }
+        }
+        hw.setVisibleLayersSortedByZ(layersSortedByZ);
+
+
+        // FIXME: mWormholeRegion needs to be calculated per screen
+        //const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here
+        mWormholeRegion = Region(hw.getBounds()).subtract(
+                hw.getTransform().transform(opaqueRegion) );
+        mVisibleRegionsDirty = false;
+        invalidateHwcGeometry();
+    }
+
+
     // XXX: dirtyRegion should be per screen, we should check all of them
     if (mDirtyRegion.isEmpty()) {
         return;
@@ -515,7 +548,8 @@
             glClear(GL_COLOR_BUFFER_BIT);
             glMatrixMode(GL_MODELVIEW);
             glLoadIdentity();
-            const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+
+            const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
             const size_t count = layers.size();
             for (size_t i=0 ; i<count ; ++i) {
                 const sp<LayerBase>& layer(layers[i]);
@@ -546,7 +580,8 @@
 
     const DisplayHardware& hw(getDefaultDisplayHardware());
     HWComposer& hwc(hw.getHwComposer());
-    size_t numLayers = mVisibleLayersSortedByZ.size();
+    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
+    size_t numLayers = layers.size();
     const nsecs_t now = systemTime();
     mDebugInSwapBuffers = now;
 
@@ -555,7 +590,7 @@
         const HWComposer::LayerListIterator end = hwc.end();
         for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
             if (cur->getCompositionType() == HWC_OVERLAY) {
-                mVisibleLayersSortedByZ[i]->setAcquireFence(*cur);
+                layers[i]->setAcquireFence(*cur);
             } else {
                 cur->setAcquireFenceFd(-1);
             }
@@ -568,11 +603,11 @@
         HWComposer::LayerListIterator cur = hwc.begin();
         const HWComposer::LayerListIterator end = hwc.end();
         for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
-            mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur);
+            layers[i]->onLayerDisplayed(&*cur);
         }
     } else {
         for (size_t i = 0; i < numLayers; i++) {
-            mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL);
+            layers[i]->onLayerDisplayed(NULL);
         }
     }
 
@@ -713,7 +748,7 @@
     Region aboveCoveredLayers;
     Region dirty;
 
-    bool secureFrameBuffer = false;
+    dirtyRegion.clear();
 
     size_t i = currentLayers.size();
     while (i--) {
@@ -823,14 +858,8 @@
         // Store the visible region is screen space
         layer->setVisibleRegion(visibleRegion);
         layer->setCoveredRegion(coveredRegion);
-
-        // If a secure layer is partially visible, lock-down the screen!
-        if (layer->isSecure() && !visibleRegion.isEmpty()) {
-            secureFrameBuffer = true;
-        }
     }
 
-    mSecureFrameBuffer = secureFrameBuffer;
     opaqueRegion = aboveOpaqueLayers;
 }
 
@@ -849,30 +878,7 @@
         dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) );
     }
 
-    if (visibleRegions || mVisibleRegionsDirty) {
-        Region opaqueRegion;
-        computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion);
-
-        /*
-         *  rebuild the visible layer list
-         */
-
-        // XXX: mVisibleLayersSortedByZ should be per-screen
-        const size_t count = currentLayers.size();
-        mVisibleLayersSortedByZ.clear();
-        mVisibleLayersSortedByZ.setCapacity(count);
-        for (size_t i=0 ; i<count ; i++) {
-            if (!currentLayers[i]->visibleRegion.isEmpty())
-                mVisibleLayersSortedByZ.add(currentLayers[i]);
-        }
-
-        // FIXME: mWormholeRegion needs to be calculated per screen
-        const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here
-        mWormholeRegion = Region(hw.getBounds()).subtract(
-                hw.getTransform().transform(opaqueRegion) );
-        mVisibleRegionsDirty = false;
-        invalidateHwcGeometry();
-    }
+    mVisibleRegionsDirty |= visibleRegions;
 
     return dirtyRegion;
 }
@@ -904,7 +910,7 @@
     mHwWorkListDirty = false;
     HWComposer& hwc(hw.getHwComposer());
     if (hwc.initCheck() == NO_ERROR) {
-        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
+        const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
         const size_t count = currentLayers.size();
         hwc.createWorkList(count);
 
@@ -971,7 +977,7 @@
         return;
     }
 
-    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
     size_t count = layers.size();
 
     ALOGE_IF(hwc.getNumLayers() != count,
@@ -1025,7 +1031,7 @@
          * and then, render the layers targeted at the framebuffer
          */
 
-        const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+        const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
         const size_t count = layers.size();
         const Transform& tr = hw.getTransform();
         for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
@@ -1741,7 +1747,7 @@
             hwc.initCheck()==NO_ERROR ? "present" : "not present",
                     (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled");
     result.append(buffer);
-    hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ);
+    hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ());
 
     /*
      * Dump gralloc state
@@ -1931,7 +1937,7 @@
     glClear(GL_COLOR_BUFFER_BIT);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
-    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+    const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
     const size_t count = layers.size();
     for (size_t i=0 ; i<count ; ++i) {
         const sp<LayerBase>& layer(layers[i]);
@@ -2428,19 +2434,27 @@
     status_t result = PERMISSION_DENIED;
 
     // only one display supported for now
-    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+    if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) {
         return BAD_VALUE;
+    }
 
-    if (!GLExtensions::getInstance().haveFramebufferObject())
+    if (!GLExtensions::getInstance().haveFramebufferObject()) {
         return INVALID_OPERATION;
+    }
 
     // get screen geometry
     const DisplayHardware& hw(getDisplayHardware(dpy));
     const uint32_t hw_w = hw.getWidth();
     const uint32_t hw_h = hw.getHeight();
 
-    if ((sw > hw_w) || (sh > hw_h))
+    // if we have secure windows on this display, never allow the screen capture
+    if (hw.getSecureLayerVisible()) {
+        return PERMISSION_DENIED;
+    }
+
+    if ((sw > hw_w) || (sh > hw_h)) {
         return BAD_VALUE;
+    }
 
     sw = (!sw) ? hw_w : sw;
     sh = (!sh) ? hw_h : sh;
@@ -2579,14 +2593,8 @@
         }
         virtual bool handler() {
             Mutex::Autolock _l(flinger->mStateLock);
-
-            // if we have secure windows, never allow the screen capture
-            if (flinger->mSecureFrameBuffer)
-                return true;
-
             result = flinger->captureScreenImplLocked(dpy,
                     heap, w, h, f, sw, sh, minLayerZ, maxLayerZ);
-
             return true;
         }
     };
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 91cc6a5..7642e3d 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -342,7 +342,6 @@
                 bool                        mVisibleRegionsDirty;
                 bool                        mHwWorkListDirty;
                 int32_t                     mElectronBeamAnimationMode;
-                Vector< sp<LayerBase> >     mVisibleLayersSortedByZ;
 
 
                 // don't use a lock for these, we don't care
@@ -364,9 +363,6 @@
     mutable     Mutex                       mDestroyedLayerLock;
                 Vector<LayerBase const *>   mDestroyedLayers;
 
-   // only written in the main thread, only read in other threads
-   volatile     int32_t                     mSecureFrameBuffer;
-
 
    EGLSurface getExternalDisplaySurface() const;
    sp<SurfaceTextureClient> mExternalDisplayNativeWindow;