mVisibleLayersSortedByZ is now maintained per display
Change-Id: Idcdb77eba1a3f99b3e4b2150128a82acaffcd2a8
This commit is contained in:
parent
df5cbd7622
commit
3b1d2b6b2b
@ -97,7 +97,7 @@ DisplayHardware::DisplayHardware(
|
||||
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::dump(String8& res) const
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -85,6 +85,11 @@ public:
|
||||
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 @@ 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<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,
|
||||
|
@ -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<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 @@ void SurfaceFlinger::handleMessageRefresh() {
|
||||
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 @@ void SurfaceFlinger::postFramebuffer()
|
||||
|
||||
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 @@ 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 ; 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 @@ void SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
|
||||
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 @@ void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
|
||||
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 @@ void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& di
|
||||
* 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 @@ void SurfaceFlinger::dumpAllLocked(
|
||||
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 @@ status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
|
||||
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 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;
|
||||
}
|
||||
};
|
||||
|
@ -342,7 +342,6 @@ private:
|
||||
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 @@ private:
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user