From 089a15298e045598bf15fd2a46284c34dd56384c Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 Mar 2013 14:51:39 -0800 Subject: Remove support for ScreenshotLayer Change-Id: I5b571a4cf3faa77d2c4aca916fa4bd00a1065bb9 --- include/gui/ISurfaceComposerClient.h | 2 -- services/surfaceflinger/Android.mk | 1 - services/surfaceflinger/LayerBase.h | 3 +- services/surfaceflinger/LayerScreenshot.cpp | 47 ----------------------------- services/surfaceflinger/LayerScreenshot.h | 41 ------------------------- services/surfaceflinger/SurfaceFlinger.cpp | 14 --------- services/surfaceflinger/SurfaceFlinger.h | 5 --- 7 files changed, 1 insertion(+), 112 deletions(-) delete mode 100644 services/surfaceflinger/LayerScreenshot.cpp delete mode 100644 services/surfaceflinger/LayerScreenshot.h 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..4f6cf85 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -9,7 +9,6 @@ LOCAL_SRC_FILES:= \ Layer.cpp \ LayerBase.cpp \ LayerDim.cpp \ - LayerScreenshot.cpp \ DisplayHardware/FramebufferSurface.cpp \ DisplayHardware/HWComposer.cpp \ DisplayHardware/PowerHAL.cpp \ diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index ecae2d9..33de5fe 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -58,8 +58,7 @@ class SurfaceFlinger; * 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. + * Notable subclasses (below LayerBaseClient) include Layer and LayerDim. */ class LayerBase : virtual public RefBase { 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 -#include -#include - -#include "LayerScreenshot.h" -#include "SurfaceFlinger.h" -#include "DisplayDevice.h" - -namespace android { -// --------------------------------------------------------------------------- - -LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, - const sp& 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 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 -#include - -#include "Layer.h" - -// --------------------------------------------------------------------------- - -namespace android { - -class LayerScreenshot : public Layer -{ -public: - LayerScreenshot(SurfaceFlinger* flinger, const sp& 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 8fa0800..1a966dc 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" @@ -1951,13 +1950,9 @@ sp 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 +2010,6 @@ sp SurfaceFlinger::createDimLayer( return layer; } -sp SurfaceFlinger::createScreenshotLayer( - const sp& client, - uint32_t w, uint32_t h, uint32_t flags) -{ - sp layer = new LayerScreenshot(this, client); - layer->setBuffers(w, h, PIXEL_FORMAT_RGBA_8888, flags); - return layer; -} - status_t SurfaceFlinger::onLayerRemoved(const sp& client, const sp& handle) { /* diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index d1221dc..0475835 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -63,7 +63,6 @@ class Layer; class LayerBase; class LayerBaseClient; class LayerDim; -class LayerScreenshot; class Surface; // --------------------------------------------------------------------------- @@ -133,7 +132,6 @@ private: friend class LayerBase; friend class LayerBaseClient; friend class Layer; - friend class LayerScreenshot; // We're reference counted, never destroy SurfaceFlinger directly virtual ~SurfaceFlinger(); @@ -272,9 +270,6 @@ private: sp createDimLayer(const sp& client, uint32_t w, uint32_t h, uint32_t flags); - sp createScreenshotLayer(const sp& 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 -- cgit v1.1 From b79f61d41ef053bee1087ec612896c59f95f9686 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 Mar 2013 15:14:58 -0800 Subject: fold LayerBaseClient into LayerBase Change-Id: Ic745136522df59c42f0885fd969e75ea55d09f01 --- services/surfaceflinger/Client.cpp | 12 ++-- services/surfaceflinger/Client.h | 10 +-- services/surfaceflinger/Layer.cpp | 18 ++--- services/surfaceflinger/Layer.h | 4 +- services/surfaceflinger/LayerBase.cpp | 69 +++++++------------ services/surfaceflinger/LayerBase.h | 102 +++++++++++------------------ services/surfaceflinger/LayerDim.cpp | 2 +- services/surfaceflinger/LayerDim.h | 2 +- services/surfaceflinger/SurfaceFlinger.cpp | 38 +++++------ services/surfaceflinger/SurfaceFlinger.h | 6 +- 10 files changed, 104 insertions(+), 159 deletions(-) diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 0f56f99..287b330 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -43,7 +43,7 @@ Client::~Client() { const size_t count = mLayers.size(); for (size_t i=0 ; i layer(mLayers.valueAt(i).promote()); + sp layer(mLayers.valueAt(i).promote()); if (layer != 0) { mFlinger->removeLayer(layer); } @@ -54,13 +54,13 @@ status_t Client::initCheck() const { return NO_ERROR; } -void Client::attachLayer(const sp& handle, const sp& layer) +void Client::attachLayer(const sp& handle, const sp& layer) { Mutex::Autolock _l(mLock); mLayers.add(handle, layer); } -void Client::detachLayer(const LayerBaseClient* layer) +void Client::detachLayer(const LayerBase* layer) { Mutex::Autolock _l(mLock); // we do a linear search here, because this doesn't happen often @@ -72,11 +72,11 @@ void Client::detachLayer(const LayerBaseClient* layer) } } } -sp Client::getLayerUser(const sp& handle) const +sp Client::getLayerUser(const sp& handle) const { Mutex::Autolock _l(mLock); - sp lbc; - wp layer(mLayers.valueFor(handle)); + sp lbc; + wp 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..43f8fb7 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -30,7 +30,7 @@ namespace android { // --------------------------------------------------------------------------- -class LayerBaseClient; +class LayerBase; class SurfaceFlinger; // --------------------------------------------------------------------------- @@ -44,11 +44,11 @@ public: status_t initCheck() const; // protected by SurfaceFlinger::mStateLock - void attachLayer(const sp& handle, const sp& layer); + void attachLayer(const sp& handle, const sp& layer); - void detachLayer(const LayerBaseClient* layer); + void detachLayer(const LayerBase* layer); - sp getLayerUser(const sp& handle) const; + sp getLayerUser(const sp& handle) const; private: // ISurfaceComposerClient interface @@ -66,7 +66,7 @@ private: sp mFlinger; // protected by mLock - DefaultKeyedVector< wp, wp > mLayers; + DefaultKeyedVector< wp, wp > mLayers; // thread-safe mutable Mutex mLock; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index c9f1eb5..6245b6b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -50,7 +50,7 @@ namespace android { // --------------------------------------------------------------------------- Layer::Layer(SurfaceFlinger* flinger, const sp& client) - : LayerBaseClient(flinger, client), + : LayerBase(flinger, client), mTextureName(-1U), mQueuedFrames(0), mCurrentTransform(0), @@ -70,7 +70,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp& client) void Layer::onLayerDisplayed(const sp& hw, HWComposer::HWCLayerInterface* layer) { - LayerBaseClient::onLayerDisplayed(hw, layer); + LayerBase::onLayerDisplayed(hw, layer); if (layer) { mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd()); } @@ -78,7 +78,7 @@ void Layer::onLayerDisplayed(const sp& hw, void Layer::onFirstRef() { - LayerBaseClient::onFirstRef(); + LayerBase::onFirstRef(); // Creates a custom BufferQueue for SurfaceFlingerConsumer to use sp bq = new SurfaceTextureLayer(); @@ -224,7 +224,7 @@ void Layer::setGeometry( const sp& hw, HWComposer::HWCLayerInterface& layer) { - LayerBaseClient::setGeometry(hw, layer); + LayerBase::setGeometry(hw, layer); // enable this layer layer.setSkip(false); @@ -260,7 +260,7 @@ void Layer::setGeometry( void Layer::setPerFrameData(const sp& hw, HWComposer::HWCLayerInterface& layer) { - LayerBaseClient::setPerFrameData(hw, layer); + LayerBase::setPerFrameData(hw, layer); // NOTE: buffer can be NULL if the client never drew into this // layer yet, or if we ran out of memory layer.setBuffer(mActiveBuffer); @@ -528,7 +528,7 @@ void Layer::onPostComposition() { } bool Layer::isVisible() const { - return LayerBaseClient::isVisible() && (mActiveBuffer != NULL); + return LayerBase::isVisible() && (mActiveBuffer != NULL); } Region Layer::latchBuffer(bool& recomputeVisibleRegions) @@ -704,7 +704,7 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) void Layer::dump(String8& result, char* buffer, size_t SIZE) const { - LayerBaseClient::dump(result, buffer, SIZE); + LayerBase::dump(result, buffer, SIZE); sp buf0(mActiveBuffer); uint32_t w0=0, h0=0, s0=0, f0=0; @@ -730,13 +730,13 @@ 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); + LayerBase::dumpStats(result, buffer, SIZE); mFrameTracker.dump(result); } void Layer::clearStats() { - LayerBaseClient::clearStats(); + LayerBase::clearStats(); mFrameTracker.clear(); } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index e57fb59..25afeef 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -55,7 +55,7 @@ class GLExtensions; * This also implements onFrameAvailable(), which notifies SurfaceFlinger * that new data has arrived. */ -class Layer : public LayerBaseClient, +class Layer : public LayerBase, public SurfaceFlingerConsumer::FrameAvailableListener { public: @@ -93,7 +93,7 @@ public: virtual void setName(const String8& name); virtual bool isVisible() const; - // LayerBaseClient interface + // LayerBase interface virtual wp getSurfaceTextureBinder() const; // only for debugging diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index db2b20e..6f9ad4c 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -42,18 +42,24 @@ namespace android { int32_t LayerBase::sSequence = 1; -LayerBase::LayerBase(SurfaceFlinger* flinger) +LayerBase::LayerBase(SurfaceFlinger* flinger, const sp& client) : contentDirty(false), sequence(uint32_t(android_atomic_inc(&sSequence))), mFlinger(flinger), mFiltering(false), mNeedsFiltering(false), mTransactionFlags(0), - mPremultipliedAlpha(true), mName("unnamed"), mDebug(false) + mPremultipliedAlpha(true), mName("unnamed"), mDebug(false), + mHasSurface(false), + mClientRef(client) { } LayerBase::~LayerBase() { + sp c(mClientRef.promote()); + if (c != 0) { + c->detachLayer(this); + } } void LayerBase::setName(const String8& name) { @@ -542,19 +548,22 @@ void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const s.transparentRegion.dump(result, "transparentRegion"); visibleRegion.dump(result, "visibleRegion"); + sp client(mClientRef.promote()); 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", + "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(), needsDithering(), contentDirty, s.alpha, s.flags, s.transform[0][0], s.transform[0][1], - s.transform[1][0], s.transform[1][1]); + s.transform[1][0], s.transform[1][1], + client.get()); result.append(buffer); } @@ -568,52 +577,32 @@ void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const { void LayerBase::clearStats() { } -sp LayerBase::getLayerBaseClient() const { - return 0; -} - sp LayerBase::getLayer() const { return 0; } // --------------------------------------------------------------------------- -LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, - const sp& client) - : LayerBase(flinger), - mHasSurface(false), - mClientRef(client) -{ -} - -LayerBaseClient::~LayerBaseClient() -{ - sp c(mClientRef.promote()); - if (c != 0) { - c->detachLayer(this); - } -} - -sp LayerBaseClient::createSurface() +sp LayerBase::createSurface() { class BSurface : public BnSurface, public LayerCleaner { virtual sp getSurfaceTexture() const { return 0; } public: BSurface(const sp& flinger, - const sp& layer) + const sp& layer) : LayerCleaner(flinger, layer) { } }; sp sur(new BSurface(mFlinger, this)); return sur; } -sp LayerBaseClient::getSurface() +sp LayerBase::getSurface() { sp s; Mutex::Autolock _l(mLock); LOG_ALWAYS_FATAL_IF(mHasSurface, - "LayerBaseClient::getSurface() has already been called"); + "LayerBase::getSurface() has already been called"); mHasSurface = true; s = createSurface(); @@ -621,36 +610,22 @@ sp LayerBaseClient::getSurface() return s; } -wp LayerBaseClient::getSurfaceBinder() const { +wp LayerBase::getSurfaceBinder() const { return mClientSurfaceBinder; } -wp LayerBaseClient::getSurfaceTextureBinder() const { +wp LayerBase::getSurfaceTextureBinder() const { return 0; } -void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const -{ - LayerBase::dump(result, buffer, SIZE); - sp 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& flinger, - const sp& layer) +LayerBase::LayerCleaner::LayerCleaner(const sp& flinger, + const sp& layer) : mFlinger(flinger), mLayer(layer) { } -LayerBaseClient::LayerCleaner::~LayerCleaner() { +LayerBase::LayerCleaner::~LayerCleaner() { // destroy client resources mFlinger->onLayerDestroyed(mLayer); } diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index 33de5fe..01d82d4 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -44,7 +44,6 @@ class Client; class DisplayDevice; class GraphicBuffer; class Layer; -class LayerBaseClient; class SurfaceFlinger; // --------------------------------------------------------------------------- @@ -57,15 +56,25 @@ class SurfaceFlinger; * 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 and LayerDim. */ class LayerBase : virtual public RefBase { static int32_t sSequence; public: - LayerBase(SurfaceFlinger* flinger); + LayerBase(SurfaceFlinger* flinger, const sp& client); + + + // Creates an ISurface associated with this object. This may only be + // called once (see also getSurfaceBinder()). + sp getSurface(); + + // Returns the Binder object for the ISurface associated with + // this object. + wp getSurfaceBinder() const; + + virtual wp getSurfaceTextureBinder() const; + mutable bool contentDirty; // regions below are in window-manager space @@ -138,7 +147,6 @@ public: Rect computeBounds() const; - virtual sp getLayerBaseClient() const; virtual sp getLayer() const; virtual const char* getTypeId() const { return "LayerBase"; } @@ -294,6 +302,8 @@ public: bool getFiltering() const; private: + virtual sp createSurface(); + Rect computeCrop(const sp& hw) const; protected: @@ -301,6 +311,23 @@ protected: GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const; void drawWithOpenGL(const sp& hw, const Region& clip) const; + + /* + * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer) + * is called. + */ + class LayerCleaner { + sp mFlinger; + wp mLayer; + protected: + ~LayerCleaner(); + public: + LayerCleaner(const sp& flinger, + const sp& layer); + }; + + + sp mFlinger; private: @@ -323,64 +350,7 @@ protected: 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); - - virtual ~LayerBaseClient(); - - // Creates an ISurface associated with this object. This may only be - // called once (see also getSurfaceBinder()). - sp getSurface(); - - // Returns the Binder object for the ISurface associated with - // this object. - wp getSurfaceBinder() const; - - virtual wp getSurfaceTextureBinder() const; - - virtual sp getLayerBaseClient() const { - return const_cast(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 mFlinger; - wp mLayer; - protected: - ~LayerCleaner(); - public: - LayerCleaner(const sp& flinger, - const sp& layer); - }; - -private: - virtual sp createSurface(); mutable Mutex mLock; @@ -391,6 +361,14 @@ private: wp mClientSurfaceBinder; const wp mClientRef; + + +public: + // called from class SurfaceFlinger + virtual ~LayerBase(); + +private: + LayerBase(const LayerBase& rhs); }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp index 25caa0a..24ad706 100644 --- a/services/surfaceflinger/LayerDim.cpp +++ b/services/surfaceflinger/LayerDim.cpp @@ -34,7 +34,7 @@ namespace android { // --------------------------------------------------------------------------- LayerDim::LayerDim(SurfaceFlinger* flinger, const sp& client) - : LayerBaseClient(flinger, client) + : LayerBase(flinger, client) { } diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h index 06f312d..5cdfafc 100644 --- a/services/surfaceflinger/LayerDim.h +++ b/services/surfaceflinger/LayerDim.h @@ -29,7 +29,7 @@ namespace android { -class LayerDim : public LayerBaseClient +class LayerDim : public LayerBase { public: LayerDim(SurfaceFlinger* flinger, const sp& client); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 1a966dc..5ef22ae 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -581,16 +581,13 @@ bool SurfaceFlinger::authenticateSurfaceTexture( size_t count = currentLayers.size(); for (size_t i=0 ; i& layer(currentLayers[i]); - sp 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 lbcBinder = lbc->getSurfaceTextureBinder(); - if (lbcBinder == surfaceTextureBinder) { - return true; - } + // 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 lbcBinder = layer->getSurfaceTextureBinder(); + if (lbcBinder == surfaceTextureBinder) { + return true; } } @@ -604,12 +601,9 @@ bool SurfaceFlinger::authenticateSurfaceTexture( size_t purgatorySize = mLayerPurgatory.size(); for (size_t i=0 ; i& layer(mLayerPurgatory.itemAt(i)); - sp lbc(layer->getLayerBaseClient()); - if (lbc != NULL) { - wp lbcBinder = lbc->getSurfaceTextureBinder(); - if (lbcBinder == surfaceTextureBinder) { - return true; - } + wp lbcBinder = layer->getSurfaceTextureBinder(); + if (lbcBinder == surfaceTextureBinder) { + return true; } } @@ -1683,7 +1677,7 @@ void SurfaceFlinger::drawWormhole(const sp& hw, void SurfaceFlinger::addClientLayer(const sp& client, const sp& handle, - const sp& lbc) + const sp& lbc) { // attach this layer to the client client->attachLayer(handle, lbc); @@ -1872,7 +1866,7 @@ uint32_t SurfaceFlinger::setClientStateLocked( const layer_state_t& s) { uint32_t flags = 0; - sp layer(client->getLayerUser(s.surface)); + sp layer(client->getLayerUser(s.surface)); if (layer != 0) { const uint32_t what = s.what; if (what & layer_state_t::ePositionChanged) { @@ -1936,7 +1930,7 @@ sp SurfaceFlinger::createLayer( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { - sp layer; + sp layer; sp surfaceHandle; if (int32_t(w|h) < 0) { @@ -2023,7 +2017,7 @@ status_t SurfaceFlinger::onLayerRemoved(const sp& client, const sp layer = client->getLayerUser(handle); + sp layer = client->getLayerUser(handle); if (layer != 0) { err = purgatorizeLayer_l(layer); @@ -2034,11 +2028,11 @@ status_t SurfaceFlinger::onLayerRemoved(const sp& client, const sp& layer) +status_t SurfaceFlinger::onLayerDestroyed(const wp& layer) { // called by ~ISurface() when all references are gone status_t err = NO_ERROR; - sp l(layer.promote()); + sp l(layer.promote()); if (l != NULL) { Mutex::Autolock _l(mStateLock); err = removeLayer_l(l); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 0475835..1f63b42 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -61,7 +61,6 @@ class EventThread; class IGraphicBufferAlloc; class Layer; class LayerBase; -class LayerBaseClient; class LayerDim; class Surface; @@ -130,7 +129,6 @@ private: friend class Client; friend class DisplayEventConnection; friend class LayerBase; - friend class LayerBaseClient; friend class Layer; // We're reference counted, never destroy SurfaceFlinger directly @@ -279,14 +277,14 @@ 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& layer); + status_t onLayerDestroyed(const wp& layer); // remove a layer from SurfaceFlinger immediately status_t removeLayer(const sp& layer); // add a layer to SurfaceFlinger void addClientLayer(const sp& client, const sp& handle, - const sp& lbc); + const sp& lbc); status_t removeLayer_l(const sp& layer); status_t purgatorizeLayer_l(const sp& layer); -- cgit v1.1 From 2f73af9212487c81d31d07227fa8a2f4abc77638 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 Mar 2013 15:50:58 -0800 Subject: Make LayerDim a regular Layer instead of a LayerBase this is in preparation to get rid of LayerBase entirely Change-Id: Ia051949fc5205fd87371331145356ee11598a597 --- services/surfaceflinger/Layer.h | 2 +- services/surfaceflinger/LayerDim.cpp | 21 ++++++++++++++++++++- services/surfaceflinger/LayerDim.h | 8 ++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 25afeef..e9eab17 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -68,7 +68,7 @@ public: status_t setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags=0); - bool isFixedSize() const; + virtual bool isFixedSize() const; // LayerBase interface virtual void setGeometry(const sp& hw, diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp index 24ad706..f8c4139 100644 --- a/services/surfaceflinger/LayerDim.cpp +++ b/services/surfaceflinger/LayerDim.cpp @@ -34,7 +34,7 @@ namespace android { // --------------------------------------------------------------------------- LayerDim::LayerDim(SurfaceFlinger* flinger, const sp& client) - : LayerBase(flinger, client) + : Layer(flinger, client) { } @@ -71,6 +71,25 @@ void LayerDim::onDraw(const sp& hw, const Region& clip) con } } +sp LayerDim::createSurface() +{ + class BSurface : public BnSurface, public LayerCleaner { + virtual sp getSurfaceTexture() const { return 0; } + public: + BSurface(const sp& flinger, + const sp& layer) + : LayerCleaner(flinger, layer) { } + }; + sp sur(new BSurface(mFlinger, this)); + return sur; +} + +bool LayerDim::isVisible() const { + const Layer::State& s(mDrawingState); + return !(s.flags & layer_state_t::eLayerHidden) && s.alpha; +} + + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h index 5cdfafc..e1ea9bd 100644 --- a/services/surfaceflinger/LayerDim.h +++ b/services/surfaceflinger/LayerDim.h @@ -23,13 +23,13 @@ #include #include -#include "LayerBase.h" +#include "Layer.h" // --------------------------------------------------------------------------- namespace android { -class LayerDim : public LayerBase +class LayerDim : public Layer { public: LayerDim(SurfaceFlinger* flinger, const sp& 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 createSurface(); }; // --------------------------------------------------------------------------- -- cgit v1.1 From 13127d8921356dff794250e04208c3ed60b3a3df Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 5 Mar 2013 17:47:11 -0800 Subject: Get rid of LayerBase. The functionality of LayerBase and Layer is folded into Layer. There wasn't a need for this abstraction anymore. Change-Id: I66511c08cc3d89009ba4deabf47e26cd4cfeaefb --- services/surfaceflinger/Android.mk | 1 - services/surfaceflinger/Client.cpp | 13 +- services/surfaceflinger/Client.h | 10 +- services/surfaceflinger/DisplayDevice.cpp | 8 +- services/surfaceflinger/DisplayDevice.h | 8 +- .../surfaceflinger/DisplayHardware/HWComposer.cpp | 15 +- .../surfaceflinger/DisplayHardware/HWComposer.h | 1 - services/surfaceflinger/Layer.cpp | 683 ++++++++++++++++++--- services/surfaceflinger/Layer.h | 311 +++++++++- services/surfaceflinger/LayerBase.cpp | 635 ------------------- services/surfaceflinger/LayerBase.h | 378 ------------ services/surfaceflinger/LayerDim.cpp | 10 +- services/surfaceflinger/SurfaceFlinger.cpp | 86 +-- services/surfaceflinger/SurfaceFlinger.h | 22 +- 14 files changed, 943 insertions(+), 1238 deletions(-) delete mode 100644 services/surfaceflinger/LayerBase.cpp delete mode 100644 services/surfaceflinger/LayerBase.h diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 4f6cf85..5ff8154 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -7,7 +7,6 @@ LOCAL_SRC_FILES:= \ EventThread.cpp \ FrameTracker.cpp \ Layer.cpp \ - LayerBase.cpp \ LayerDim.cpp \ DisplayHardware/FramebufferSurface.cpp \ DisplayHardware/HWComposer.cpp \ diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 287b330..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 layer(mLayers.valueAt(i).promote()); + sp 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& handle, const sp& layer) +void Client::attachLayer(const sp& handle, const sp& layer) { Mutex::Autolock _l(mLock); mLayers.add(handle, layer); } -void Client::detachLayer(const LayerBase* 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 LayerBase* layer) } } } -sp Client::getLayerUser(const sp& handle) const +sp Client::getLayerUser(const sp& handle) const { Mutex::Autolock _l(mLock); - sp lbc; - wp layer(mLayers.valueFor(handle)); + sp lbc; + wp 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 43f8fb7..4f34b86 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -30,7 +30,7 @@ namespace android { // --------------------------------------------------------------------------- -class LayerBase; +class Layer; class SurfaceFlinger; // --------------------------------------------------------------------------- @@ -44,11 +44,11 @@ public: status_t initCheck() const; // protected by SurfaceFlinger::mStateLock - void attachLayer(const sp& handle, const sp& layer); + void attachLayer(const sp& handle, const sp& layer); - void detachLayer(const LayerBase* layer); + void detachLayer(const Layer* layer); - sp getLayerUser(const sp& handle) const; + sp getLayerUser(const sp& handle) const; private: // ISurfaceComposerClient interface @@ -66,7 +66,7 @@ private: sp mFlinger; // protected by mLock - DefaultKeyedVector< wp, wp > mLayers; + DefaultKeyedVector< wp, wp > 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& hw) // ---------------------------------------------------------------------------- -void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp >& layers) { +void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp >& layers) { mVisibleLayersSortedByZ = layers; mSecureLayerVisible = false; size_t count = layers.size(); for (size_t i=0 ; i& layer(layers[i]); + const sp& layer(layers[i]); if (layer->isSecure()) { mSecureLayerVisible = true; } } } -const Vector< sp >& DisplayDevice::getVisibleLayersSortedByZ() const { +const Vector< sp >& 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 >& layers); - const Vector< sp >& getVisibleLayersSortedByZ() const; + void setVisibleLayersSortedByZ(const Vector< sp >& layers); + const Vector< sp >& getVisibleLayersSortedByZ() const; bool getSecureLayerVisible() const; Region getDirtyRegion(bool repaintEverything) const; @@ -186,7 +186,7 @@ private: */ // list of visible layers on that display - Vector< sp > mVisibleLayersSortedByZ; + Vector< sp > 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 #include "Layer.h" // needed only for debugging -#include "LayerBase.h" #include "HWComposer.h" #include "SurfaceFlinger.h" #include @@ -925,7 +924,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const { for (size_t i=0 ; i >& visibleLayersSortedByZ = + const Vector< sp >& 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& layer(visibleLayersSortedByZ[i]); - if (layer->getLayer() != NULL) { - const sp& buffer( - layer->getLayer()->getActiveBuffer()); - if (buffer != NULL) { - format = buffer->getPixelFormat(); - } + const sp& layer(visibleLayersSortedByZ[i]); + const sp& 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 6245b6b..44ef0b8 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -49,37 +50,39 @@ namespace android { // --------------------------------------------------------------------------- +int32_t Layer::sSequence = 1; + Layer::Layer(SurfaceFlinger* flinger, const sp& client) - : LayerBase(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& hw, - HWComposer::HWCLayerInterface* layer) { - LayerBase::onLayerDisplayed(hw, layer); - if (layer) { - mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd()); - } -} - void Layer::onFirstRef() { - LayerBase::onFirstRef(); - // Creates a custom BufferQueue for SurfaceFlingerConsumer to use sp bq = new SurfaceTextureLayer(); mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true, @@ -102,9 +105,25 @@ void Layer::onFirstRef() Layer::~Layer() { + sp c(mClientRef.promote()); + if (c != 0) { + c->detachLayer(this); + } mFlinger->deleteTextureAsync(mTextureName); } +// --------------------------------------------------------------------------- +// callbacks +// --------------------------------------------------------------------------- + +void Layer::onLayerDisplayed(const sp& 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 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 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 Layer::createSurface() return sur; } -wp Layer::getSurfaceTextureBinder() const -{ +wp Layer::getSurfaceTextureBinder() const { return mSurfaceFlingerConsumer->getBufferQueue()->asBinder(); } -status_t Layer::setBuffers( uint32_t w, uint32_t h, - PixelFormat format, uint32_t flags) +sp Layer::getSurface() { - // this surfaces pixel format - PixelFormatInfo info; - status_t err = getPixelFormatInfo(format, &info); - if (err) { - ALOGE("unsupported pixelformat %d", format); - return err; - } + sp 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& 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& hw, HWComposer::HWCLayerInterface& layer) { - LayerBase::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& hw, HWComposer::HWCLayerInterface& layer) { - LayerBase::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& hw, layer.setAcquireFenceFd(fenceFd); } +// --------------------------------------------------------------------------- +// drawing... +// --------------------------------------------------------------------------- + +void Layer::draw(const sp& hw, const Region& clip) const { + onDraw(hw, clip); +} + +void Layer::draw(const sp& hw) { + onDraw( hw, Region(hw->bounds()) ); +} + void Layer::onDraw(const sp& hw, const Region& clip) const { ATRACE_CALL(); @@ -304,8 +476,8 @@ void Layer::onDraw(const sp& hw, const Region& clip) const mFlinger->mDrawingState.layersSortedByZ); const size_t count = drawingLayers.size(); for (size_t i=0 ; i& layer(drawingLayers[i]); - if (layer.get() == static_cast(this)) + const sp& layer(drawingLayers[i]); + if (layer.get() == static_cast(this)) break; under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); } @@ -365,6 +537,119 @@ void Layer::onDraw(const sp& hw, const Region& clip) const glDisable(GL_TEXTURE_2D); } + +void Layer::clearWithOpenGL(const sp& 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& hw, const Region& clip) const { + clearWithOpenGL(hw, clip, 0,0,0,0); +} + +void Layer::drawWithOpenGL( + const sp& 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& 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& 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 LayerBase::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& 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 { - LayerBase::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(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 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 -{ - LayerBase::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() -{ - LayerBase::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& flinger, + const sp& layer) + : mFlinger(flinger), mLayer(layer) { } -void Layer::updateTransformHint(const sp& 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 e9eab17..5fb6d8b 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -20,118 +20,356 @@ #include #include +#include +#include +#include +#include + +#include +#include #include #include #include +#include #include -#include -#include -#include -#include +#include -#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 LayerBase, - 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); 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); - virtual bool isFixedSize() const; + // Creates an ISurface associated with this object. This may only be + // called once. to provide your own ISurface, override createSurface(). + sp 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& 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& hw, HWComposer::HWCLayerInterface& layer); virtual void setPerFrameData(const sp& hw, HWComposer::HWCLayerInterface& layer); virtual void setAcquireFence(const sp& hw, HWComposer::HWCLayerInterface& layer); + + /* + * called after page-flip + */ virtual void onLayerDisplayed(const sp& 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& hw, const Region& clip) const; + virtual void draw(const sp& hw); + + /* + * onDraw - draws the surface. + */ virtual void onDraw(const sp& hw, const Region& clip) const; + + /* + * needsLinearFiltering - true if this surface's state requires filtering + */ + virtual bool needsFiltering(const sp& 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 getLayer() const { return const_cast(this); } - virtual void setName(const String8& name); + + /* + * isVisible - true if this layer is visible, false otherwise + */ virtual bool isVisible() const; - // LayerBase interface - virtual wp 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& getActiveBuffer() const { return mActiveBuffer; } + + virtual wp getSurfaceTextureBinder() const; // Updates the transform hint in our SurfaceFlingerConsumer to match // the current orientation of the display device. virtual void updateTransformHint(const sp& 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& hw, const Region& clip) const; + void setFiltering(bool filtering); + bool getFiltering() const; + + // only for debugging + inline const sp& 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 getConsumer() const { - return mSurfaceFlingerConsumer; - } +protected: + // constant + sp mFlinger; + + virtual void onFirstRef(); + + /* + * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer) + * is called. + */ + class LayerCleaner { + sp mFlinger; + wp mLayer; + protected: + ~LayerCleaner(); + public: + LayerCleaner(const sp& flinger, const sp& layer); + }; + private: // Creates an instance of ISurface for this Layer. virtual sp createSurface(); + // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener + virtual void onFrameAvailable(); + + uint32_t getEffectiveUsage(uint32_t usage) const; + Rect computeCrop(const sp& hw) const; bool isCropped() const; static bool getOpacityForFormat(uint32_t format); - // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener - virtual void onFrameAvailable(); + // drawing + void clearWithOpenGL(const sp& hw, const Region& clip, + GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const; + void drawWithOpenGL(const sp& hw, const Region& clip) const; + // ----------------------------------------------------------------------- // constants sp 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 mClientRef; }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp deleted file mode 100644 index 6f9ad4c..0000000 --- a/services/surfaceflinger/LayerBase.cpp +++ /dev/null @@ -1,635 +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 -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#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, const sp& client) - : contentDirty(false), - sequence(uint32_t(android_atomic_inc(&sSequence))), - mFlinger(flinger), mFiltering(false), - mNeedsFiltering(false), - mTransactionFlags(0), - mPremultipliedAlpha(true), mName("unnamed"), mDebug(false), - mHasSurface(false), - mClientRef(client) -{ -} - -LayerBase::~LayerBase() -{ - sp c(mClientRef.promote()); - if (c != 0) { - c->detachLayer(this); - } -} - -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& 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& 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& 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& 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& 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& hw, - HWComposer::HWCLayerInterface& layer) { - layer.setAcquireFenceFd(-1); -} - -void LayerBase::onLayerDisplayed(const sp& 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& hw, const Region& clip) const -{ - onDraw(hw, clip); -} - -void LayerBase::draw(const sp& hw) -{ - onDraw( hw, Region(hw->bounds()) ); -} - -void LayerBase::clearWithOpenGL(const sp& 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& hw, const Region& clip) const -{ - clearWithOpenGL(hw, clip, 0,0,0,0); -} - -void LayerBase::drawWithOpenGL(const sp& 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"); - sp client(mClientRef.promote()); - - 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" - " 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(), needsDithering(), 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); -} - -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 LayerBase::getLayer() const { - return 0; -} - -// --------------------------------------------------------------------------- - -sp LayerBase::createSurface() -{ - class BSurface : public BnSurface, public LayerCleaner { - virtual sp getSurfaceTexture() const { return 0; } - public: - BSurface(const sp& flinger, - const sp& layer) - : LayerCleaner(flinger, layer) { } - }; - sp sur(new BSurface(mFlinger, this)); - return sur; -} - -sp LayerBase::getSurface() -{ - sp s; - Mutex::Autolock _l(mLock); - - LOG_ALWAYS_FATAL_IF(mHasSurface, - "LayerBase::getSurface() has already been called"); - - mHasSurface = true; - s = createSurface(); - mClientSurfaceBinder = s->asBinder(); - return s; -} - -wp LayerBase::getSurfaceBinder() const { - return mClientSurfaceBinder; -} - -wp LayerBase::getSurfaceTextureBinder() const { - return 0; -} - -// --------------------------------------------------------------------------- - -LayerBase::LayerCleaner::LayerCleaner(const sp& flinger, - const sp& layer) - : mFlinger(flinger), mLayer(layer) { -} - -LayerBase::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 01d82d4..0000000 --- a/services/surfaceflinger/LayerBase.h +++ /dev/null @@ -1,378 +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 -#include - -#include -#include -#include - -#include -#include - -#include - -#include - -#include - -#include "Transform.h" -#include "DisplayHardware/HWComposer.h" - -namespace android { - -// --------------------------------------------------------------------------- - -class Client; -class DisplayDevice; -class GraphicBuffer; -class Layer; -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. - */ -class LayerBase : virtual public RefBase -{ - static int32_t sSequence; - -public: - LayerBase(SurfaceFlinger* flinger, const sp& client); - - - // Creates an ISurface associated with this object. This may only be - // called once (see also getSurfaceBinder()). - sp getSurface(); - - // Returns the Binder object for the ISurface associated with - // this object. - wp getSurfaceBinder() const; - - virtual wp getSurfaceTextureBinder() const; - - - 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& hw, LayerMesh* mesh) const; - Rect computeBounds() const; - - - virtual sp getLayer() const; - - virtual const char* getTypeId() const { return "LayerBase"; } - - virtual void setGeometry(const sp& hw, - HWComposer::HWCLayerInterface& layer); - virtual void setPerFrameData(const sp& hw, - HWComposer::HWCLayerInterface& layer); - virtual void setAcquireFence(const sp& 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& hw, const Region& clip) const; - virtual void draw(const sp& hw); - - /** - * onDraw - draws the surface. - */ - virtual void onDraw(const sp& 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& 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& 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& 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& hw, const Region& clip) const; - - void setFiltering(bool filtering); - bool getFiltering() const; - -private: - virtual sp createSurface(); - - Rect computeCrop(const sp& hw) const; - -protected: - void clearWithOpenGL(const sp& hw, const Region& clip, - GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const; - void drawWithOpenGL(const sp& hw, const Region& clip) const; - - - /* - * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer) - * is called. - */ - class LayerCleaner { - sp mFlinger; - wp mLayer; - protected: - ~LayerCleaner(); - public: - LayerCleaner(const sp& flinger, - const sp& layer); - }; - - - - sp 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; - - -private: - - 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 mClientSurfaceBinder; - - const wp mClientRef; - - -public: - // called from class SurfaceFlinger - virtual ~LayerBase(); - -private: - LayerBase(const LayerBase& rhs); -}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_LAYER_BASE_H diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp index f8c4139..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) - : Layer(flinger, client) -{ + : Layer(flinger, client) { } -LayerDim::~LayerDim() -{ +LayerDim::~LayerDim() { } void LayerDim::onDraw(const sp& hw, const Region& clip) const @@ -77,7 +75,7 @@ sp LayerDim::createSurface() virtual sp getSurfaceTexture() const { return 0; } public: BSurface(const sp& flinger, - const sp& layer) + const sp& layer) : LayerCleaner(flinger, layer) { } }; sp sur(new BSurface(mFlinger, this)); @@ -85,7 +83,7 @@ sp LayerDim::createSurface() } bool LayerDim::isVisible() const { - const Layer::State& s(mDrawingState); + const Layer::State& s(drawingState()); return !(s.flags & layer_state_t::eLayerHidden) && s.alpha; } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 5ef22ae..a27d185 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -580,7 +580,7 @@ bool SurfaceFlinger::authenticateSurfaceTexture( const LayerVector& currentLayers = mCurrentState.layersSortedByZ; size_t count = currentLayers.size(); for (size_t i=0 ; i& layer(currentLayers[i]); + const sp& 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 @@ -600,7 +600,7 @@ bool SurfaceFlinger::authenticateSurfaceTexture( // should not cause any harm. size_t purgatorySize = mLayerPurgatory.size(); for (size_t i=0 ; i& layer(mLayerPurgatory.itemAt(i)); + const sp& layer(mLayerPurgatory.itemAt(i)); wp lbcBinder = layer->getSurfaceTextureBinder(); if (lbcBinder == surfaceTextureBinder) { return true; @@ -908,7 +908,7 @@ void SurfaceFlinger::rebuildLayerStacks() { for (size_t dpy=0 ; dpy > layersSortedByZ; + Vector< sp > layersSortedByZ; const sp& hw(mDisplays[dpy]); const Transform& tr(hw->getTransform()); const Rect bounds(hw->getBounds()); @@ -918,7 +918,7 @@ void SurfaceFlinger::rebuildLayerStacks() { const size_t count = currentLayers.size(); for (size_t i=0 ; i& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); const Layer::State& s(layer->drawingState()); if (s.layerStack == hw->getLayerStack()) { Region drawRegion(tr.transform( @@ -948,14 +948,14 @@ void SurfaceFlinger::setUpHWComposer() { sp hw(mDisplays[dpy]); const int32_t id = hw->getHwcDisplayId(); if (id >= 0) { - const Vector< sp >& currentLayers( + const Vector< sp >& 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& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); layer->setGeometry(hw, *cur); if (mDebugDisableHWC || mDebugRegion) { cur->setSkip(true); @@ -971,7 +971,7 @@ void SurfaceFlinger::setUpHWComposer() { sp hw(mDisplays[dpy]); const int32_t id = hw->getHwcDisplayId(); if (id >= 0) { - const Vector< sp >& currentLayers( + const Vector< sp >& currentLayers( hw->getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); HWComposer::LayerListIterator cur = hwc.begin(id); @@ -981,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& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); layer->setPerFrameData(hw, *cur); } } @@ -1035,7 +1035,7 @@ void SurfaceFlinger::postFramebuffer() for (size_t dpy=0 ; dpy hw(mDisplays[dpy]); - const Vector< sp >& currentLayers(hw->getVisibleLayersSortedByZ()); + const Vector< sp >& currentLayers(hw->getVisibleLayersSortedByZ()); hw->onSwapBuffersCompleted(hwc); const size_t count = currentLayers.size(); int32_t id = hw->getHwcDisplayId(); @@ -1091,7 +1091,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) if (transactionFlags & eTraversalNeeded) { for (size_t i=0 ; i& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); if (!trFlags) continue; @@ -1238,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(currentLayers[i]); - uint32_t layerStack = layerBase->drawingState().layerStack; + const sp& layer(currentLayers[i]); + uint32_t layerStack = layer->drawingState().layerStack; if (i==0 || currentlayerStack != layerStack) { currentlayerStack = layerStack; // figure out if this layerstack is mirrored @@ -1261,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); } } } @@ -1284,7 +1284,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) mVisibleRegionsDirty = true; const size_t count = previousLayers.size(); for (size_t i=0 ; i& layer(previousLayers[i]); + const sp& 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 @@ -1335,7 +1335,7 @@ void SurfaceFlinger::computeVisibleRegions( size_t i = currentLayers.size(); while (i--) { - const sp& layer = currentLayers[i]; + const sp& layer = currentLayers[i]; // start with the whole surface at its current location const Layer::State& s(layer->drawingState()); @@ -1478,7 +1478,7 @@ void SurfaceFlinger::handlePageFlip() const LayerVector& currentLayers(mDrawingState.layersSortedByZ); const size_t count = currentLayers.size(); for (size_t i=0 ; i& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); const Region dirty(layer->latchBuffer(visibleRegions)); const Layer::State& s(layer->drawingState()); invalidateLayerStack(s.layerStack, dirty); @@ -1600,13 +1600,13 @@ void SurfaceFlinger::doComposeSurfaces(const sp& hw, const * and then, render the layers targeted at the framebuffer */ - const Vector< sp >& layers(hw->getVisibleLayersSortedByZ()); + const Vector< sp >& 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& layer(layers[i]); + const sp& layer(layers[i]); const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); if (!clip.isEmpty()) { switch (cur->getCompositionType()) { @@ -1638,7 +1638,7 @@ void SurfaceFlinger::doComposeSurfaces(const sp& hw, const } else { // we're not using h/w composer for (size_t i=0 ; i& layer(layers[i]); + const sp& layer(layers[i]); const Region clip(dirty.intersect( tr.transform(layer->visibleRegion))); if (!clip.isEmpty()) { @@ -1677,7 +1677,7 @@ void SurfaceFlinger::drawWormhole(const sp& hw, void SurfaceFlinger::addClientLayer(const sp& client, const sp& handle, - const sp& lbc) + const sp& lbc) { // attach this layer to the client client->attachLayer(handle, lbc); @@ -1687,7 +1687,7 @@ void SurfaceFlinger::addClientLayer(const sp& client, mCurrentState.layersSortedByZ.add(lbc); } -status_t SurfaceFlinger::removeLayer(const sp& layer) +status_t SurfaceFlinger::removeLayer(const sp& layer) { Mutex::Autolock _l(mStateLock); status_t err = purgatorizeLayer_l(layer); @@ -1696,9 +1696,9 @@ status_t SurfaceFlinger::removeLayer(const sp& layer) return err; } -status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) +status_t SurfaceFlinger::removeLayer_l(const sp& layer) { - ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); + ssize_t index = mCurrentState.layersSortedByZ.remove(layer); if (index >= 0) { mLayersRemoved = true; return NO_ERROR; @@ -1706,16 +1706,16 @@ status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) return status_t(index); } -status_t SurfaceFlinger::purgatorizeLayer_l(const sp& layerBase) +status_t SurfaceFlinger::purgatorizeLayer_l(const sp& 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 @@ -1866,7 +1866,7 @@ uint32_t SurfaceFlinger::setClientStateLocked( const layer_state_t& s) { uint32_t flags = 0; - sp layer(client->getLayerUser(s.surface)); + sp layer(client->getLayerUser(s.surface)); if (layer != 0) { const uint32_t what = s.what; if (what & layer_state_t::ePositionChanged) { @@ -1930,7 +1930,7 @@ sp SurfaceFlinger::createLayer( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { - sp layer; + sp layer; sp surfaceHandle; if (int32_t(w|h) < 0) { @@ -2017,7 +2017,7 @@ status_t SurfaceFlinger::onLayerRemoved(const sp& client, const sp layer = client->getLayerUser(handle); + sp layer = client->getLayerUser(handle); if (layer != 0) { err = purgatorizeLayer_l(layer); @@ -2028,11 +2028,11 @@ status_t SurfaceFlinger::onLayerRemoved(const sp& client, const sp& layer) +status_t SurfaceFlinger::onLayerDestroyed(const wp& layer) { // called by ~ISurface() when all references are gone status_t err = NO_ERROR; - sp l(layer.promote()); + sp l(layer.promote()); if (l != NULL) { Mutex::Autolock _l(mStateLock); err = removeLayer_l(l); @@ -2249,7 +2249,7 @@ void SurfaceFlinger::listLayersLocked(const Vector& args, size_t& inde const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const size_t count = currentLayers.size(); for (size_t i=0 ; i& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); snprintf(buffer, SIZE, "%s\n", layer->getName().string()); result.append(buffer); } @@ -2274,7 +2274,7 @@ void SurfaceFlinger::dumpStatsLocked(const Vector& args, size_t& index const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const size_t count = currentLayers.size(); for (size_t i=0 ; i& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); if (name == layer->getName()) { layer->dumpStats(result, buffer, SIZE); } @@ -2294,7 +2294,7 @@ void SurfaceFlinger::clearStatsLocked(const Vector& args, size_t& inde const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const size_t count = currentLayers.size(); for (size_t i=0 ; i& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); if (name.isEmpty() || (name == layer->getName())) { layer->clearStats(); } @@ -2350,7 +2350,7 @@ void SurfaceFlinger::dumpAllLocked( snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); result.append(buffer); for (size_t i=0 ; i& layer(currentLayers[i]); + const sp& layer(currentLayers[i]); layer->dump(result, buffer, SIZE); } @@ -2362,7 +2362,7 @@ void SurfaceFlinger::dumpAllLocked( snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); result.append(buffer); for (size_t i=0 ; i& layer(mLayerPurgatory.itemAt(i)); + const sp& layer(mLayerPurgatory.itemAt(i)); layer->shortDump(result, buffer, SIZE); } @@ -2451,7 +2451,7 @@ void SurfaceFlinger::dumpAllLocked( alloc.dump(result); } -const Vector< sp >& +const Vector< sp >& SurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) { // Note: mStateLock is held here return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ(); @@ -2708,10 +2708,10 @@ status_t SurfaceFlinger::captureScreenImplLocked( glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); - const Vector< sp >& layers(hw->getVisibleLayersSortedByZ()); + const Vector< sp >& layers(hw->getVisibleLayersSortedByZ()); const size_t count = layers.size(); for (size_t i=0 ; i& layer(layers[i]); + const sp& layer(layers[i]); const uint32_t z = layer->drawingState().z; if (z >= minLayerZ && z <= maxLayerZ) { if (filtering) layer->setFiltering(true); @@ -2874,15 +2874,15 @@ SurfaceFlinger::LayerVector::LayerVector() { } SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) - : SortedVector >(rhs) { + : SortedVector >(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& l(*reinterpret_cast*>(lhs)); - const sp& r(*reinterpret_cast*>(rhs)); + const sp& l(*reinterpret_cast*>(lhs)); + const sp& r(*reinterpret_cast*>(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 1f63b42..241a7d6 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -60,7 +60,6 @@ class DisplayEventConnection; class EventThread; class IGraphicBufferAlloc; class Layer; -class LayerBase; class LayerDim; class Surface; @@ -123,12 +122,11 @@ public: // for debugging only // TODO: this should be made accessible only to HWComposer - const Vector< sp >& getLayerSortedByZForHwcDisplay(int disp); + const Vector< sp >& getLayerSortedByZForHwcDisplay(int disp); private: friend class Client; friend class DisplayEventConnection; - friend class LayerBase; friend class Layer; // We're reference counted, never destroy SurfaceFlinger directly @@ -138,7 +136,7 @@ private: * Internal data structures */ - class LayerVector : public SortedVector > { + class LayerVector : public SortedVector< sp > { public: LayerVector(); LayerVector(const LayerVector& rhs); @@ -277,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& layer); + status_t onLayerDestroyed(const wp& layer); // remove a layer from SurfaceFlinger immediately - status_t removeLayer(const sp& layer); + status_t removeLayer(const sp& layer); // add a layer to SurfaceFlinger void addClientLayer(const sp& client, const sp& handle, - const sp& lbc); + const sp& lbc); - status_t removeLayer_l(const sp& layer); - status_t purgatorizeLayer_l(const sp& layer); + status_t removeLayer_l(const sp& layer); + status_t purgatorizeLayer_l(const sp& layer); /* ------------------------------------------------------------------------ * Boot animation, on/off animations and screen capture @@ -401,10 +399,10 @@ private: State mCurrentState; volatile int32_t mTransactionFlags; Condition mTransactionCV; - SortedVector > mLayerPurgatory; + SortedVector< sp > mLayerPurgatory; bool mTransactionPending; bool mAnimTransactionPending; - Vector > mLayersPendingRemoval; + Vector< sp > mLayersPendingRemoval; // protected by mStateLock (but we could use another lock) bool mLayersRemoved; @@ -453,7 +451,7 @@ private: // protected by mDestroyedLayerLock; mutable Mutex mDestroyedLayerLock; - Vector mDestroyedLayers; + Vector mDestroyedLayers; /* ------------------------------------------------------------------------ * Feature prototyping -- cgit v1.1