diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp index eb64c9f8f..fdde15aa8 100644 --- a/services/surfaceflinger/DisplayHardware.cpp +++ b/services/surfaceflinger/DisplayHardware.cpp @@ -97,7 +97,7 @@ DisplayHardware::DisplayHardware( const sp& 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::dump(String8& res) const // ---------------------------------------------------------------------------- +void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp >& layers) { + mVisibleLayersSortedByZ = layers; + size_t count = layers.size(); + for (size_t i=0 ; iisSecure()) { + mSecureLayerVisible = true; + } + } +} + +Vector< sp > 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 3da9f163b..86500a68b 100644 --- a/services/surfaceflinger/DisplayHardware.h +++ b/services/surfaceflinger/DisplayHardware.h @@ -85,6 +85,11 @@ public: nsecs_t getRefreshTimestamp() const; void makeCurrent() const; + + void setVisibleLayersSortedByZ(const Vector< sp >& layers); + Vector< sp > 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 @@ private: 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 > 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 6c900be99..46a711d6b 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -98,7 +98,6 @@ SurfaceFlinger::SurfaceFlinger() mDebugInTransaction(0), mLastTransactionTime(0), mBootFinished(false), - mSecureFrameBuffer(0), mExternalDisplaySurface(EGL_NO_SURFACE) { init(); @@ -465,6 +464,40 @@ void SurfaceFlinger::handleMessageInvalidate() { 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(getDisplayHardware(0))); + + Vector< sp > layersSortedByZ; + const size_t count = currentLayers.size(); + for (size_t i=0 ; ivisibleRegion.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 @@ void SurfaceFlinger::handleMessageRefresh() { glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - const Vector< sp >& layers(mVisibleLayersSortedByZ); + + const Vector< sp >& layers( hw.getVisibleLayersSortedByZ() ); const size_t count = layers.size(); for (size_t i=0 ; i& layer(layers[i]); @@ -546,7 +580,8 @@ void SurfaceFlinger::postFramebuffer() const DisplayHardware& hw(getDefaultDisplayHardware()); HWComposer& hwc(hw.getHwComposer()); - size_t numLayers = mVisibleLayersSortedByZ.size(); + const Vector< sp >& layers(hw.getVisibleLayersSortedByZ()); + size_t numLayers = layers.size(); const nsecs_t now = systemTime(); mDebugInSwapBuffers = now; @@ -555,7 +590,7 @@ void SurfaceFlinger::postFramebuffer() 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 @@ void SurfaceFlinger::postFramebuffer() 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 @@ void SurfaceFlinger::computeVisibleRegions( Region aboveCoveredLayers; Region dirty; - bool secureFrameBuffer = false; + dirtyRegion.clear(); size_t i = currentLayers.size(); while (i--) { @@ -823,14 +858,8 @@ void SurfaceFlinger::computeVisibleRegions( // 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 @@ Region SurfaceFlinger::handlePageFlip() 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 ; ivisibleRegion.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 @@ void SurfaceFlinger::handleWorkList(const DisplayHardware& hw) mHwWorkListDirty = false; HWComposer& hwc(hw.getHwComposer()); if (hwc.initCheck() == NO_ERROR) { - const Vector< sp >& currentLayers(mVisibleLayersSortedByZ); + const Vector< sp >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); hwc.createWorkList(count); @@ -971,7 +977,7 @@ void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) return; } - const Vector< sp >& layers(mVisibleLayersSortedByZ); + const Vector< sp >& layers(hw.getVisibleLayersSortedByZ()); size_t count = layers.size(); ALOGE_IF(hwc.getNumLayers() != count, @@ -1025,7 +1031,7 @@ void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& di * and then, render the layers targeted at the framebuffer */ - const Vector< sp >& layers(mVisibleLayersSortedByZ); + const Vector< sp >& layers(hw.getVisibleLayersSortedByZ()); const size_t count = layers.size(); const Transform& tr = hw.getTransform(); for (size_t i=0 ; cur!=end && i >& layers(mVisibleLayersSortedByZ); + const Vector< sp >& layers(hw.getVisibleLayersSortedByZ()); const size_t count = layers.size(); for (size_t i=0 ; i& layer(layers[i]); @@ -2428,19 +2434,27 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 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 @@ status_t SurfaceFlinger::captureScreen(DisplayID dpy, } 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 91cc6a5eb..7642e3dd5 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -342,7 +342,6 @@ private: bool mVisibleRegionsDirty; bool mHwWorkListDirty; int32_t mElectronBeamAnimationMode; - Vector< sp > mVisibleLayersSortedByZ; // don't use a lock for these, we don't care @@ -364,9 +363,6 @@ private: mutable Mutex mDestroyedLayerLock; Vector mDestroyedLayers; - // only written in the main thread, only read in other threads - volatile int32_t mSecureFrameBuffer; - EGLSurface getExternalDisplaySurface() const; sp mExternalDisplayNativeWindow;