diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 50b2ad150..48629498b 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -39,6 +39,10 @@ class DisplayInfo; class IDisplayEventConnection; class IMemoryHeap; +/* + * This class defines the Binder IPC interface for accessing various + * SurfaceFlinger features. + */ class ISurfaceComposer: public IInterface { public: DECLARE_META_INTERFACE(SurfaceComposer); diff --git a/include/gui/Surface.h b/include/gui/Surface.h index cba11b8a4..8654f76ab 100644 --- a/include/gui/Surface.h +++ b/include/gui/Surface.h @@ -107,11 +107,9 @@ private: // --------------------------------------------------------------------------- /* - * This is a small wrapper around SurfaceTextureClient that provides some - * helper classes for Binder interaction. + * This is a small wrapper around SurfaceTextureClient. * - * TODO: rename to SurfaceJniHelper. May want to move SurfaceInfo and - * the associated lock() / unlockAndPost() calls to STC. + * TODO: rename and/or merge with STC. */ class Surface : public SurfaceTextureClient { diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h index bce232987..6f0982192 100644 --- a/include/gui/SurfaceTextureClient.h +++ b/include/gui/SurfaceTextureClient.h @@ -35,19 +35,20 @@ namespace android { class Surface; /* - * An implementation of ANativeWindow that also behaves as the producer - * side of a BufferQueue. + * An implementation of ANativeWindow that feeds graphics buffers into a + * BufferQueue. * * This is typically used by programs that want to render frames through * some means (maybe OpenGL, a software renderer, or a hardware decoder) * and have the frames they create forwarded to SurfaceFlinger for * compositing. For example, a video decoder could render a frame and call * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by - * SurfaceTextureClient. STC then acts as the BufferQueue producer, - * providing the new frame to a consumer such as GLConsumer. + * SurfaceTextureClient. STC then forwards the buffers through Binder IPC + * to the BufferQueue's producer interface, providing the new frame to a + * consumer such as GLConsumer. * - * TODO: rename to Surface. The existing Surface class wraps STC with - * some Binder goodies, which most users of Surface class don't care about. + * TODO: rename to Surface after merging or renaming the existing Surface + * class. */ class SurfaceTextureClient : public ANativeObjectBase diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 8c2dadec9..f94a9ba7e 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 2d4afc483..ef829edf9 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 7a9471e92..47473e790 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(); - sp getSurface(); - wp getSurfaceBinder() const; - virtual wp getSurfaceTextureBinder() const; + // 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); } @@ -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 f0e57198f..46476f9b6 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 0b638b45f..395c8c835 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 8baa8d268..a75ccf47d 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); };