From 882e3a39ed770b335a203e233b57127fde1c839e Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Tue, 8 Jan 2013 16:06:15 -0800 Subject: Add some comments. Also, minor tweak to SurfaceTextureLayer. Change-Id: If616d5ee4e8226dd0e16c5dbb0e0f80db553110e --- services/surfaceflinger/Layer.cpp | 16 ++++++++++ services/surfaceflinger/Layer.h | 13 ++++++-- services/surfaceflinger/LayerBase.h | 42 ++++++++++++++++++++++--- services/surfaceflinger/SurfaceFlinger.cpp | 7 ++++- services/surfaceflinger/SurfaceTextureLayer.cpp | 1 - services/surfaceflinger/SurfaceTextureLayer.h | 5 +++ 6 files changed, 75 insertions(+), 9 deletions(-) (limited to 'services') diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 8c2dade..f94a9ba 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -125,6 +125,22 @@ void Layer::setName(const String8& name) { sp Layer::createSurface() { + /* + * This class provides an implementation of BnSurface (the "native" or + * "remote" side of the Binder IPC interface ISurface), and mixes in + * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for + * this layer when the BSurface is destroyed. + * + * The idea is to provide a handle to the Layer through ISurface that + * is cleaned up automatically when the last reference to the ISurface + * goes away. (The references will be held on the "proxy" side, while + * the Layer exists on the "native" side.) + * + * The Layer has a reference to an instance of SurfaceFlinger's variant + * of GLConsumer, which holds a reference to the BufferQueue. The + * getSurfaceTexture() call returns a Binder interface reference for + * the producer interface of the buffer queue associated with the Layer. + */ class BSurface : public BnSurface, public LayerCleaner { wp mOwner; virtual sp getSurfaceTexture() const { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 2d4afc4..ef829ed 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -47,11 +47,19 @@ class GLExtensions; // --------------------------------------------------------------------------- +/* + * The Layer class is essentially a LayerBase combined with a BufferQueue. + * A new BufferQueue and a new SurfaceFlingerConsumer are created when the + * Layer is first referenced. + * + * This also implements onFrameAvailable(), which notifies SurfaceFlinger + * that new data has arrived. + */ class Layer : public LayerBaseClient, public SurfaceFlingerConsumer::FrameAvailableListener { public: - Layer(SurfaceFlinger* flinger, const sp& client); + Layer(SurfaceFlinger* flinger, const sp& client); virtual ~Layer(); virtual const char* getTypeId() const { return "Layer"; } @@ -102,8 +110,9 @@ protected: virtual void clearStats(); private: - friend class SurfaceTextureLayer; + // Creates an instance of ISurface for this Layer. virtual sp createSurface(); + uint32_t getEffectiveUsage(uint32_t usage) const; bool isCropped() const; Rect computeBufferCrop() const; diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index 7a9471e..47473e7 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -49,6 +49,18 @@ class SurfaceFlinger; // --------------------------------------------------------------------------- +/* + * Layers are rectangular graphic entities, internal to SurfaceFlinger. + * They have properties including width, height, Z-depth, and 2D + * transformations (chiefly translation and 90-degree rotations). + * + * Layers are organized into "layer stacks". Each layer is a member of + * exactly one layer stack, identified by an integer in Layer::State. A + * given layer stack may appear on more than one display. + * + * Notable subclasses (below LayerBaseClient) include Layer, LayerDim, and + * LayerScreenshot. + */ class LayerBase : virtual public RefBase { static int32_t sSequence; @@ -308,16 +320,27 @@ private: // --------------------------------------------------------------------------- +/* + * 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); + LayerBaseClient(SurfaceFlinger* flinger, const sp& client); + + virtual ~LayerBaseClient(); - virtual ~LayerBaseClient(); + // Creates an ISurface associated with this object. This may only be + // called once (see also getSurfaceBinder()). + sp getSurface(); - sp getSurface(); - wp getSurfaceBinder() const; - virtual wp getSurfaceTextureBinder() const; + // 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); } @@ -330,6 +353,10 @@ 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; @@ -344,8 +371,13 @@ private: virtual sp createSurface(); mutable Mutex mLock; + + // Set to true if an ISurface has been associated with this object. mutable bool mHasSurface; + + // The ISurface's Binder object, set by getSurface(). wp mClientSurfaceBinder; + const wp mClientRef; // only read const uint32_t mIdentity; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index f0e5719..46476f9 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -575,13 +575,18 @@ bool SurfaceFlinger::authenticateSurfaceTexture( Mutex::Autolock _l(mStateLock); sp surfaceTextureBinder(bufferProducer->asBinder()); - // Check the visible layer list for the ISurface + // We want to determine whether the IGraphicBufferProducer was created by + // SurfaceFlinger. Check to see if we can find it in the layer list. const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 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; diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp index 0b638b4..395c8c8 100644 --- a/services/surfaceflinger/SurfaceTextureLayer.cpp +++ b/services/surfaceflinger/SurfaceTextureLayer.cpp @@ -20,7 +20,6 @@ #include -#include "Layer.h" #include "SurfaceTextureLayer.h" namespace android { diff --git a/services/surfaceflinger/SurfaceTextureLayer.h b/services/surfaceflinger/SurfaceTextureLayer.h index 8baa8d2..a75ccf4 100644 --- a/services/surfaceflinger/SurfaceTextureLayer.h +++ b/services/surfaceflinger/SurfaceTextureLayer.h @@ -29,12 +29,17 @@ namespace android { class Layer; +/* + * This is a thin wrapper around BufferQueue, used by the Layer class. + */ class SurfaceTextureLayer : public BufferQueue { public: SurfaceTextureLayer(); ~SurfaceTextureLayer(); + // After calling the superclass connect(), set or clear synchronous + // mode appropriately for the specified API. virtual status_t connect(int api, QueueBufferOutput* output); }; -- cgit v1.1