diff options
author | Mathias Agopian <mathias@google.com> | 2013-03-07 01:47:34 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-03-07 01:47:34 +0000 |
commit | 438ca07b6ba74235e87bfbd78c94874d8bbde391 (patch) | |
tree | 40fdc15cc3c3547cc39292313aff03ef22c708b0 | |
parent | 175264b09c6080b29a23fc9f545d4b99445714bd (diff) | |
parent | 13127d8921356dff794250e04208c3ed60b3a3df (diff) | |
download | frameworks_native-438ca07b6ba74235e87bfbd78c94874d8bbde391.zip frameworks_native-438ca07b6ba74235e87bfbd78c94874d8bbde391.tar.gz frameworks_native-438ca07b6ba74235e87bfbd78c94874d8bbde391.tar.bz2 |
Merge changes I66511c08,Ia051949f,Ic7451365,I5b571a4c into jb-mr2-dev
* changes:
Get rid of LayerBase.
Make LayerDim a regular Layer instead of a LayerBase
fold LayerBaseClient into LayerBase
Remove support for ScreenshotLayer
-rw-r--r-- | include/gui/ISurfaceComposerClient.h | 2 | ||||
-rw-r--r-- | services/surfaceflinger/Android.mk | 2 | ||||
-rw-r--r-- | services/surfaceflinger/Client.cpp | 13 | ||||
-rw-r--r-- | services/surfaceflinger/Client.h | 10 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 8 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 15 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 683 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 311 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.cpp | 660 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.h | 401 | ||||
-rw-r--r-- | services/surfaceflinger/LayerDim.cpp | 25 | ||||
-rw-r--r-- | services/surfaceflinger/LayerDim.h | 8 | ||||
-rw-r--r-- | services/surfaceflinger/LayerScreenshot.cpp | 47 | ||||
-rw-r--r-- | services/surfaceflinger/LayerScreenshot.h | 41 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 126 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 29 |
18 files changed, 976 insertions, 1414 deletions
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h index 23d1d4c..4afc860 100644 --- a/include/gui/ISurfaceComposerClient.h +++ b/include/gui/ISurfaceComposerClient.h @@ -48,9 +48,7 @@ public: eProtectedByDRM = 0x00001000, eFXSurfaceNormal = 0x00000000, - eFXSurfaceBlur = 0x00010000, // deprecated, same as Dim eFXSurfaceDim = 0x00020000, - eFXSurfaceScreenshot= 0x00030000, eFXSurfaceMask = 0x000F0000, }; diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index b4b19b4..5ff8154 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -7,9 +7,7 @@ LOCAL_SRC_FILES:= \ EventThread.cpp \ FrameTracker.cpp \ Layer.cpp \ - LayerBase.cpp \ LayerDim.cpp \ - LayerScreenshot.cpp \ DisplayHardware/FramebufferSurface.cpp \ DisplayHardware/HWComposer.cpp \ DisplayHardware/PowerHAL.cpp \ diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 0f56f99..0575e35 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -23,7 +23,6 @@ #include "Client.h" #include "Layer.h" -#include "LayerBase.h" #include "SurfaceFlinger.h" namespace android { @@ -43,7 +42,7 @@ Client::~Client() { const size_t count = mLayers.size(); for (size_t i=0 ; i<count ; i++) { - sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); + sp<Layer> layer(mLayers.valueAt(i).promote()); if (layer != 0) { mFlinger->removeLayer(layer); } @@ -54,13 +53,13 @@ status_t Client::initCheck() const { return NO_ERROR; } -void Client::attachLayer(const sp<IBinder>& handle, const sp<LayerBaseClient>& layer) +void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer) { Mutex::Autolock _l(mLock); mLayers.add(handle, layer); } -void Client::detachLayer(const LayerBaseClient* layer) +void Client::detachLayer(const Layer* layer) { Mutex::Autolock _l(mLock); // we do a linear search here, because this doesn't happen often @@ -72,11 +71,11 @@ void Client::detachLayer(const LayerBaseClient* layer) } } } -sp<LayerBaseClient> Client::getLayerUser(const sp<IBinder>& handle) const +sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const { Mutex::Autolock _l(mLock); - sp<LayerBaseClient> lbc; - wp<LayerBaseClient> layer(mLayers.valueFor(handle)); + sp<Layer> lbc; + wp<Layer> layer(mLayers.valueFor(handle)); if (layer != 0) { lbc = layer.promote(); ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get()); diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index e6a7165..4f34b86 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -30,7 +30,7 @@ namespace android { // --------------------------------------------------------------------------- -class LayerBaseClient; +class Layer; class SurfaceFlinger; // --------------------------------------------------------------------------- @@ -44,11 +44,11 @@ public: status_t initCheck() const; // protected by SurfaceFlinger::mStateLock - void attachLayer(const sp<IBinder>& handle, const sp<LayerBaseClient>& layer); + void attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer); - void detachLayer(const LayerBaseClient* layer); + void detachLayer(const Layer* layer); - sp<LayerBaseClient> getLayerUser(const sp<IBinder>& handle) const; + sp<Layer> getLayerUser(const sp<IBinder>& handle) const; private: // ISurfaceComposerClient interface @@ -66,7 +66,7 @@ private: sp<SurfaceFlinger> mFlinger; // protected by mLock - DefaultKeyedVector< wp<IBinder>, wp<LayerBaseClient> > mLayers; + DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers; // thread-safe mutable Mutex mLock; diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index ed2768c..2bbe49c 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -42,7 +42,7 @@ #include "DisplayDevice.h" #include "GLExtensions.h" #include "SurfaceFlinger.h" -#include "LayerBase.h" +#include "Layer.h" // ---------------------------------------------------------------------------- using namespace android; @@ -282,19 +282,19 @@ void DisplayDevice::setViewportAndProjection(const sp<const DisplayDevice>& hw) // ---------------------------------------------------------------------------- -void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { +void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { mVisibleLayersSortedByZ = layers; mSecureLayerVisible = false; size_t count = layers.size(); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(layers[i]); + const sp<Layer>& layer(layers[i]); if (layer->isSecure()) { mSecureLayerVisible = true; } } } -const Vector< sp<LayerBase> >& DisplayDevice::getVisibleLayersSortedByZ() const { +const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { return mVisibleLayersSortedByZ; } diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h index 91f34db..f671017 100644 --- a/services/surfaceflinger/DisplayDevice.h +++ b/services/surfaceflinger/DisplayDevice.h @@ -38,7 +38,7 @@ namespace android { class DisplayInfo; class FramebufferSurface; -class LayerBase; +class Layer; class SurfaceFlinger; class HWComposer; @@ -99,8 +99,8 @@ public: EGLSurface getEGLSurface() const; - void setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers); - const Vector< sp<LayerBase> >& getVisibleLayersSortedByZ() const; + void setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers); + const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const; bool getSecureLayerVisible() const; Region getDirtyRegion(bool repaintEverything) const; @@ -186,7 +186,7 @@ private: */ // list of visible layers on that display - Vector< sp<LayerBase> > mVisibleLayersSortedByZ; + Vector< sp<Layer> > mVisibleLayersSortedByZ; // Whether we have a visible secure layer on this display bool mSecureLayerVisible; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 11f65f6..bb567e2 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -41,7 +41,6 @@ #include <cutils/properties.h> #include "Layer.h" // needed only for debugging -#include "LayerBase.h" #include "HWComposer.h" #include "SurfaceFlinger.h" #include <utils/CallStack.h> @@ -925,7 +924,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const { for (size_t i=0 ; i<mNumDisplays ; i++) { const DisplayData& disp(mDisplayData[i]); - const Vector< sp<LayerBase> >& visibleLayersSortedByZ = + const Vector< sp<Layer> >& visibleLayersSortedByZ = mFlinger->getLayerSortedByZForHwcDisplay(i); if (disp.connected) { @@ -949,13 +948,11 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const { String8 name("unknown"); if (i < visibleLayersSortedByZ.size()) { - const sp<LayerBase>& layer(visibleLayersSortedByZ[i]); - if (layer->getLayer() != NULL) { - const sp<GraphicBuffer>& buffer( - layer->getLayer()->getActiveBuffer()); - if (buffer != NULL) { - format = buffer->getPixelFormat(); - } + const sp<Layer>& layer(visibleLayersSortedByZ[i]); + const sp<GraphicBuffer>& buffer( + layer->getActiveBuffer()); + if (buffer != NULL) { + format = buffer->getPixelFormat(); } name = layer->getName(); } diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index f7ed1aa..9816a45 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -47,7 +47,6 @@ namespace android { class GraphicBuffer; class Fence; -class LayerBase; class Region; class String8; class SurfaceFlinger; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index c9f1eb5..44ef0b8 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -19,6 +19,7 @@ #include <stdlib.h> #include <stdint.h> #include <sys/types.h> +#include <math.h> #include <cutils/compiler.h> #include <cutils/native_handle.h> @@ -49,37 +50,39 @@ namespace android { // --------------------------------------------------------------------------- +int32_t Layer::sSequence = 1; + Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client) - : LayerBaseClient(flinger, client), + : contentDirty(false), + sequence(uint32_t(android_atomic_inc(&sSequence))), + mFlinger(flinger), mTextureName(-1U), + mPremultipliedAlpha(true), + mName("unnamed"), + mDebug(false), + mFormat(PIXEL_FORMAT_NONE), + mGLExtensions(GLExtensions::getInstance()), + mOpaqueLayer(true), + mTransactionFlags(0), mQueuedFrames(0), mCurrentTransform(0), mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), mCurrentOpacity(true), mRefreshPending(false), mFrameLatencyNeeded(false), - mFormat(PIXEL_FORMAT_NONE), - mGLExtensions(GLExtensions::getInstance()), - mOpaqueLayer(true), + mFiltering(false), + mNeedsFiltering(false), mSecure(false), - mProtectedByApp(false) + mProtectedByApp(false), + mHasSurface(false), + mClientRef(client) { mCurrentCrop.makeInvalid(); glGenTextures(1, &mTextureName); } -void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface* layer) { - LayerBaseClient::onLayerDisplayed(hw, layer); - if (layer) { - mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd()); - } -} - void Layer::onFirstRef() { - LayerBaseClient::onFirstRef(); - // Creates a custom BufferQueue for SurfaceFlingerConsumer to use sp<BufferQueue> bq = new SurfaceTextureLayer(); mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true, @@ -102,9 +105,25 @@ void Layer::onFirstRef() Layer::~Layer() { + sp<Client> c(mClientRef.promote()); + if (c != 0) { + c->detachLayer(this); + } mFlinger->deleteTextureAsync(mTextureName); } +// --------------------------------------------------------------------------- +// callbacks +// --------------------------------------------------------------------------- + +void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw, + HWComposer::HWCLayerInterface* layer) { + if (layer) { + layer->onDisplayed(); + mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd()); + } +} + void Layer::onFrameAvailable() { android_atomic_inc(&mQueuedFrames); mFlinger->signalLayerUpdate(); @@ -112,18 +131,83 @@ void Layer::onFrameAvailable() { // called with SurfaceFlinger::mStateLock as soon as the layer is entered // in the purgatory list -void Layer::onRemoved() -{ +void Layer::onRemoved() { mSurfaceFlingerConsumer->abandon(); } +// --------------------------------------------------------------------------- +// set-up +// --------------------------------------------------------------------------- + void Layer::setName(const String8& name) { - LayerBase::setName(name); + mName = name; mSurfaceFlingerConsumer->setName(name); } -sp<ISurface> Layer::createSurface() +String8 Layer::getName() const { + return mName; +} + +void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags) +{ + uint32_t layerFlags = 0; + if (flags & ISurfaceComposerClient::eHidden) + layerFlags = layer_state_t::eLayerHidden; + + if (flags & ISurfaceComposerClient::eNonPremultiplied) + mPremultipliedAlpha = false; + + mCurrentState.active.w = w; + mCurrentState.active.h = h; + mCurrentState.active.crop.makeInvalid(); + mCurrentState.z = 0; + mCurrentState.alpha = 0xFF; + mCurrentState.layerStack = 0; + mCurrentState.flags = layerFlags; + mCurrentState.sequence = 0; + mCurrentState.transform.set(0, 0); + mCurrentState.requested = mCurrentState.active; + + // drawing state & current state are identical + mDrawingState = mCurrentState; +} + +status_t Layer::setBuffers( uint32_t w, uint32_t h, + PixelFormat format, uint32_t flags) { + // this surfaces pixel format + PixelFormatInfo info; + status_t err = getPixelFormatInfo(format, &info); + if (err) { + ALOGE("unsupported pixelformat %d", format); + return err; + } + + uint32_t const maxSurfaceDims = min( + mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); + + // never allow a surface larger than what our underlying GL implementation + // can handle. + if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { + ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); + return BAD_VALUE; + } + + mFormat = format; + + mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; + mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; + mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); + mCurrentOpacity = getOpacityForFormat(format); + + mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); + mSurfaceFlingerConsumer->setDefaultBufferFormat(format); + mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); + + return NO_ERROR; +} + +sp<ISurface> Layer::createSurface() { /* * This class provides an implementation of BnSurface (the "native" or * "remote" side of the Binder IPC interface ISurface), and mixes in @@ -159,46 +243,27 @@ sp<ISurface> Layer::createSurface() return sur; } -wp<IBinder> Layer::getSurfaceTextureBinder() const -{ +wp<IBinder> Layer::getSurfaceTextureBinder() const { return mSurfaceFlingerConsumer->getBufferQueue()->asBinder(); } -status_t Layer::setBuffers( uint32_t w, uint32_t h, - PixelFormat format, uint32_t flags) +sp<ISurface> Layer::getSurface() { - // this surfaces pixel format - PixelFormatInfo info; - status_t err = getPixelFormatInfo(format, &info); - if (err) { - ALOGE("unsupported pixelformat %d", format); - return err; - } + sp<ISurface> s; + Mutex::Autolock _l(mLock); - uint32_t const maxSurfaceDims = min( - mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); + LOG_ALWAYS_FATAL_IF(mHasSurface, + "Layer::getSurface() has already been called"); - // never allow a surface larger than what our underlying GL implementation - // can handle. - if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { - ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); - return BAD_VALUE; - } - - mFormat = format; - - mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; - mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; - mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); - mCurrentOpacity = getOpacityForFormat(format); - - mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); - mSurfaceFlingerConsumer->setDefaultBufferFormat(format); - mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); - - return NO_ERROR; + mHasSurface = true; + s = createSurface(); + return s; } +// --------------------------------------------------------------------------- +// h/w composer set-up +// --------------------------------------------------------------------------- + Rect Layer::getContentCrop() const { // this is the crop rectangle that applies to the buffer // itself (as opposed to the window) @@ -220,11 +285,85 @@ uint32_t Layer::getContentTransform() const { return mCurrentTransform; } +Rect Layer::computeBounds() const { + const Layer::State& s(drawingState()); + Rect win(s.active.w, s.active.h); + if (!s.active.crop.isEmpty()) { + win.intersect(s.active.crop, &win); + } + return win; +} + +Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const { + /* + * The way we compute the crop (aka. texture coordinates when we have a + * Layer) produces a different output from the GL code in + * drawWithOpenGL() due to HWC being limited to integers. The difference + * can be large if getContentTransform() contains a large scale factor. + * See comments in drawWithOpenGL() for more details. + */ + + // the content crop is the area of the content that gets scaled to the + // layer's size. + Rect crop(getContentCrop()); + + // the active.crop is the area of the window that gets cropped, but not + // scaled in any ways. + const State& s(drawingState()); + + // apply the projection's clipping to the window crop in + // layerstack space, and convert-back to layer space. + // if there are no window scaling (or content scaling) involved, + // this operation will map to full pixels in the buffer. + // NOTE: should we revert to GL composition if a scaling is involved + // since it cannot be represented in the HWC API? + Rect activeCrop(s.transform.transform(s.active.crop)); + activeCrop.intersect(hw->getViewport(), &activeCrop); + activeCrop = s.transform.inverse().transform(activeCrop); + + // paranoia: make sure the window-crop is constrained in the + // window's bounds + activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); + + if (!activeCrop.isEmpty()) { + // Transform the window crop to match the buffer coordinate system, + // which means using the inverse of the current transform set on the + // SurfaceFlingerConsumer. + uint32_t invTransform = getContentTransform(); + int winWidth = s.active.w; + int winHeight = s.active.h; + if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { + invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | + NATIVE_WINDOW_TRANSFORM_FLIP_H; + winWidth = s.active.h; + winHeight = s.active.w; + } + const Rect winCrop = activeCrop.transform( + invTransform, s.active.w, s.active.h); + + // the code below essentially performs a scaled intersection + // of crop and winCrop + float xScale = float(crop.width()) / float(winWidth); + float yScale = float(crop.height()) / float(winHeight); + + int insetL = int(ceilf( winCrop.left * xScale)); + int insetT = int(ceilf( winCrop.top * yScale)); + int insetR = int(ceilf((winWidth - winCrop.right ) * xScale)); + int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale)); + + crop.left += insetL; + crop.top += insetT; + crop.right -= insetR; + crop.bottom -= insetB; + } + return crop; +} + void Layer::setGeometry( const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer) { - LayerBaseClient::setGeometry(hw, layer); + layer.setDefaultState(); // enable this layer layer.setSkip(false); @@ -233,7 +372,21 @@ void Layer::setGeometry( layer.setSkip(true); } + // this gives us only the "orientation" component of the transform const State& s(drawingState()); + if (!isOpaque() || s.alpha != 0xFF) { + layer.setBlending(mPremultipliedAlpha ? + HWC_BLENDING_PREMULT : + HWC_BLENDING_COVERAGE); + } + + // apply the layer's transform, followed by the display's global transform + // here we're guaranteed that the layer's transform preserves rects + Rect frame(s.transform.transform(computeBounds())); + frame.intersect(hw->getViewport(), &frame); + const Transform& tr(hw->getTransform()); + layer.setFrame(tr.transform(frame)); + layer.setCrop(computeCrop(hw)); layer.setPlaneAlpha(s.alpha); /* @@ -245,22 +398,29 @@ void Layer::setGeometry( */ const Transform bufferOrientation(mCurrentTransform); - const Transform tr(hw->getTransform() * s.transform * bufferOrientation); + const Transform transform(tr * s.transform * bufferOrientation); // this gives us only the "orientation" component of the transform - const uint32_t finalTransform = tr.getOrientation(); - - // we can only handle simple transformation - if (finalTransform & Transform::ROT_INVALID) { + const uint32_t orientation = transform.getOrientation(); + if (orientation & Transform::ROT_INVALID) { + // we can only handle simple transformation layer.setSkip(true); } else { - layer.setTransform(finalTransform); + layer.setTransform(orientation); } } void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer) { - LayerBaseClient::setPerFrameData(hw, layer); + // we have to set the visible region on every frame because + // we currently free it during onLayerDisplayed(), which is called + // after HWComposer::commit() -- every frame. + // Apply this display's projection's viewport to the visible region + // before giving it to the HWC HAL. + const Transform& tr = hw->getTransform(); + Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); + layer.setVisibleRegionScreen(visible); + // NOTE: buffer can be NULL if the client never drew into this // layer yet, or if we ran out of memory layer.setBuffer(mActiveBuffer); @@ -285,6 +445,18 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& hw, layer.setAcquireFenceFd(fenceFd); } +// --------------------------------------------------------------------------- +// drawing... +// --------------------------------------------------------------------------- + +void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const { + onDraw(hw, clip); +} + +void Layer::draw(const sp<const DisplayDevice>& hw) { + onDraw( hw, Region(hw->bounds()) ); +} + void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const { ATRACE_CALL(); @@ -304,8 +476,8 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const mFlinger->mDrawingState.layersSortedByZ); const size_t count = drawingLayers.size(); for (size_t i=0 ; i<count ; ++i) { - const sp<LayerBase>& layer(drawingLayers[i]); - if (layer.get() == static_cast<LayerBase const*>(this)) + const sp<Layer>& layer(drawingLayers[i]); + if (layer.get() == static_cast<Layer const*>(this)) break; under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); } @@ -365,6 +537,119 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const glDisable(GL_TEXTURE_2D); } + +void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip, + GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const +{ + const uint32_t fbHeight = hw->getHeight(); + glColor4f(red,green,blue,alpha); + + glDisable(GL_TEXTURE_EXTERNAL_OES); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + + LayerMesh mesh; + computeGeometry(hw, &mesh); + + glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices()); + glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount()); +} + +void Layer::clearWithOpenGL( + const sp<const DisplayDevice>& hw, const Region& clip) const { + clearWithOpenGL(hw, clip, 0,0,0,0); +} + +void Layer::drawWithOpenGL( + const sp<const DisplayDevice>& hw, const Region& clip) const { + const uint32_t fbHeight = hw->getHeight(); + const State& s(drawingState()); + + GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; + if (CC_UNLIKELY(s.alpha < 0xFF)) { + const GLfloat alpha = s.alpha * (1.0f/255.0f); + if (mPremultipliedAlpha) { + glColor4f(alpha, alpha, alpha, alpha); + } else { + glColor4f(1, 1, 1, alpha); + } + glEnable(GL_BLEND); + glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } else { + glColor4f(1, 1, 1, 1); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + if (!isOpaque()) { + glEnable(GL_BLEND); + glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); + } else { + glDisable(GL_BLEND); + } + } + + LayerMesh mesh; + computeGeometry(hw, &mesh); + + // TODO: we probably want to generate the texture coords with the mesh + // here we assume that we only have 4 vertices + + struct TexCoords { + GLfloat u; + GLfloat v; + }; + + + /* + * NOTE: the way we compute the texture coordinates here produces + * different results than when we take the HWC path -- in the later case + * the "source crop" is rounded to texel boundaries. + * This can produce significantly different results when the texture + * is scaled by a large amount. + * + * The GL code below is more logical (imho), and the difference with + * HWC is due to a limitation of the HWC API to integers -- a question + * is suspend is wether we should ignore this problem or revert to + * GL composition when a buffer scaling is applied (maybe with some + * minimal value)? Or, we could make GL behave like HWC -- but this feel + * like more of a hack. + */ + const Rect win(computeBounds()); + + GLfloat left = GLfloat(win.left) / GLfloat(s.active.w); + GLfloat top = GLfloat(win.top) / GLfloat(s.active.h); + GLfloat right = GLfloat(win.right) / GLfloat(s.active.w); + GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h); + + TexCoords texCoords[4]; + texCoords[0].u = left; + texCoords[0].v = top; + texCoords[1].u = left; + texCoords[1].v = bottom; + texCoords[2].u = right; + texCoords[2].v = bottom; + texCoords[3].u = right; + texCoords[3].v = top; + for (int i = 0; i < 4; i++) { + texCoords[i].v = 1.0f - texCoords[i].v; + } + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices()); + glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount()); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_BLEND); +} + +void Layer::setFiltering(bool filtering) { + mFiltering = filtering; +} + +bool Layer::getFiltering() const { + return mFiltering; +} + // As documented in libhardware header, formats in the range // 0x100 - 0x1FF are specific to the HAL implementation, and // are known to have no alpha channel @@ -383,6 +668,29 @@ bool Layer::getOpacityForFormat(uint32_t format) return (err || info.h_alpha <= info.l_alpha); } +// ---------------------------------------------------------------------------- +// local state +// ---------------------------------------------------------------------------- + +void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const +{ + const Layer::State& s(drawingState()); + const Transform tr(hw->getTransform() * s.transform); + const uint32_t hw_h = hw->getHeight(); + Rect win(s.active.w, s.active.h); + if (!s.active.crop.isEmpty()) { + win.intersect(s.active.crop, &win); + } + if (mesh) { + tr.transform(mesh->mVertices[0], win.left, win.top); + tr.transform(mesh->mVertices[1], win.left, win.bottom); + tr.transform(mesh->mVertices[2], win.right, win.bottom); + tr.transform(mesh->mVertices[3], win.right, win.top); + for (size_t i=0 ; i<4 ; i++) { + mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1]; + } + } +} bool Layer::isOpaque() const { @@ -404,8 +712,39 @@ bool Layer::isProtected() const (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); } -uint32_t Layer::doTransaction(uint32_t flags) -{ +bool Layer::isFixedSize() const { + return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; +} + +bool Layer::isCropped() const { + return !mCurrentCrop.isEmpty(); +} + +bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const { + return mNeedsFiltering || hw->needsFiltering(); +} + +void Layer::setVisibleRegion(const Region& visibleRegion) { + // always called from main thread + this->visibleRegion = visibleRegion; +} + +void Layer::setCoveredRegion(const Region& coveredRegion) { + // always called from main thread + this->coveredRegion = coveredRegion; +} + +void Layer::setVisibleNonTransparentRegion(const Region& + setVisibleNonTransparentRegion) { + // always called from main thread + this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; +} + +// ---------------------------------------------------------------------------- +// transaction +// ---------------------------------------------------------------------------- + +uint32_t Layer::doTransaction(uint32_t flags) { ATRACE_CALL(); const Layer::State& front(drawingState()); @@ -464,7 +803,7 @@ uint32_t Layer::doTransaction(uint32_t flags) (temp.requested.h != temp.active.h); if (resizePending) { - // don't let LayerBase::doTransaction update the drawing state + // don't let Layer::doTransaction update the drawing state // if we have a pending resize, unless we are in fixed-size mode. // the drawing state will be updated only once we receive a buffer // with the correct size. @@ -477,15 +816,117 @@ uint32_t Layer::doTransaction(uint32_t flags) } } - return LayerBase::doTransaction(flags); + // always set active to requested, unless we're asked not to + // this is used by Layer, which special cases resizes. + if (flags & eDontUpdateGeometryState) { + } else { + Layer::State& editTemp(currentState()); + editTemp.active = temp.requested; + } + + if (front.active != temp.active) { + // invalidate and recompute the visible regions if needed + flags |= Layer::eVisibleRegion; + } + + if (temp.sequence != front.sequence) { + // invalidate and recompute the visible regions if needed + flags |= eVisibleRegion; + this->contentDirty = true; + + // we may use linear filtering, if the matrix scales us + const uint8_t type = temp.transform.getType(); + mNeedsFiltering = (!temp.transform.preserveRects() || + (type >= Transform::SCALE)); + } + + // Commit the transaction + commitTransaction(); + return flags; } -bool Layer::isFixedSize() const { - return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; +void Layer::commitTransaction() { + mDrawingState = mCurrentState; } -bool Layer::isCropped() const { - return !mCurrentCrop.isEmpty(); +uint32_t Layer::getTransactionFlags(uint32_t flags) { + return android_atomic_and(~flags, &mTransactionFlags) & flags; +} + +uint32_t Layer::setTransactionFlags(uint32_t flags) { + return android_atomic_or(flags, &mTransactionFlags); +} + +bool Layer::setPosition(float x, float y) { + if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) + return false; + mCurrentState.sequence++; + mCurrentState.transform.set(x, y); + setTransactionFlags(eTransactionNeeded); + return true; +} +bool Layer::setLayer(uint32_t z) { + if (mCurrentState.z == z) + return false; + mCurrentState.sequence++; + mCurrentState.z = z; + setTransactionFlags(eTransactionNeeded); + return true; +} +bool Layer::setSize(uint32_t w, uint32_t h) { + if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) + return false; + mCurrentState.requested.w = w; + mCurrentState.requested.h = h; + setTransactionFlags(eTransactionNeeded); + return true; +} +bool Layer::setAlpha(uint8_t alpha) { + if (mCurrentState.alpha == alpha) + return false; + mCurrentState.sequence++; + mCurrentState.alpha = alpha; + setTransactionFlags(eTransactionNeeded); + return true; +} +bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { + mCurrentState.sequence++; + mCurrentState.transform.set( + matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); + setTransactionFlags(eTransactionNeeded); + return true; +} +bool Layer::setTransparentRegionHint(const Region& transparent) { + mCurrentState.sequence++; + mCurrentState.transparentRegion = transparent; + setTransactionFlags(eTransactionNeeded); + return true; +} +bool Layer::setFlags(uint8_t flags, uint8_t mask) { + const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); + if (mCurrentState.flags == newFlags) + return false; + mCurrentState.sequence++; + mCurrentState.flags = newFlags; + setTransactionFlags(eTransactionNeeded); + return true; +} +bool Layer::setCrop(const Rect& crop) { + if (mCurrentState.requested.crop == crop) + return false; + mCurrentState.sequence++; + mCurrentState.requested.crop = crop; + setTransactionFlags(eTransactionNeeded); + return true; +} + +bool Layer::setLayerStack(uint32_t layerStack) { + if (mCurrentState.layerStack == layerStack) + return false; + mCurrentState.sequence++; + mCurrentState.layerStack = layerStack; + setTransactionFlags(eTransactionNeeded); + return true; } // ---------------------------------------------------------------------------- @@ -528,7 +969,9 @@ void Layer::onPostComposition() { } bool Layer::isVisible() const { - return LayerBaseClient::isVisible() && (mActiveBuffer != NULL); + const Layer::State& s(mDrawingState); + return !(s.flags & layer_state_t::eLayerHidden) && s.alpha + && (mActiveBuffer != NULL); } Region Layer::latchBuffer(bool& recomputeVisibleRegions) @@ -702,9 +1145,64 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) return outDirtyRegion; } +uint32_t Layer::getEffectiveUsage(uint32_t usage) const +{ + // TODO: should we do something special if mSecure is set? + if (mProtectedByApp) { + // need a hardware-protected path to external video sink + usage |= GraphicBuffer::USAGE_PROTECTED; + } + usage |= GraphicBuffer::USAGE_HW_COMPOSER; + return usage; +} + +void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { + uint32_t orientation = 0; + if (!mFlinger->mDebugDisableTransformHint) { + // The transform hint is used to improve performance, but we can + // only have a single transform hint, it cannot + // apply to all displays. + const Transform& planeTransform(hw->getTransform()); + orientation = planeTransform.getOrientation(); + if (orientation & Transform::ROT_INVALID) { + orientation = 0; + } + } + mSurfaceFlingerConsumer->setTransformHint(orientation); +} + +// ---------------------------------------------------------------------------- +// debugging +// ---------------------------------------------------------------------------- + void Layer::dump(String8& result, char* buffer, size_t SIZE) const { - LayerBaseClient::dump(result, buffer, SIZE); + const Layer::State& s(drawingState()); + + snprintf(buffer, SIZE, + "+ %s %p (%s)\n", + getTypeId(), this, getName().string()); + result.append(buffer); + + s.transparentRegion.dump(result, "transparentRegion"); + visibleRegion.dump(result, "visibleRegion"); + sp<Client> client(mClientRef.promote()); + + snprintf(buffer, SIZE, + " " + "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), " + "isOpaque=%1d, invalidate=%1d, " + "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n" + " client=%p\n", + s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h, + s.active.crop.left, s.active.crop.top, + s.active.crop.right, s.active.crop.bottom, + isOpaque(), contentDirty, + s.alpha, s.flags, + s.transform[0][0], s.transform[0][1], + s.transform[1][0], s.transform[1][1], + client.get()); + result.append(buffer); sp<const GraphicBuffer> buf0(mActiveBuffer); uint32_t w0=0, h0=0, s0=0, f0=0; @@ -728,42 +1226,29 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const } } -void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const -{ - LayerBaseClient::dumpStats(result, buffer, SIZE); + +void Layer::shortDump(String8& result, char* scratch, size_t size) const { + Layer::dump(result, scratch, size); +} + +void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const { mFrameTracker.dump(result); } -void Layer::clearStats() -{ - LayerBaseClient::clearStats(); +void Layer::clearStats() { mFrameTracker.clear(); } -uint32_t Layer::getEffectiveUsage(uint32_t usage) const -{ - // TODO: should we do something special if mSecure is set? - if (mProtectedByApp) { - // need a hardware-protected path to external video sink - usage |= GraphicBuffer::USAGE_PROTECTED; - } - usage |= GraphicBuffer::USAGE_HW_COMPOSER; - return usage; +// --------------------------------------------------------------------------- + +Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, + const sp<Layer>& layer) + : mFlinger(flinger), mLayer(layer) { } -void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { - uint32_t orientation = 0; - if (!mFlinger->mDebugDisableTransformHint) { - // The transform hint is used to improve performance, but we can - // only have a single transform hint, it cannot - // apply to all displays. - const Transform& planeTransform(hw->getTransform()); - orientation = planeTransform.getOrientation(); - if (orientation & Transform::ROT_INVALID) { - orientation = 0; - } - } - mSurfaceFlingerConsumer->setTransformHint(orientation); +Layer::LayerCleaner::~LayerCleaner() { + // destroy client resources + mFlinger->onLayerDestroyed(mLayer); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index e57fb59..5fb6d8b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -20,118 +20,356 @@ #include <stdint.h> #include <sys/types.h> +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include <utils/RefBase.h> +#include <utils/String8.h> #include <utils/Timers.h> #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> +#include <ui/Region.h> #include <gui/ISurfaceComposerClient.h> -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES/gl.h> -#include <GLES/glext.h> +#include <private/gui/LayerState.h> -#include "SurfaceFlingerConsumer.h" #include "FrameTracker.h" -#include "LayerBase.h" +#include "Client.h" +#include "SurfaceFlinger.h" +#include "SurfaceFlingerConsumer.h" #include "SurfaceTextureLayer.h" #include "Transform.h" +#include "DisplayHardware/HWComposer.h" + namespace android { // --------------------------------------------------------------------------- class Client; +class DisplayDevice; +class GraphicBuffer; +class SurfaceFlinger; class GLExtensions; // --------------------------------------------------------------------------- /* - * The Layer class is essentially a LayerBase combined with a BufferQueue. * A new BufferQueue and a new SurfaceFlingerConsumer are created when the * Layer is first referenced. * * This also implements onFrameAvailable(), which notifies SurfaceFlinger * that new data has arrived. */ -class Layer : public LayerBaseClient, - public SurfaceFlingerConsumer::FrameAvailableListener -{ +class Layer : public SurfaceFlingerConsumer::FrameAvailableListener { + static int32_t sSequence; + public: + mutable bool contentDirty; + // regions below are in window-manager space + Region visibleRegion; + Region coveredRegion; + Region visibleNonTransparentRegion; + int32_t sequence; + + enum { // flags for doTransaction() + eDontUpdateGeometryState = 0x00000001, + eVisibleRegion = 0x00000002, + }; + + struct Geometry { + uint32_t w; + uint32_t h; + Rect crop; + inline bool operator ==(const Geometry& rhs) const { + return (w == rhs.w && h == rhs.h && crop == rhs.crop); + } + inline bool operator !=(const Geometry& rhs) const { + return !operator ==(rhs); + } + }; + + struct State { + Geometry active; + Geometry requested; + uint32_t z; + uint32_t layerStack; + uint8_t alpha; + uint8_t flags; + uint8_t reserved[2]; + int32_t sequence; // changes when visible regions can change + Transform transform; + Region transparentRegion; + }; + + class LayerMesh { + friend class Layer; + GLfloat mVertices[4][2]; + size_t mNumVertices; + public: + LayerMesh() : + mNumVertices(4) { + } + GLfloat const* getVertices() const { + return &mVertices[0][0]; + } + size_t getVertexCount() const { + return mNumVertices; + } + }; + + // ----------------------------------------------------------------------- + Layer(SurfaceFlinger* flinger, const sp<Client>& client); virtual ~Layer(); - virtual const char* getTypeId() const { return "Layer"; } - // the this layer's size and format status_t setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags=0); - bool isFixedSize() const; + // Creates an ISurface associated with this object. This may only be + // called once. to provide your own ISurface, override createSurface(). + sp<ISurface> getSurface(); + + // modify current state + bool setPosition(float x, float y); + bool setLayer(uint32_t z); + bool setSize(uint32_t w, uint32_t h); + bool setAlpha(uint8_t alpha); + bool setMatrix(const layer_state_t::matrix22_t& matrix); + bool setTransparentRegionHint(const Region& transparent); + bool setFlags(uint8_t flags, uint8_t mask); + bool setCrop(const Rect& crop); + bool setLayerStack(uint32_t layerStack); + + void commitTransaction(); + + uint32_t getTransactionFlags(uint32_t flags); + uint32_t setTransactionFlags(uint32_t flags); + + void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const; + Rect computeBounds() const; + + // ----------------------------------------------------------------------- + + /* + * initStates - called just after construction + */ + virtual void initStates(uint32_t w, uint32_t h, uint32_t flags); + + virtual const char* getTypeId() const { return "Layer"; } + + virtual void setName(const String8& name); + String8 getName() const; - // LayerBase interface virtual void setGeometry(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer); virtual void setPerFrameData(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer); virtual void setAcquireFence(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface& layer); + + /* + * called after page-flip + */ virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw, HWComposer::HWCLayerInterface* layer); + + /* + * called before composition. + * returns true if the layer has pending updates. + */ virtual bool onPreComposition(); + + /* + * called after composition. + */ virtual void onPostComposition(); + /* + * draw - performs some global clipping optimizations + * and calls onDraw(). + * Typically this method is not overridden, instead implement onDraw() + * to perform the actual drawing. + */ + virtual void draw(const sp<const DisplayDevice>& hw, const Region& clip) const; + virtual void draw(const sp<const DisplayDevice>& hw); + + /* + * onDraw - draws the surface. + */ virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const; + + /* + * needsLinearFiltering - true if this surface's state requires filtering + */ + virtual bool needsFiltering(const sp<const DisplayDevice>& hw) const; + + /* + * doTransaction - process the transaction. This is a good place to figure + * out which attributes of the surface have changed. + */ virtual uint32_t doTransaction(uint32_t transactionFlags); + + /* + * setVisibleRegion - called to set the new visible region. This gives + * a chance to update the new visible region or record the fact it changed. + */ + virtual void setVisibleRegion(const Region& visibleRegion); + + /* + * setCoveredRegion - called when the covered region changes. The covered + * region corresponds to any area of the surface that is covered + * (transparently or not) by another surface. + */ + virtual void setCoveredRegion(const Region& coveredRegion); + + /* + * setVisibleNonTransparentRegion - called when the visible and + * non-transparent region changes. + */ + virtual void setVisibleNonTransparentRegion(const Region& + visibleNonTransparentRegion); + + /* + * latchBuffer - called each time the screen is redrawn and returns whether + * the visible regions need to be recomputed (this is a fairly heavy + * operation, so this should be set only if needed). Typically this is used + * to figure out if the content or size of a surface has changed. + */ virtual Region latchBuffer(bool& recomputeVisibleRegions); + + /* + * isOpaque - true if this surface is opaque + */ virtual bool isOpaque() const; + + /* + * isSecure - true if this surface is secure, that is if it prevents + * screenshots or VNC servers. + */ virtual bool isSecure() const { return mSecure; } + + /* + * isProtected - true if the layer may contain protected content in the + * GRALLOC_USAGE_PROTECTED sense. + */ virtual bool isProtected() const; - virtual void onRemoved(); - virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); } - virtual void setName(const String8& name); + + /* + * isVisible - true if this layer is visible, false otherwise + */ virtual bool isVisible() const; - // LayerBaseClient interface - virtual wp<IBinder> getSurfaceTextureBinder() const; + /* + * isFixedSize - true if content has a fixed size + */ + virtual bool isFixedSize() const; + + /* + * called with the state lock when the surface is removed from the + * current list + */ + virtual void onRemoved(); - // only for debugging - inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; } + + virtual wp<IBinder> getSurfaceTextureBinder() const; // Updates the transform hint in our SurfaceFlingerConsumer to match // the current orientation of the display device. virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const; + /* + * returns the rectangle that crops the content of the layer and scales it + * to the layer's size. + */ virtual Rect getContentCrop() const; + + /* + * returns the transform bits (90 rotation / h-flip / v-flip) of the + * layer's content + */ virtual uint32_t getContentTransform() const; -protected: - virtual void onFirstRef(); + // ----------------------------------------------------------------------- + + void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const; + void setFiltering(bool filtering); + bool getFiltering() const; + + // only for debugging + inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; } + + inline const State& drawingState() const { return mDrawingState; } + inline const State& currentState() const { return mCurrentState; } + inline State& currentState() { return mCurrentState; } + + + /* always call base class first */ virtual void dump(String8& result, char* scratch, size_t size) const; + virtual void shortDump(String8& result, char* scratch, size_t size) const; virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const; virtual void clearStats(); - sp<SurfaceFlingerConsumer> getConsumer() const { - return mSurfaceFlingerConsumer; - } +protected: + // constant + sp<SurfaceFlinger> mFlinger; + + virtual void onFirstRef(); + + /* + * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer) + * is called. + */ + class LayerCleaner { + sp<SurfaceFlinger> mFlinger; + wp<Layer> mLayer; + protected: + ~LayerCleaner(); + public: + LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer); + }; + private: // Creates an instance of ISurface for this Layer. virtual sp<ISurface> createSurface(); + // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener + virtual void onFrameAvailable(); + + uint32_t getEffectiveUsage(uint32_t usage) const; + Rect computeCrop(const sp<const DisplayDevice>& hw) const; bool isCropped() const; static bool getOpacityForFormat(uint32_t format); - // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener - virtual void onFrameAvailable(); + // drawing + void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip, + GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const; + void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const; + // ----------------------------------------------------------------------- // constants sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer; GLuint mTextureName; + bool mPremultipliedAlpha; + String8 mName; + mutable bool mDebug; + PixelFormat mFormat; + const GLExtensions& mGLExtensions; + bool mOpaqueLayer; + + // these are protected by an external lock + State mCurrentState; + State mDrawingState; + volatile int32_t mTransactionFlags; // thread-safe volatile int32_t mQueuedFrames; @@ -145,15 +383,20 @@ private: bool mCurrentOpacity; bool mRefreshPending; bool mFrameLatencyNeeded; - - // constants - PixelFormat mFormat; - const GLExtensions& mGLExtensions; - bool mOpaqueLayer; + // Whether filtering is forced on or not + bool mFiltering; + // Whether filtering is needed b/c of the drawingstate + bool mNeedsFiltering; // page-flip thread (currently main thread) - bool mSecure; // no screenshots + bool mSecure; // no screenshots bool mProtectedByApp; // application requires protected path to external sink + + // protected by mLock + mutable Mutex mLock; + // Set to true if an ISurface has been associated with this object. + mutable bool mHasSurface; + const wp<Client> mClientRef; }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp deleted file mode 100644 index db2b20e..0000000 --- a/services/surfaceflinger/LayerBase.cpp +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> -#include <math.h> - -#include <utils/Errors.h> -#include <utils/Log.h> -#include <binder/IPCThreadState.h> -#include <binder/IServiceManager.h> - -#include <GLES/gl.h> -#include <GLES/glext.h> - -#include <hardware/hardware.h> - -#include "clz.h" -#include "Client.h" -#include "LayerBase.h" -#include "Layer.h" -#include "SurfaceFlinger.h" -#include "DisplayDevice.h" - -namespace android { - -// --------------------------------------------------------------------------- - -int32_t LayerBase::sSequence = 1; - -LayerBase::LayerBase(SurfaceFlinger* flinger) - : contentDirty(false), - sequence(uint32_t(android_atomic_inc(&sSequence))), - mFlinger(flinger), mFiltering(false), - mNeedsFiltering(false), - mTransactionFlags(0), - mPremultipliedAlpha(true), mName("unnamed"), mDebug(false) -{ -} - -LayerBase::~LayerBase() -{ -} - -void LayerBase::setName(const String8& name) { - mName = name; -} - -String8 LayerBase::getName() const { - return mName; -} - -void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags) -{ - uint32_t layerFlags = 0; - if (flags & ISurfaceComposerClient::eHidden) - layerFlags = layer_state_t::eLayerHidden; - - if (flags & ISurfaceComposerClient::eNonPremultiplied) - mPremultipliedAlpha = false; - - mCurrentState.active.w = w; - mCurrentState.active.h = h; - mCurrentState.active.crop.makeInvalid(); - mCurrentState.z = 0; - mCurrentState.alpha = 0xFF; - mCurrentState.layerStack = 0; - mCurrentState.flags = layerFlags; - mCurrentState.sequence = 0; - mCurrentState.transform.set(0, 0); - mCurrentState.requested = mCurrentState.active; - - // drawing state & current state are identical - mDrawingState = mCurrentState; -} - -bool LayerBase::needsFiltering(const sp<const DisplayDevice>& hw) const { - return mNeedsFiltering || hw->needsFiltering(); -} - -void LayerBase::commitTransaction() { - mDrawingState = mCurrentState; -} -void LayerBase::forceVisibilityTransaction() { - // this can be called without SurfaceFlinger.mStateLock, but if we - // can atomically increment the sequence number, it doesn't matter. - android_atomic_inc(&mCurrentState.sequence); - requestTransaction(); -} -bool LayerBase::requestTransaction() { - int32_t old = setTransactionFlags(eTransactionNeeded); - return ((old & eTransactionNeeded) == 0); -} -uint32_t LayerBase::getTransactionFlags(uint32_t flags) { - return android_atomic_and(~flags, &mTransactionFlags) & flags; -} -uint32_t LayerBase::setTransactionFlags(uint32_t flags) { - return android_atomic_or(flags, &mTransactionFlags); -} - -bool LayerBase::setPosition(float x, float y) { - if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) - return false; - mCurrentState.sequence++; - mCurrentState.transform.set(x, y); - requestTransaction(); - return true; -} -bool LayerBase::setLayer(uint32_t z) { - if (mCurrentState.z == z) - return false; - mCurrentState.sequence++; - mCurrentState.z = z; - requestTransaction(); - return true; -} -bool LayerBase::setSize(uint32_t w, uint32_t h) { - if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) - return false; - mCurrentState.requested.w = w; - mCurrentState.requested.h = h; - requestTransaction(); - return true; -} -bool LayerBase::setAlpha(uint8_t alpha) { - if (mCurrentState.alpha == alpha) - return false; - mCurrentState.sequence++; - mCurrentState.alpha = alpha; - requestTransaction(); - return true; -} -bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) { - mCurrentState.sequence++; - mCurrentState.transform.set( - matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); - requestTransaction(); - return true; -} -bool LayerBase::setTransparentRegionHint(const Region& transparent) { - mCurrentState.sequence++; - mCurrentState.transparentRegion = transparent; - requestTransaction(); - return true; -} -bool LayerBase::setFlags(uint8_t flags, uint8_t mask) { - const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); - if (mCurrentState.flags == newFlags) - return false; - mCurrentState.sequence++; - mCurrentState.flags = newFlags; - requestTransaction(); - return true; -} -bool LayerBase::setCrop(const Rect& crop) { - if (mCurrentState.requested.crop == crop) - return false; - mCurrentState.sequence++; - mCurrentState.requested.crop = crop; - requestTransaction(); - return true; -} - -bool LayerBase::setLayerStack(uint32_t layerStack) { - if (mCurrentState.layerStack == layerStack) - return false; - mCurrentState.sequence++; - mCurrentState.layerStack = layerStack; - requestTransaction(); - return true; -} - -void LayerBase::setVisibleRegion(const Region& visibleRegion) { - // always called from main thread - this->visibleRegion = visibleRegion; -} - -void LayerBase::setCoveredRegion(const Region& coveredRegion) { - // always called from main thread - this->coveredRegion = coveredRegion; -} - -void LayerBase::setVisibleNonTransparentRegion(const Region& - setVisibleNonTransparentRegion) { - // always called from main thread - this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; -} - -uint32_t LayerBase::doTransaction(uint32_t flags) -{ - const Layer::State& front(drawingState()); - const Layer::State& temp(currentState()); - - // always set active to requested, unless we're asked not to - // this is used by Layer, which special cases resizes. - if (flags & eDontUpdateGeometryState) { - } else { - Layer::State& editTemp(currentState()); - editTemp.active = temp.requested; - } - - if (front.active != temp.active) { - // invalidate and recompute the visible regions if needed - flags |= Layer::eVisibleRegion; - } - - if (temp.sequence != front.sequence) { - // invalidate and recompute the visible regions if needed - flags |= eVisibleRegion; - this->contentDirty = true; - - // we may use linear filtering, if the matrix scales us - const uint8_t type = temp.transform.getType(); - mNeedsFiltering = (!temp.transform.preserveRects() || - (type >= Transform::SCALE)); - } - - // Commit the transaction - commitTransaction(); - return flags; -} - -void LayerBase::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const -{ - const Layer::State& s(drawingState()); - const Transform tr(hw->getTransform() * s.transform); - const uint32_t hw_h = hw->getHeight(); - Rect win(s.active.w, s.active.h); - if (!s.active.crop.isEmpty()) { - win.intersect(s.active.crop, &win); - } - if (mesh) { - tr.transform(mesh->mVertices[0], win.left, win.top); - tr.transform(mesh->mVertices[1], win.left, win.bottom); - tr.transform(mesh->mVertices[2], win.right, win.bottom); - tr.transform(mesh->mVertices[3], win.right, win.top); - for (size_t i=0 ; i<4 ; i++) { - mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1]; - } - } -} - -Rect LayerBase::computeBounds() const { - const Layer::State& s(drawingState()); - Rect win(s.active.w, s.active.h); - if (!s.active.crop.isEmpty()) { - win.intersect(s.active.crop, &win); - } - return win; -} - -Region LayerBase::latchBuffer(bool& recomputeVisibleRegions) { - Region result; - return result; -} - - -Rect LayerBase::getContentCrop() const { - // regular layers just use their active area as the content crop - const State& s(drawingState()); - return Rect(s.active.w, s.active.h); -} - -uint32_t LayerBase::getContentTransform() const { - // regular layers don't have a content transform - return 0; -} - -Rect LayerBase::computeCrop(const sp<const DisplayDevice>& hw) const { - /* - * The way we compute the crop (aka. texture coordinates when we have a - * Layer) produces a different output from the GL code in - * drawWithOpenGL() due to HWC being limited to integers. The difference - * can be large if getContentTransform() contains a large scale factor. - * See comments in drawWithOpenGL() for more details. - */ - - // the content crop is the area of the content that gets scaled to the - // layer's size. - Rect crop(getContentCrop()); - - // the active.crop is the area of the window that gets cropped, but not - // scaled in any ways. - const State& s(drawingState()); - - // apply the projection's clipping to the window crop in - // layerstack space, and convert-back to layer space. - // if there are no window scaling (or content scaling) involved, - // this operation will map to full pixels in the buffer. - // NOTE: should we revert to GL composition if a scaling is involved - // since it cannot be represented in the HWC API? - Rect activeCrop(s.transform.transform(s.active.crop)); - activeCrop.intersect(hw->getViewport(), &activeCrop); - activeCrop = s.transform.inverse().transform(activeCrop); - - // paranoia: make sure the window-crop is constrained in the - // window's bounds - activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); - - if (!activeCrop.isEmpty()) { - // Transform the window crop to match the buffer coordinate system, - // which means using the inverse of the current transform set on the - // SurfaceFlingerConsumer. - uint32_t invTransform = getContentTransform(); - int winWidth = s.active.w; - int winHeight = s.active.h; - if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { - invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | - NATIVE_WINDOW_TRANSFORM_FLIP_H; - winWidth = s.active.h; - winHeight = s.active.w; - } - const Rect winCrop = activeCrop.transform( - invTransform, s.active.w, s.active.h); - - // the code below essentially performs a scaled intersection - // of crop and winCrop - float xScale = float(crop.width()) / float(winWidth); - float yScale = float(crop.height()) / float(winHeight); - - int insetL = int(ceilf( winCrop.left * xScale)); - int insetT = int(ceilf( winCrop.top * yScale)); - int insetR = int(ceilf((winWidth - winCrop.right ) * xScale)); - int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale)); - - crop.left += insetL; - crop.top += insetT; - crop.right -= insetR; - crop.bottom -= insetB; - } - return crop; -} - -void LayerBase::setGeometry( - const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer) -{ - layer.setDefaultState(); - - // this gives us only the "orientation" component of the transform - const State& s(drawingState()); - const uint32_t finalTransform = s.transform.getOrientation(); - // we can only handle simple transformation - if (finalTransform & Transform::ROT_INVALID) { - layer.setTransform(0); - } else { - layer.setTransform(finalTransform); - } - - if (!isOpaque() || s.alpha != 0xFF) { - layer.setBlending(mPremultipliedAlpha ? - HWC_BLENDING_PREMULT : - HWC_BLENDING_COVERAGE); - } - - - // apply the layer's transform, followed by the display's global transform - // here we're guaranteed that the layer's transform preserves rects - - Rect frame(s.transform.transform(computeBounds())); - frame.intersect(hw->getViewport(), &frame); - const Transform& tr(hw->getTransform()); - layer.setFrame(tr.transform(frame)); - layer.setCrop(computeCrop(hw)); -} - -void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer) { - // we have to set the visible region on every frame because - // we currently free it during onLayerDisplayed(), which is called - // after HWComposer::commit() -- every frame. - // Apply this display's projection's viewport to the visible region - // before giving it to the HWC HAL. - const Transform& tr = hw->getTransform(); - Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); - layer.setVisibleRegionScreen(visible); -} - -void LayerBase::setAcquireFence(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer) { - layer.setAcquireFenceFd(-1); -} - -void LayerBase::onLayerDisplayed(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface* layer) { - if (layer) { - layer->onDisplayed(); - } -} - -void LayerBase::setFiltering(bool filtering) -{ - mFiltering = filtering; -} - -bool LayerBase::getFiltering() const -{ - return mFiltering; -} - -bool LayerBase::isVisible() const { - const Layer::State& s(mDrawingState); - return !(s.flags & layer_state_t::eLayerHidden) && s.alpha; -} - -void LayerBase::draw(const sp<const DisplayDevice>& hw, const Region& clip) const -{ - onDraw(hw, clip); -} - -void LayerBase::draw(const sp<const DisplayDevice>& hw) -{ - onDraw( hw, Region(hw->bounds()) ); -} - -void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip, - GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const -{ - const uint32_t fbHeight = hw->getHeight(); - glColor4f(red,green,blue,alpha); - - glDisable(GL_TEXTURE_EXTERNAL_OES); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - LayerMesh mesh; - computeGeometry(hw, &mesh); - - glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices()); - glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount()); -} - -void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const -{ - clearWithOpenGL(hw, clip, 0,0,0,0); -} - -void LayerBase::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const -{ - const uint32_t fbHeight = hw->getHeight(); - const State& s(drawingState()); - - GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; - if (CC_UNLIKELY(s.alpha < 0xFF)) { - const GLfloat alpha = s.alpha * (1.0f/255.0f); - if (mPremultipliedAlpha) { - glColor4f(alpha, alpha, alpha, alpha); - } else { - glColor4f(1, 1, 1, alpha); - } - glEnable(GL_BLEND); - glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } else { - glColor4f(1, 1, 1, 1); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - if (!isOpaque()) { - glEnable(GL_BLEND); - glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); - } else { - glDisable(GL_BLEND); - } - } - - LayerMesh mesh; - computeGeometry(hw, &mesh); - - // TODO: we probably want to generate the texture coords with the mesh - // here we assume that we only have 4 vertices - - struct TexCoords { - GLfloat u; - GLfloat v; - }; - - - /* - * NOTE: the way we compute the texture coordinates here produces - * different results than when we take the HWC path -- in the later case - * the "source crop" is rounded to texel boundaries. - * This can produce significantly different results when the texture - * is scaled by a large amount. - * - * The GL code below is more logical (imho), and the difference with - * HWC is due to a limitation of the HWC API to integers -- a question - * is suspend is wether we should ignore this problem or revert to - * GL composition when a buffer scaling is applied (maybe with some - * minimal value)? Or, we could make GL behave like HWC -- but this feel - * like more of a hack. - */ - const Rect win(computeBounds()); - - GLfloat left = GLfloat(win.left) / GLfloat(s.active.w); - GLfloat top = GLfloat(win.top) / GLfloat(s.active.h); - GLfloat right = GLfloat(win.right) / GLfloat(s.active.w); - GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h); - - TexCoords texCoords[4]; - texCoords[0].u = left; - texCoords[0].v = top; - texCoords[1].u = left; - texCoords[1].v = bottom; - texCoords[2].u = right; - texCoords[2].v = bottom; - texCoords[3].u = right; - texCoords[3].v = top; - for (int i = 0; i < 4; i++) { - texCoords[i].v = 1.0f - texCoords[i].v; - } - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, texCoords); - glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices()); - glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount()); - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisable(GL_BLEND); -} - -void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const -{ - const Layer::State& s(drawingState()); - - snprintf(buffer, SIZE, - "+ %s %p (%s)\n", - getTypeId(), this, getName().string()); - result.append(buffer); - - s.transparentRegion.dump(result, "transparentRegion"); - visibleRegion.dump(result, "visibleRegion"); - - snprintf(buffer, SIZE, - " " - "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), " - "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, " - "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", - s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h, - s.active.crop.left, s.active.crop.top, - s.active.crop.right, s.active.crop.bottom, - isOpaque(), needsDithering(), contentDirty, - s.alpha, s.flags, - s.transform[0][0], s.transform[0][1], - s.transform[1][0], s.transform[1][1]); - result.append(buffer); -} - -void LayerBase::shortDump(String8& result, char* scratch, size_t size) const { - LayerBase::dump(result, scratch, size); -} - -void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const { -} - -void LayerBase::clearStats() { -} - -sp<LayerBaseClient> LayerBase::getLayerBaseClient() const { - return 0; -} - -sp<Layer> LayerBase::getLayer() const { - return 0; -} - -// --------------------------------------------------------------------------- - -LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, - const sp<Client>& client) - : LayerBase(flinger), - mHasSurface(false), - mClientRef(client) -{ -} - -LayerBaseClient::~LayerBaseClient() -{ - sp<Client> c(mClientRef.promote()); - if (c != 0) { - c->detachLayer(this); - } -} - -sp<ISurface> LayerBaseClient::createSurface() -{ - class BSurface : public BnSurface, public LayerCleaner { - virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; } - public: - BSurface(const sp<SurfaceFlinger>& flinger, - const sp<LayerBaseClient>& layer) - : LayerCleaner(flinger, layer) { } - }; - sp<ISurface> sur(new BSurface(mFlinger, this)); - return sur; -} - -sp<ISurface> LayerBaseClient::getSurface() -{ - sp<ISurface> s; - Mutex::Autolock _l(mLock); - - LOG_ALWAYS_FATAL_IF(mHasSurface, - "LayerBaseClient::getSurface() has already been called"); - - mHasSurface = true; - s = createSurface(); - mClientSurfaceBinder = s->asBinder(); - return s; -} - -wp<IBinder> LayerBaseClient::getSurfaceBinder() const { - return mClientSurfaceBinder; -} - -wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const { - return 0; -} - -void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const -{ - LayerBase::dump(result, buffer, SIZE); - sp<Client> client(mClientRef.promote()); - snprintf(buffer, SIZE, " client=%p\n", client.get()); - result.append(buffer); -} - - -void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const -{ - LayerBaseClient::dump(result, scratch, size); -} - -// --------------------------------------------------------------------------- - -LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, - const sp<LayerBaseClient>& layer) - : mFlinger(flinger), mLayer(layer) { -} - -LayerBaseClient::LayerCleaner::~LayerCleaner() { - // destroy client resources - mFlinger->onLayerDestroyed(mLayer); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h deleted file mode 100644 index ecae2d9..0000000 --- a/services/surfaceflinger/LayerBase.h +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_LAYER_BASE_H -#define ANDROID_LAYER_BASE_H - -#include <stdint.h> -#include <sys/types.h> - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GLES/gl.h> - -#include <utils/RefBase.h> -#include <utils/String8.h> - -#include <ui/Region.h> - -#include <gui/ISurfaceComposerClient.h> - -#include <private/gui/LayerState.h> - -#include "Transform.h" -#include "DisplayHardware/HWComposer.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class Client; -class DisplayDevice; -class GraphicBuffer; -class Layer; -class LayerBaseClient; -class SurfaceFlinger; - -// --------------------------------------------------------------------------- - -/* - * Layers are rectangular graphic entities, internal to SurfaceFlinger. - * They have properties including width, height, Z-depth, and 2D - * transformations (chiefly translation and 90-degree rotations). - * - * Layers are organized into "layer stacks". Each layer is a member of - * exactly one layer stack, identified by an integer in Layer::State. A - * given layer stack may appear on more than one display. - * - * Notable subclasses (below LayerBaseClient) include Layer, LayerDim, and - * LayerScreenshot. - */ -class LayerBase : virtual public RefBase -{ - static int32_t sSequence; - -public: - LayerBase(SurfaceFlinger* flinger); - - mutable bool contentDirty; - // regions below are in window-manager space - Region visibleRegion; - Region coveredRegion; - Region visibleNonTransparentRegion; - int32_t sequence; - - struct Geometry { - uint32_t w; - uint32_t h; - Rect crop; - inline bool operator == (const Geometry& rhs) const { - return (w==rhs.w && h==rhs.h && crop==rhs.crop); - } - inline bool operator != (const Geometry& rhs) const { - return !operator == (rhs); - } - }; - - struct State { - Geometry active; - Geometry requested; - uint32_t z; - uint32_t layerStack; - uint8_t alpha; - uint8_t flags; - uint8_t reserved[2]; - int32_t sequence; // changes when visible regions can change - Transform transform; - Region transparentRegion; - }; - - class LayerMesh { - friend class LayerBase; - GLfloat mVertices[4][2]; - size_t mNumVertices; - public: - LayerMesh() : mNumVertices(4) { } - GLfloat const* getVertices() const { - return &mVertices[0][0]; - } - size_t getVertexCount() const { - return mNumVertices; - } - }; - - virtual void setName(const String8& name); - String8 getName() const; - - // modify current state - bool setPosition(float x, float y); - bool setLayer(uint32_t z); - bool setSize(uint32_t w, uint32_t h); - bool setAlpha(uint8_t alpha); - bool setMatrix(const layer_state_t::matrix22_t& matrix); - bool setTransparentRegionHint(const Region& transparent); - bool setFlags(uint8_t flags, uint8_t mask); - bool setCrop(const Rect& crop); - bool setLayerStack(uint32_t layerStack); - - void commitTransaction(); - bool requestTransaction(); - void forceVisibilityTransaction(); - - uint32_t getTransactionFlags(uint32_t flags); - uint32_t setTransactionFlags(uint32_t flags); - - void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const; - Rect computeBounds() const; - - - virtual sp<LayerBaseClient> getLayerBaseClient() const; - virtual sp<Layer> getLayer() const; - - virtual const char* getTypeId() const { return "LayerBase"; } - - virtual void setGeometry(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer); - virtual void setPerFrameData(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer); - virtual void setAcquireFence(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface& layer); - - /** - * draw - performs some global clipping optimizations - * and calls onDraw(). - * Typically this method is not overridden, instead implement onDraw() - * to perform the actual drawing. - */ - virtual void draw(const sp<const DisplayDevice>& hw, const Region& clip) const; - virtual void draw(const sp<const DisplayDevice>& hw); - - /** - * onDraw - draws the surface. - */ - virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const = 0; - - /** - * initStates - called just after construction - */ - virtual void initStates(uint32_t w, uint32_t h, uint32_t flags); - - /** - * doTransaction - process the transaction. This is a good place to figure - * out which attributes of the surface have changed. - */ - virtual uint32_t doTransaction(uint32_t transactionFlags); - - /** - * setVisibleRegion - called to set the new visible region. This gives - * a chance to update the new visible region or record the fact it changed. - */ - virtual void setVisibleRegion(const Region& visibleRegion); - - /** - * setCoveredRegion - called when the covered region changes. The covered - * region corresponds to any area of the surface that is covered - * (transparently or not) by another surface. - */ - virtual void setCoveredRegion(const Region& coveredRegion); - - /** - * setVisibleNonTransparentRegion - called when the visible and - * non-transparent region changes. - */ - virtual void setVisibleNonTransparentRegion(const Region& - visibleNonTransparentRegion); - - /** - * latchBuffer - called each time the screen is redrawn and returns whether - * the visible regions need to be recomputed (this is a fairly heavy - * operation, so this should be set only if needed). Typically this is used - * to figure out if the content or size of a surface has changed. - */ - virtual Region latchBuffer(bool& recomputeVisibleRegions); - - /** - * isOpaque - true if this surface is opaque - */ - virtual bool isOpaque() const { return true; } - - /** - * needsDithering - true if this surface needs dithering - */ - virtual bool needsDithering() const { return false; } - - /** - * needsLinearFiltering - true if this surface's state requires filtering - */ - virtual bool needsFiltering(const sp<const DisplayDevice>& hw) const; - - /** - * isSecure - true if this surface is secure, that is if it prevents - * screenshots or VNC servers. - */ - virtual bool isSecure() const { return false; } - - /** - * isProtected - true if the layer may contain protected content in the - * GRALLOC_USAGE_PROTECTED sense. - */ - virtual bool isProtected() const { return false; } - - /* - * isVisible - true if this layer is visibile, false otherwise - */ - virtual bool isVisible() const; - - /** called with the state lock when the surface is removed from the - * current list */ - virtual void onRemoved() { } - - /** called after page-flip - */ - virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw, - HWComposer::HWCLayerInterface* layer); - - /** called before composition. - * returns true if the layer has pending updates. - */ - virtual bool onPreComposition() { return false; } - - /** called before composition. - */ - virtual void onPostComposition() { } - - /** - * Updates the GLConsumer's transform hint, for layers that have - * a GLConsumer. - */ - virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const { } - - /** - * returns the rectangle that crops the content of the layer and scales it - * to the layer's size. - */ - virtual Rect getContentCrop() const; - - /* - * returns the transform bits (90 rotation / h-flip / v-flip) of the - * layer's content - */ - virtual uint32_t getContentTransform() const; - - /** always call base class first */ - virtual void dump(String8& result, char* scratch, size_t size) const; - virtual void shortDump(String8& result, char* scratch, size_t size) const; - virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const; - virtual void clearStats(); - - - enum { // flags for doTransaction() - eDontUpdateGeometryState = 0x00000001, - eVisibleRegion = 0x00000002, - }; - - - inline const State& drawingState() const { return mDrawingState; } - inline const State& currentState() const { return mCurrentState; } - inline State& currentState() { return mCurrentState; } - - void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const; - - void setFiltering(bool filtering); - bool getFiltering() const; - -private: - Rect computeCrop(const sp<const DisplayDevice>& hw) const; - -protected: - void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip, - GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const; - void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const; - - sp<SurfaceFlinger> mFlinger; - -private: - // accessed only in the main thread - // Whether filtering is forced on or not - bool mFiltering; - - // Whether filtering is needed b/c of the drawingstate - bool mNeedsFiltering; - -protected: - // these are protected by an external lock - State mCurrentState; - State mDrawingState; - volatile int32_t mTransactionFlags; - - // don't change, don't need a lock - bool mPremultipliedAlpha; - String8 mName; - mutable bool mDebug; - - -public: - // called from class SurfaceFlinger - virtual ~LayerBase(); - -private: - LayerBase(const LayerBase& rhs); -}; - - -// --------------------------------------------------------------------------- - -/* - * This adds some additional fields and methods to support some Binder IPC - * interactions. In particular, the LayerBaseClient's lifetime can be - * managed by references to an ISurface object in another process. - */ -class LayerBaseClient : public LayerBase -{ -public: - LayerBaseClient(SurfaceFlinger* flinger, const sp<Client>& client); - - virtual ~LayerBaseClient(); - - // Creates an ISurface associated with this object. This may only be - // called once (see also getSurfaceBinder()). - sp<ISurface> getSurface(); - - // Returns the Binder object for the ISurface associated with - // this object. - wp<IBinder> getSurfaceBinder() const; - - virtual wp<IBinder> getSurfaceTextureBinder() const; - - virtual sp<LayerBaseClient> getLayerBaseClient() const { - return const_cast<LayerBaseClient*>(this); } - - virtual const char* getTypeId() const { return "LayerBaseClient"; } - -protected: - virtual void dump(String8& result, char* scratch, size_t size) const; - virtual void shortDump(String8& result, char* scratch, size_t size) const; - - /* - * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer) - * is called. - */ - class LayerCleaner { - sp<SurfaceFlinger> mFlinger; - wp<LayerBaseClient> mLayer; - protected: - ~LayerCleaner(); - public: - LayerCleaner(const sp<SurfaceFlinger>& flinger, - const sp<LayerBaseClient>& layer); - }; - -private: - virtual sp<ISurface> createSurface(); - - mutable Mutex mLock; - - // Set to true if an ISurface has been associated with this object. - mutable bool mHasSurface; - - // The ISurface's Binder object, set by getSurface(). - wp<IBinder> mClientSurfaceBinder; - - const wp<Client> mClientRef; -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_BASE_H diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp index 25caa0a..23decff 100644 --- a/services/surfaceflinger/LayerDim.cpp +++ b/services/surfaceflinger/LayerDim.cpp @@ -34,12 +34,10 @@ namespace android { // --------------------------------------------------------------------------- LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client) - : LayerBaseClient(flinger, client) -{ + : Layer(flinger, client) { } -LayerDim::~LayerDim() -{ +LayerDim::~LayerDim() { } void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const @@ -71,6 +69,25 @@ void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) con } } +sp<ISurface> LayerDim::createSurface() +{ + class BSurface : public BnSurface, public LayerCleaner { + virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; } + public: + BSurface(const sp<SurfaceFlinger>& flinger, + const sp<Layer>& layer) + : LayerCleaner(flinger, layer) { } + }; + sp<ISurface> sur(new BSurface(mFlinger, this)); + return sur; +} + +bool LayerDim::isVisible() const { + const Layer::State& s(drawingState()); + return !(s.flags & layer_state_t::eLayerHidden) && s.alpha; +} + + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h index 06f312d..e1ea9bd 100644 --- a/services/surfaceflinger/LayerDim.h +++ b/services/surfaceflinger/LayerDim.h @@ -23,13 +23,13 @@ #include <EGL/egl.h> #include <EGL/eglext.h> -#include "LayerBase.h" +#include "Layer.h" // --------------------------------------------------------------------------- namespace android { -class LayerDim : public LayerBaseClient +class LayerDim : public Layer { public: LayerDim(SurfaceFlinger* flinger, const sp<Client>& client); @@ -41,6 +41,10 @@ public: virtual bool isProtectedByApp() const { return false; } virtual bool isProtectedByDRM() const { return false; } virtual const char* getTypeId() const { return "LayerDim"; } + + virtual bool isFixedSize() const { return true; } + virtual bool isVisible() const; + virtual sp<ISurface> createSurface(); }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp deleted file mode 100644 index 3470d67..0000000 --- a/services/surfaceflinger/LayerScreenshot.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> - -#include "LayerScreenshot.h" -#include "SurfaceFlinger.h" -#include "DisplayDevice.h" - -namespace android { -// --------------------------------------------------------------------------- - -LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, - const sp<Client>& client) - : Layer(flinger, client) -{ -} - -void LayerScreenshot::onFirstRef() -{ - Layer::onFirstRef(); - - // FIXME: we currently hardcode the default display - // it's unclear what should we do instead. - sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); - mFlinger->captureScreenImplLocked(hw, getConsumer()->getBufferQueue(), - 0, 0, 0, 0x7FFFFFFF); -} - -// --------------------------------------------------------------------------- - -}; // namespace android diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h deleted file mode 100644 index a2ae03f..0000000 --- a/services/surfaceflinger/LayerScreenshot.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_LAYER_SCREENSHOT_H -#define ANDROID_LAYER_SCREENSHOT_H - -#include <stdint.h> -#include <sys/types.h> - -#include "Layer.h" - -// --------------------------------------------------------------------------- - -namespace android { - -class LayerScreenshot : public Layer -{ -public: - LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client); -protected: - virtual void onFirstRef(); -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_SCREENSHOT_H diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a0d2827..f1e9c65 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -62,7 +62,6 @@ #include "GLExtensions.h" #include "Layer.h" #include "LayerDim.h" -#include "LayerScreenshot.h" #include "SurfaceFlinger.h" #include "DisplayHardware/FramebufferSurface.h" @@ -581,17 +580,14 @@ bool SurfaceFlinger::authenticateSurfaceTexture( const LayerVector& currentLayers = mCurrentState.layersSortedByZ; size_t count = currentLayers.size(); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); - sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); - if (lbc != NULL) { - // If this is an instance of Layer (as opposed to, say, LayerDim), - // we will get the consumer interface of SurfaceFlingerConsumer's - // BufferQueue. If it's the same Binder object as the graphic - // buffer producer interface, return success. - wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); - if (lbcBinder == surfaceTextureBinder) { - return true; - } + const sp<Layer>& layer(currentLayers[i]); + // If this is an instance of Layer (as opposed to, say, LayerDim), + // we will get the consumer interface of SurfaceFlingerConsumer's + // BufferQueue. If it's the same Binder object as the graphic + // buffer producer interface, return success. + wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder(); + if (lbcBinder == surfaceTextureBinder) { + return true; } } @@ -604,13 +600,10 @@ bool SurfaceFlinger::authenticateSurfaceTexture( // should not cause any harm. size_t purgatorySize = mLayerPurgatory.size(); for (size_t i=0 ; i<purgatorySize ; i++) { - const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); - sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); - if (lbc != NULL) { - wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder(); - if (lbcBinder == surfaceTextureBinder) { - return true; - } + const sp<Layer>& layer(mLayerPurgatory.itemAt(i)); + wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder(); + if (lbcBinder == surfaceTextureBinder) { + return true; } } @@ -915,7 +908,7 @@ void SurfaceFlinger::rebuildLayerStacks() { for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { Region opaqueRegion; Region dirtyRegion; - Vector< sp<LayerBase> > layersSortedByZ; + Vector< sp<Layer> > layersSortedByZ; const sp<DisplayDevice>& hw(mDisplays[dpy]); const Transform& tr(hw->getTransform()); const Rect bounds(hw->getBounds()); @@ -925,7 +918,7 @@ void SurfaceFlinger::rebuildLayerStacks() { const size_t count = currentLayers.size(); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); const Layer::State& s(layer->drawingState()); if (s.layerStack == hw->getLayerStack()) { Region drawRegion(tr.transform( @@ -955,14 +948,14 @@ void SurfaceFlinger::setUpHWComposer() { sp<const DisplayDevice> hw(mDisplays[dpy]); const int32_t id = hw->getHwcDisplayId(); if (id >= 0) { - const Vector< sp<LayerBase> >& currentLayers( + const Vector< sp<Layer> >& currentLayers( hw->getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); if (hwc.createWorkList(id, count) == NO_ERROR) { HWComposer::LayerListIterator cur = hwc.begin(id); const HWComposer::LayerListIterator end = hwc.end(id); for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); layer->setGeometry(hw, *cur); if (mDebugDisableHWC || mDebugRegion) { cur->setSkip(true); @@ -978,7 +971,7 @@ void SurfaceFlinger::setUpHWComposer() { sp<const DisplayDevice> hw(mDisplays[dpy]); const int32_t id = hw->getHwcDisplayId(); if (id >= 0) { - const Vector< sp<LayerBase> >& currentLayers( + const Vector< sp<Layer> >& currentLayers( hw->getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); HWComposer::LayerListIterator cur = hwc.begin(id); @@ -988,7 +981,7 @@ void SurfaceFlinger::setUpHWComposer() { * update the per-frame h/w composer data for each layer * and build the transparent region of the FB */ - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); layer->setPerFrameData(hw, *cur); } } @@ -1042,7 +1035,7 @@ void SurfaceFlinger::postFramebuffer() for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { sp<const DisplayDevice> hw(mDisplays[dpy]); - const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ()); + const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ()); hw->onSwapBuffersCompleted(hwc); const size_t count = currentLayers.size(); int32_t id = hw->getHwcDisplayId(); @@ -1098,7 +1091,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) if (transactionFlags & eTraversalNeeded) { for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); if (!trFlags) continue; @@ -1245,8 +1238,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) // NOTE: we rely on the fact that layers are sorted by // layerStack first (so we don't have to traverse the list // of displays for every layer). - const sp<LayerBase>& layerBase(currentLayers[i]); - uint32_t layerStack = layerBase->drawingState().layerStack; + const sp<Layer>& layer(currentLayers[i]); + uint32_t layerStack = layer->drawingState().layerStack; if (i==0 || currentlayerStack != layerStack) { currentlayerStack = layerStack; // figure out if this layerstack is mirrored @@ -1268,7 +1261,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) if (disp != NULL) { // presumably this means this layer is using a layerStack // that is not visible on any display - layerBase->updateTransformHint(disp); + layer->updateTransformHint(disp); } } } @@ -1291,7 +1284,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) mVisibleRegionsDirty = true; const size_t count = previousLayers.size(); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(previousLayers[i]); + const sp<Layer>& layer(previousLayers[i]); if (currentLayers.indexOf(layer) < 0) { // this layer is not visible anymore // TODO: we could traverse the tree from front to back and @@ -1342,7 +1335,7 @@ void SurfaceFlinger::computeVisibleRegions( size_t i = currentLayers.size(); while (i--) { - const sp<LayerBase>& layer = currentLayers[i]; + const sp<Layer>& layer = currentLayers[i]; // start with the whole surface at its current location const Layer::State& s(layer->drawingState()); @@ -1485,7 +1478,7 @@ void SurfaceFlinger::handlePageFlip() const LayerVector& currentLayers(mDrawingState.layersSortedByZ); const size_t count = currentLayers.size(); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); const Region dirty(layer->latchBuffer(visibleRegions)); const Layer::State& s(layer->drawingState()); invalidateLayerStack(s.layerStack, dirty); @@ -1607,13 +1600,13 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const * and then, render the layers targeted at the framebuffer */ - const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); + const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); const size_t count = layers.size(); const Transform& tr = hw->getTransform(); if (cur != end) { // we're using h/w composer for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) { - const sp<LayerBase>& layer(layers[i]); + const sp<Layer>& layer(layers[i]); const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); if (!clip.isEmpty()) { switch (cur->getCompositionType()) { @@ -1645,7 +1638,7 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const } else { // we're not using h/w composer for (size_t i=0 ; i<count ; ++i) { - const sp<LayerBase>& layer(layers[i]); + const sp<Layer>& layer(layers[i]); const Region clip(dirty.intersect( tr.transform(layer->visibleRegion))); if (!clip.isEmpty()) { @@ -1684,7 +1677,7 @@ void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, void SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle, - const sp<LayerBaseClient>& lbc) + const sp<Layer>& lbc) { // attach this layer to the client client->attachLayer(handle, lbc); @@ -1694,7 +1687,7 @@ void SurfaceFlinger::addClientLayer(const sp<Client>& client, mCurrentState.layersSortedByZ.add(lbc); } -status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) +status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) { Mutex::Autolock _l(mStateLock); status_t err = purgatorizeLayer_l(layer); @@ -1703,9 +1696,9 @@ status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) return err; } -status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) +status_t SurfaceFlinger::removeLayer_l(const sp<Layer>& layer) { - ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); + ssize_t index = mCurrentState.layersSortedByZ.remove(layer); if (index >= 0) { mLayersRemoved = true; return NO_ERROR; @@ -1713,16 +1706,16 @@ status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) return status_t(index); } -status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) +status_t SurfaceFlinger::purgatorizeLayer_l(const sp<Layer>& layer) { // First add the layer to the purgatory list, which makes sure it won't // go away, then remove it from the main list (through a transaction). - ssize_t err = removeLayer_l(layerBase); + ssize_t err = removeLayer_l(layer); if (err >= 0) { - mLayerPurgatory.add(layerBase); + mLayerPurgatory.add(layer); } - mLayersPendingRemoval.push(layerBase); + mLayersPendingRemoval.push(layer); // it's possible that we don't find a layer, because it might // have been destroyed already -- this is not technically an error @@ -1873,7 +1866,7 @@ uint32_t SurfaceFlinger::setClientStateLocked( const layer_state_t& s) { uint32_t flags = 0; - sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); + sp<Layer> layer(client->getLayerUser(s.surface)); if (layer != 0) { const uint32_t what = s.what; if (what & layer_state_t::ePositionChanged) { @@ -1937,7 +1930,7 @@ sp<ISurface> SurfaceFlinger::createLayer( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { - sp<LayerBaseClient> layer; + sp<Layer> layer; sp<ISurface> surfaceHandle; if (int32_t(w|h) < 0) { @@ -1951,13 +1944,9 @@ sp<ISurface> SurfaceFlinger::createLayer( case ISurfaceComposerClient::eFXSurfaceNormal: layer = createNormalLayer(client, w, h, flags, format); break; - case ISurfaceComposerClient::eFXSurfaceBlur: case ISurfaceComposerClient::eFXSurfaceDim: layer = createDimLayer(client, w, h, flags); break; - case ISurfaceComposerClient::eFXSurfaceScreenshot: - layer = createScreenshotLayer(client, w, h, flags); - break; } if (layer != 0) { @@ -2015,15 +2004,6 @@ sp<LayerDim> SurfaceFlinger::createDimLayer( return layer; } -sp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer( - const sp<Client>& client, - uint32_t w, uint32_t h, uint32_t flags) -{ - sp<LayerScreenshot> layer = new LayerScreenshot(this, client); - layer->setBuffers(w, h, PIXEL_FORMAT_RGBA_8888, flags); - return layer; -} - status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle) { /* @@ -2037,7 +2017,7 @@ status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBind status_t err = NAME_NOT_FOUND; Mutex::Autolock _l(mStateLock); - sp<LayerBaseClient> layer = client->getLayerUser(handle); + sp<Layer> layer = client->getLayerUser(handle); if (layer != 0) { err = purgatorizeLayer_l(layer); @@ -2048,11 +2028,11 @@ status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBind return err; } -status_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer) +status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer) { // called by ~ISurface() when all references are gone status_t err = NO_ERROR; - sp<LayerBaseClient> l(layer.promote()); + sp<Layer> l(layer.promote()); if (l != NULL) { Mutex::Autolock _l(mStateLock); err = removeLayer_l(l); @@ -2269,7 +2249,7 @@ void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& inde const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const size_t count = currentLayers.size(); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); snprintf(buffer, SIZE, "%s\n", layer->getName().string()); result.append(buffer); } @@ -2294,7 +2274,7 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const size_t count = currentLayers.size(); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); if (name == layer->getName()) { layer->dumpStats(result, buffer, SIZE); } @@ -2314,7 +2294,7 @@ void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& inde const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const size_t count = currentLayers.size(); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); if (name.isEmpty() || (name == layer->getName())) { layer->clearStats(); } @@ -2370,7 +2350,7 @@ void SurfaceFlinger::dumpAllLocked( snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); result.append(buffer); for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer(currentLayers[i]); + const sp<Layer>& layer(currentLayers[i]); layer->dump(result, buffer, SIZE); } @@ -2382,7 +2362,7 @@ void SurfaceFlinger::dumpAllLocked( snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); result.append(buffer); for (size_t i=0 ; i<purgatorySize ; i++) { - const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); + const sp<Layer>& layer(mLayerPurgatory.itemAt(i)); layer->shortDump(result, buffer, SIZE); } @@ -2471,7 +2451,7 @@ void SurfaceFlinger::dumpAllLocked( alloc.dump(result); } -const Vector< sp<LayerBase> >& +const Vector< sp<Layer> >& SurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) { // Note: mStateLock is held here return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ(); @@ -2728,10 +2708,10 @@ status_t SurfaceFlinger::captureScreenImplLocked( glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); - const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ()); + const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { - const sp<LayerBase>& layer(layers[i]); + const sp<Layer>& layer(layers[i]); const uint32_t z = layer->drawingState().z; if (z >= minLayerZ && z <= maxLayerZ) { if (filtering) layer->setFiltering(true); @@ -2896,15 +2876,15 @@ SurfaceFlinger::LayerVector::LayerVector() { } SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) - : SortedVector<sp<LayerBase> >(rhs) { + : SortedVector<sp<Layer> >(rhs) { } int SurfaceFlinger::LayerVector::do_compare(const void* lhs, const void* rhs) const { // sort layers per layer-stack, then by z-order and finally by sequence - const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs)); - const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs)); + const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs)); + const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs)); uint32_t ls = l->currentState().layerStack; uint32_t rs = r->currentState().layerStack; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index d1221dc..241a7d6 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -60,10 +60,7 @@ class DisplayEventConnection; class EventThread; class IGraphicBufferAlloc; class Layer; -class LayerBase; -class LayerBaseClient; class LayerDim; -class LayerScreenshot; class Surface; // --------------------------------------------------------------------------- @@ -125,15 +122,12 @@ public: // for debugging only // TODO: this should be made accessible only to HWComposer - const Vector< sp<LayerBase> >& getLayerSortedByZForHwcDisplay(int disp); + const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int disp); private: friend class Client; friend class DisplayEventConnection; - friend class LayerBase; - friend class LayerBaseClient; friend class Layer; - friend class LayerScreenshot; // We're reference counted, never destroy SurfaceFlinger directly virtual ~SurfaceFlinger(); @@ -142,7 +136,7 @@ private: * Internal data structures */ - class LayerVector : public SortedVector<sp<LayerBase> > { + class LayerVector : public SortedVector< sp<Layer> > { public: LayerVector(); LayerVector(const LayerVector& rhs); @@ -272,9 +266,6 @@ private: sp<LayerDim> createDimLayer(const sp<Client>& client, uint32_t w, uint32_t h, uint32_t flags); - sp<LayerScreenshot> createScreenshotLayer(const sp<Client>& client, - uint32_t w, uint32_t h, uint32_t flags); - // called in response to the window-manager calling // ISurfaceComposerClient::destroySurface() // The specified layer is first placed in a purgatory list @@ -284,17 +275,17 @@ private: // called when all clients have released all their references to // this layer meaning it is entirely safe to destroy all // resources associated to this layer. - status_t onLayerDestroyed(const wp<LayerBaseClient>& layer); + status_t onLayerDestroyed(const wp<Layer>& layer); // remove a layer from SurfaceFlinger immediately - status_t removeLayer(const sp<LayerBase>& layer); + status_t removeLayer(const sp<Layer>& layer); // add a layer to SurfaceFlinger void addClientLayer(const sp<Client>& client, const sp<IBinder>& handle, - const sp<LayerBaseClient>& lbc); + const sp<Layer>& lbc); - status_t removeLayer_l(const sp<LayerBase>& layer); - status_t purgatorizeLayer_l(const sp<LayerBase>& layer); + status_t removeLayer_l(const sp<Layer>& layer); + status_t purgatorizeLayer_l(const sp<Layer>& layer); /* ------------------------------------------------------------------------ * Boot animation, on/off animations and screen capture @@ -408,10 +399,10 @@ private: State mCurrentState; volatile int32_t mTransactionFlags; Condition mTransactionCV; - SortedVector<sp<LayerBase> > mLayerPurgatory; + SortedVector< sp<Layer> > mLayerPurgatory; bool mTransactionPending; bool mAnimTransactionPending; - Vector<sp<LayerBase> > mLayersPendingRemoval; + Vector< sp<Layer> > mLayersPendingRemoval; // protected by mStateLock (but we could use another lock) bool mLayersRemoved; @@ -460,7 +451,7 @@ private: // protected by mDestroyedLayerLock; mutable Mutex mDestroyedLayerLock; - Vector<LayerBase const *> mDestroyedLayers; + Vector<Layer const *> mDestroyedLayers; /* ------------------------------------------------------------------------ * Feature prototyping |