diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 6af1943c6..d5d551efa 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -22,6 +22,7 @@ #include #include "Client.h" +#include "Layer.h" #include "LayerBase.h" #include "SurfaceFlinger.h" @@ -118,7 +119,7 @@ sp Client::createSurface( * have access to the GL context. */ - class MessageCreateSurface : public MessageBase { + class MessageCreateLayer : public MessageBase { sp result; SurfaceFlinger* flinger; ISurfaceComposerClient::surface_data_t* params; @@ -129,7 +130,7 @@ sp Client::createSurface( PixelFormat format; uint32_t flags; public: - MessageCreateSurface(SurfaceFlinger* flinger, + MessageCreateLayer(SurfaceFlinger* flinger, ISurfaceComposerClient::surface_data_t* params, const String8& name, Client* client, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, @@ -140,19 +141,19 @@ sp Client::createSurface( } sp getResult() const { return result; } virtual bool handler() { - result = flinger->createSurface(params, name, client, + result = flinger->createLayer(params, name, client, display, w, h, format, flags); return true; } }; - sp msg = new MessageCreateSurface(mFlinger.get(), + sp msg = new MessageCreateLayer(mFlinger.get(), params, name, this, display, w, h, format, flags); mFlinger->postMessageSync(msg); - return static_cast( msg.get() )->getResult(); + return static_cast( msg.get() )->getResult(); } status_t Client::destroySurface(SurfaceID sid) { - return mFlinger->removeSurface(this, sid); + return mFlinger->onLayerRemoved(this, sid); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp index af33a8959..6a8a55dc7 100644 --- a/services/surfaceflinger/DisplayHardware.cpp +++ b/services/surfaceflinger/DisplayHardware.cpp @@ -40,6 +40,7 @@ #include "DisplayHardware.h" #include "GLExtensions.h" #include "SurfaceFlinger.h" +#include "LayerBase.h" // ---------------------------------------------------------------------------- using namespace android; @@ -102,7 +103,7 @@ DisplayHardware::DisplayHardware( int display, const sp& surface, EGLConfig config) - : DisplayHardwareBase(flinger, display), + : DisplayHardwareBase(display), mFlinger(flinger), mDisplayId(display), mHwc(0), diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp index e161c44e5..414118125 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp +++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp @@ -14,25 +14,15 @@ * limitations under the License. */ -#include -#include -#include -#include - -#include -#include - -#include +#include +#include #include "DisplayHardware/DisplayHardwareBase.h" -#include "SurfaceFlinger.h" // ---------------------------------------------------------------------------- namespace android { -DisplayHardwareBase::DisplayHardwareBase(const sp& flinger, - uint32_t displayIndex) -{ +DisplayHardwareBase::DisplayHardwareBase(uint32_t displayIndex) { mScreenAcquired = true; } diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h index 685748143..e6eb2b597 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h +++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h @@ -18,25 +18,14 @@ #define ANDROID_DISPLAY_HARDWARE_BASE_H #include -#include -#include -#include namespace android { -class SurfaceFlinger; - -class DisplayHardwareBase -{ +class DisplayHardwareBase { public: - DisplayHardwareBase( - const sp& flinger, - uint32_t displayIndex); - + DisplayHardwareBase(uint32_t displayIndex); ~DisplayHardwareBase(); - void startSleepManagement() const; - // console management void releaseScreen() const; void acquireScreen() const; @@ -44,21 +33,8 @@ public: bool canDraw() const; - private: - class DisplayEventThread : public Thread { - wp mFlinger; - status_t waitForFbSleep(); - status_t waitForFbWake(); - public: - DisplayEventThread(const sp& flinger); - virtual ~DisplayEventThread(); - virtual bool threadLoop(); - status_t initCheck() const; - }; - - sp mDisplayEventThread; - mutable int mScreenAcquired; + mutable int mScreenAcquired; }; }; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 122be5ed0..6d0631d8d 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -31,6 +31,8 @@ #include #include +#include + #include #include @@ -39,6 +41,7 @@ #include +#include "Layer.h" // needed only for debugging #include "LayerBase.h" #include "HWComposer.h" #include "SurfaceFlinger.h" diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index 5cde7fbcf..c2fff4fd9 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -24,7 +24,11 @@ #include +#include +#include #include +#include +#include #include extern "C" int clock_nanosleep(clockid_t clock_id, int flags, @@ -38,10 +42,10 @@ struct hwc_procs; namespace android { // --------------------------------------------------------------------------- +class GraphicBuffer; +class LayerBase; class String8; class SurfaceFlinger; -class LayerBase; -class GraphicBuffer; class HWComposer { diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index 0f1137723..fe9efa6d9 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include "DisplayHardware.h" @@ -31,20 +32,16 @@ #include "SurfaceFlinger.h" // --------------------------------------------------------------------------- - namespace android { - // --------------------------------------------------------------------------- EventThread::EventThread(const sp& flinger) - : mFlinger(flinger), - mHw(const_cast(flinger->getDefaultDisplayHardware())), // XXX: eventthread will need rework + : mHw(const_cast(flinger->getDefaultDisplayHardware())), // XXX: eventthread will need rework mLastVSyncTimestamp(0), mVSyncTimestamp(0), mUseSoftwareVSync(false), mDeliveredEvents(0), - mDebugVsyncEnabled(false) -{ + mDebugVsyncEnabled(false) { } void EventThread::onFirstRef() { diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h index 04c8f53f5..92c92ded8 100644 --- a/services/surfaceflinger/EventThread.h +++ b/services/surfaceflinger/EventThread.h @@ -30,12 +30,11 @@ #include "DisplayHardware.h" // --------------------------------------------------------------------------- - namespace android { - // --------------------------------------------------------------------------- class SurfaceFlinger; +class String8; // --------------------------------------------------------------------------- @@ -91,7 +90,6 @@ private: void disableVSyncLocked(); // constants - sp mFlinger; DisplayHardware& mHw; mutable Mutex mLock; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index b2f26831b..6617ea28d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -124,8 +124,7 @@ void Layer::onFirstRef() Layer::~Layer() { - mFlinger->postMessageAsync( - new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); + mFlinger->deleteTextureAsync(mTextureName); } void Layer::onFrameQueued() { diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index 2070cb971..f4eebb2d8 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -31,6 +31,7 @@ #include "clz.h" #include "Client.h" #include "LayerBase.h" +#include "Layer.h" #include "SurfaceFlinger.h" #include "DisplayHardware.h" @@ -438,6 +439,14 @@ 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; +} + // --------------------------------------------------------------------------- int32_t LayerBaseClient::sIdentity = 1; @@ -521,7 +530,7 @@ LayerBaseClient::LayerCleaner::LayerCleaner(const sp& flinger, LayerBaseClient::LayerCleaner::~LayerCleaner() { // destroy client resources - mFlinger->destroySurface(mLayer); + mFlinger->onLayerDestroyed(mLayer); } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index c689297b8..80bc4c3e8 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -125,8 +125,8 @@ public: Rect computeBounds() const; - virtual sp getLayerBaseClient() const { return 0; } - virtual sp getLayer() const { return 0; } + virtual sp getLayerBaseClient() const; + virtual sp getLayer() const; virtual const char* getTypeId() const { return "LayerBase"; } diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp index f2bf19d29..bed820686 100644 --- a/services/surfaceflinger/LayerScreenshot.cpp +++ b/services/surfaceflinger/LayerScreenshot.cpp @@ -41,8 +41,7 @@ LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display, LayerScreenshot::~LayerScreenshot() { if (mTextureName) { - mFlinger->postMessageAsync( - new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); + mFlinger->deleteTextureAsync(mTextureName); } } @@ -85,8 +84,8 @@ void LayerScreenshot::initStates(uint32_t w, uint32_t h, uint32_t flags) { uint32_t LayerScreenshot::doTransaction(uint32_t flags) { - const Layer::State& draw(drawingState()); - const Layer::State& curr(currentState()); + const LayerBase::State& draw(drawingState()); + const LayerBase::State& curr(currentState()); if (draw.flags & ISurfaceComposer::eLayerHidden) { if (!(curr.flags & ISurfaceComposer::eLayerHidden)) { diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 840222c04..ad3865ed0 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -16,17 +16,13 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS -#include -#include #include -#include -#include +#include #include #include -#include -#include -#include -#include + +#include +#include #include #include @@ -37,16 +33,19 @@ #include #include +#include +#include + +#include +#include #include #include #include #include -#include -#include - -#include +#include +#include #include "clz.h" #include "DdmConnection.h" @@ -62,10 +61,6 @@ #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/HWComposer.h" -#include -#include -#include -#include #define EGL_VERSION_HW_ANDROID 0x3143 @@ -100,11 +95,6 @@ SurfaceFlinger::SurfaceFlinger() mLastTransactionTime(0), mBootFinished(false), mExternalDisplaySurface(EGL_NO_SURFACE) -{ - init(); -} - -void SurfaceFlinger::init() { ALOGI("SurfaceFlinger is starting"); @@ -192,7 +182,7 @@ void SurfaceFlinger::bootFinished() const String16 name("window"); sp window(defaultServiceManager()->getService(name)); if (window != 0) { - window->linkToDeath(this); + window->linkToDeath(static_cast(this)); } // stop boot animation @@ -201,6 +191,21 @@ void SurfaceFlinger::bootFinished() property_set("service.bootanim.exit", "1"); } +void SurfaceFlinger::deleteTextureAsync(GLuint texture) { + class MessageDestroyGLTexture : public MessageBase { + GLuint texture; + public: + MessageDestroyGLTexture(GLuint texture) + : texture(texture) { + } + virtual bool handler() { + glDeleteTextures(1, &texture); + return true; + } + }; + postMessageAsync(new MessageDestroyGLTexture(texture)); +} + status_t SurfaceFlinger::selectConfigForPixelFormat( EGLDisplay dpy, EGLint const* attrs, @@ -1250,30 +1255,15 @@ void SurfaceFlinger::drawWormhole() const } } -status_t SurfaceFlinger::addLayer(const sp& layer) -{ - Mutex::Autolock _l(mStateLock); - addLayer_l(layer); - setTransactionFlags(eTransactionNeeded|eTraversalNeeded); - return NO_ERROR; -} - -status_t SurfaceFlinger::addLayer_l(const sp& layer) -{ - ssize_t i = mCurrentState.layersSortedByZ.add(layer); - return (i < 0) ? status_t(i) : status_t(NO_ERROR); -} - ssize_t SurfaceFlinger::addClientLayer(const sp& client, const sp& lbc) { // attach this layer to the client size_t name = client->attachLayer(lbc); - Mutex::Autolock _l(mStateLock); - // add this layer to the current state list - addLayer_l(lbc); + Mutex::Autolock _l(mStateLock); + mCurrentState.layersSortedByZ.add(lbc); return ssize_t(name); } @@ -1289,10 +1279,6 @@ status_t SurfaceFlinger::removeLayer(const sp& layer) status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) { - sp lbc(layerBase->getLayerBaseClient()); - if (lbc != 0) { - mLayerMap.removeItem( lbc->getSurfaceBinder() ); - } ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); if (index >= 0) { mLayersRemoved = true; @@ -1319,13 +1305,6 @@ status_t SurfaceFlinger::purgatorizeLayer_l(const sp& layerBase) return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; } -status_t SurfaceFlinger::invalidateLayerVisibility(const sp& layer) -{ - layer->forceVisibilityTransaction(); - setTransactionFlags(eTraversalNeeded); - return NO_ERROR; -} - uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) { return android_atomic_release_load(&mTransactionFlags); @@ -1390,7 +1369,7 @@ void SurfaceFlinger::setTransactionState(const Vector& state, } } -sp SurfaceFlinger::createSurface( +sp SurfaceFlinger::createLayer( ISurfaceComposerClient::surface_data_t* params, const String8& name, const sp& client, @@ -1401,26 +1380,24 @@ sp SurfaceFlinger::createSurface( sp surfaceHandle; if (int32_t(w|h) < 0) { - ALOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", + ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)", int(w), int(h)); return surfaceHandle; } - //ALOGD("createSurface for (%d x %d), name=%s", w, h, name.string()); - sp normalLayer; + //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string()); switch (flags & eFXSurfaceMask) { case eFXSurfaceNormal: - normalLayer = createNormalSurface(client, d, w, h, flags, format); - layer = normalLayer; + layer = createNormalLayer(client, d, w, h, flags, format); break; case eFXSurfaceBlur: // for now we treat Blur as Dim, until we can implement it // efficiently. case eFXSurfaceDim: - layer = createDimSurface(client, d, w, h, flags); + layer = createDimLayer(client, d, w, h, flags); break; case eFXSurfaceScreenshot: - layer = createScreenshotSurface(client, d, w, h, flags); + layer = createScreenshotLayer(client, d, w, h, flags); break; } @@ -1428,24 +1405,18 @@ sp SurfaceFlinger::createSurface( layer->initStates(w, h, flags); layer->setName(name); ssize_t token = addClientLayer(client, layer); - surfaceHandle = layer->getSurface(); if (surfaceHandle != 0) { params->token = token; params->identity = layer->getIdentity(); - if (normalLayer != 0) { - Mutex::Autolock _l(mStateLock); - mLayerMap.add(layer->getSurfaceBinder(), normalLayer); - } } - setTransactionFlags(eTransactionNeeded); } return surfaceHandle; } -sp SurfaceFlinger::createNormalSurface( +sp SurfaceFlinger::createNormalLayer( const sp& client, DisplayID display, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format) @@ -1473,13 +1444,13 @@ sp SurfaceFlinger::createNormalSurface( sp layer = new Layer(this, display, client); status_t err = layer->setBuffers(w, h, format, flags); if (CC_LIKELY(err != NO_ERROR)) { - ALOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); + ALOGE("createNormalLayer() failed (%s)", strerror(-err)); layer.clear(); } return layer; } -sp SurfaceFlinger::createDimSurface( +sp SurfaceFlinger::createDimLayer( const sp& client, DisplayID display, uint32_t w, uint32_t h, uint32_t flags) { @@ -1487,7 +1458,7 @@ sp SurfaceFlinger::createDimSurface( return layer; } -sp SurfaceFlinger::createScreenshotSurface( +sp SurfaceFlinger::createScreenshotLayer( const sp& client, DisplayID display, uint32_t w, uint32_t h, uint32_t flags) { @@ -1495,7 +1466,7 @@ sp SurfaceFlinger::createScreenshotSurface( return layer; } -status_t SurfaceFlinger::removeSurface(const sp& client, SurfaceID sid) +status_t SurfaceFlinger::onLayerRemoved(const sp& client, SurfaceID sid) { /* * called by the window manager, when a surface should be marked for @@ -1519,7 +1490,7 @@ status_t SurfaceFlinger::removeSurface(const sp& client, SurfaceID sid) return err; } -status_t SurfaceFlinger::destroySurface(const wp& layer) +status_t SurfaceFlinger::onLayerDestroyed(const wp& layer) { // called by ~ISurface() when all references are gone status_t err = NO_ERROR; @@ -2731,12 +2702,30 @@ status_t SurfaceFlinger::captureScreen(DisplayID dpy, // --------------------------------------------------------------------------- -sp SurfaceFlinger::getLayer(const sp& sur) const +SurfaceFlinger::LayerVector::LayerVector() { +} + +SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs) + : SortedVector >(rhs) { +} + +int SurfaceFlinger::LayerVector::do_compare(const void* lhs, + const void* rhs) const { - sp result; - Mutex::Autolock _l(mStateLock); - result = mLayerMap.valueFor( sur->asBinder() ).promote(); - return result; + const sp& l(*reinterpret_cast*>(lhs)); + const sp& r(*reinterpret_cast*>(rhs)); + // sort layers by Z order + uint32_t lz = l->currentState().z; + uint32_t rz = r->currentState().z; + // then by sequence, so we get a stable ordering + return (lz != rz) ? (lz - rz) : (l->sequence - r->sequence); +} + +// --------------------------------------------------------------------------- + +SurfaceFlinger::State::State() + : orientation(ISurfaceComposer::eOrientationDefault), + orientationFlags(0) { } // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 4af31fb6c..569fe3530 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -20,6 +20,9 @@ #include #include +#include +#include + #include #include @@ -33,13 +36,14 @@ #include #include + #include #include #include -#include "Barrier.h" -#include "Layer.h" +#include +#include "Barrier.h" #include "MessageQueue.h" namespace android { @@ -47,18 +51,20 @@ namespace android { // --------------------------------------------------------------------------- class Client; -class DisplayHardware; class DisplayEventConnection; +class DisplayHardware; class EventThread; class Layer; +class LayerBase; +class LayerBaseClient; class LayerDim; class LayerScreenshot; +class SurfaceTextureClient; struct surface_flinger_cblk_t; // --------------------------------------------------------------------------- -class GraphicBufferAlloc : public BnGraphicBufferAlloc -{ +class GraphicBufferAlloc : public BnGraphicBufferAlloc { public: GraphicBufferAlloc(); virtual ~GraphicBufferAlloc(); @@ -69,102 +75,52 @@ public: // --------------------------------------------------------------------------- enum { - eTransactionNeeded = 0x01, - eTraversalNeeded = 0x02 + eTransactionNeeded = 0x01, eTraversalNeeded = 0x02 }; -class SurfaceFlinger : - public BinderService, - public BnSurfaceComposer, - public IBinder::DeathRecipient, - protected Thread +class SurfaceFlinger : public BinderService, + public BnSurfaceComposer, + private IBinder::DeathRecipient, + private Thread { public: - static char const* getServiceName() { return "SurfaceFlinger"; } + static char const* getServiceName() { + return "SurfaceFlinger"; + } - SurfaceFlinger(); - virtual ~SurfaceFlinger(); - void init(); + SurfaceFlinger(); - virtual status_t onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); + // post an asynchronous message to the main thread + status_t postMessageAsync(const sp& msg, nsecs_t reltime = 0, + uint32_t flags = 0); - virtual status_t dump(int fd, const Vector& args); + // post a synchronous message to the main thread + status_t postMessageSync(const sp& msg, nsecs_t reltime = 0, + uint32_t flags = 0); - // ISurfaceComposer interface - virtual sp createConnection(); - virtual sp createGraphicBufferAlloc(); - virtual sp getCblk() const; - virtual void bootFinished(); - virtual void setTransactionState(const Vector& state, - int orientation, uint32_t flags); - virtual bool authenticateSurfaceTexture(const sp& surface) const; - virtual sp createDisplayEventConnection(); + // force full composition on all displays + void repaintEverything(); - virtual status_t captureScreen(DisplayID dpy, - sp* heap, - uint32_t* width, uint32_t* height, - PixelFormat* format, uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ); + // renders content on given display to a texture. thread-safe version. + status_t renderScreenToTexture(DisplayID dpy, GLuint* textureName, + GLfloat* uOut, GLfloat* vOut); - virtual status_t turnElectronBeamOff(int32_t mode); - virtual status_t turnElectronBeamOn(int32_t mode); + // renders content on given display to a texture, w/o acquiring main lock + status_t renderScreenToTextureLocked(DisplayID dpy, GLuint* textureName, + GLfloat* uOut, GLfloat* vOut); - // called when screen needs to turn off - virtual void blank(); - // called when screen is turning back on - virtual void unblank(); + // returns the default Display + const DisplayHardware& getDefaultDisplayHardware() const { + return getDisplayHardware(0); + } - virtual void connectDisplay(const sp display); + // called on the main thread by MessageQueue when an internal message + // is received + // TODO: this should be made accessible only to MessageQueue + void onMessageReceived(int32_t what); - // called on the main thread in response to screenReleased() - void onScreenReleased(); - // called on the main thread in response to screenAcquired() - void onScreenAcquired(); - - - status_t renderScreenToTexture(DisplayID dpy, - GLuint* textureName, GLfloat* uOut, GLfloat* vOut); - status_t renderScreenToTextureLocked(DisplayID dpy, - GLuint* textureName, GLfloat* uOut, GLfloat* vOut); - - void onMessageReceived(int32_t what); - void handleMessageTransaction(); - void handleMessageInvalidate(); - void handleMessageRefresh(); - - status_t postMessageAsync(const sp& msg, - nsecs_t reltime=0, uint32_t flags = 0); - - status_t postMessageSync(const sp& msg, - nsecs_t reltime=0, uint32_t flags = 0); - - status_t removeLayer(const sp& layer); - status_t addLayer(const sp& layer); - status_t invalidateLayerVisibility(const sp& layer); - void invalidateHwcGeometry(); - - sp getLayer(const sp& sur) const; - - GLuint getProtectedTexName() const { return mProtectedTexName; } - - surface_flinger_cblk_t* getControlBlock() const; - - - class MessageDestroyGLTexture : public MessageBase { - GLuint texture; - public: - MessageDestroyGLTexture(GLuint texture) : texture(texture) { } - virtual bool handler() { - glDeleteTextures(1, &texture); - return true; - } - }; - - -private: - // DeathRecipient interface - virtual void binderDied(const wp& who); + // utility function to delete a texture on the main thread + void deleteTextureAsync(GLuint texture); private: friend class Client; @@ -173,219 +129,284 @@ private: friend class LayerBaseClient; friend class Layer; - sp createSurface( - ISurfaceComposerClient::surface_data_t* params, - const String8& name, - const sp& client, - DisplayID display, uint32_t w, uint32_t h, PixelFormat format, - uint32_t flags); + // We're reference counted, never destroy SurfaceFlinger directly + virtual ~SurfaceFlinger(); - sp createNormalSurface( - const sp& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags, - PixelFormat& format); + /* ------------------------------------------------------------------------ + * Internal data structures + */ - sp createDimSurface( - const sp& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags); - - sp createScreenshotSurface( - const sp& client, DisplayID display, - uint32_t w, uint32_t h, uint32_t flags); - - status_t removeSurface(const sp& client, SurfaceID sid); - status_t destroySurface(const wp& layer); - uint32_t setClientStateLocked(const sp& client, const layer_state_t& s); - - class LayerVector : public SortedVector< sp > { + class LayerVector : public SortedVector > { public: - LayerVector() { } - LayerVector(const LayerVector& rhs) : SortedVector< sp >(rhs) { } - virtual int do_compare(const void* lhs, const void* rhs) const { - const sp& l(*reinterpret_cast*>(lhs)); - const sp& r(*reinterpret_cast*>(rhs)); - // sort layers by Z order - uint32_t lz = l->currentState().z; - uint32_t rz = r->currentState().z; - // then by sequence, so we get a stable ordering - return (lz != rz) ? (lz - rz) : (l->sequence - r->sequence); - } + LayerVector(); + LayerVector(const LayerVector& rhs); + virtual int do_compare(const void* lhs, const void* rhs) const; }; struct State { - State() - : orientation(ISurfaceComposer::eOrientationDefault), - orientationFlags(0) { - } - LayerVector layersSortedByZ; - uint8_t orientation; - uint8_t orientationFlags; + State(); + LayerVector layersSortedByZ; + uint8_t orientation; + uint8_t orientationFlags; }; - virtual bool threadLoop(); - virtual status_t readyToRun(); - virtual void onFirstRef(); + /* ------------------------------------------------------------------------ + * IBinder interface + */ + virtual status_t onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags); + virtual status_t dump(int fd, const Vector& args); -public: // hack to work around gcc 4.0.3 bug + /* ------------------------------------------------------------------------ + * ISurfaceComposer interface + */ + virtual sp createConnection(); + virtual sp createGraphicBufferAlloc(); + virtual sp getCblk() const; + virtual void bootFinished(); + virtual void setTransactionState(const Vector& state, + int orientation, uint32_t flags); + virtual bool authenticateSurfaceTexture( + const sp& surface) const; + virtual sp createDisplayEventConnection(); + virtual status_t captureScreen(DisplayID dpy, sp* heap, + uint32_t* width, uint32_t* height, PixelFormat* format, + uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, + uint32_t maxLayerZ); + virtual status_t turnElectronBeamOff(int32_t mode); + virtual status_t turnElectronBeamOn(int32_t mode); + // called when screen needs to turn off + virtual void blank(); + // called when screen is turning back on + virtual void unblank(); + virtual void connectDisplay(const sp display); - const DisplayHardware& getDisplayHardware(DisplayID dpy) const { - return *mDisplayHardwares[dpy]; - } - const DisplayHardware& getDefaultDisplayHardware() const { - return getDisplayHardware(0); - } + /* ------------------------------------------------------------------------ + * DeathRecipient interface + */ + virtual void binderDied(const wp& who); - void signalTransaction(); - void signalLayerUpdate(); - void signalRefresh(); - void repaintEverything(); + /* ------------------------------------------------------------------------ + * Thread interface + */ + virtual bool threadLoop(); + virtual status_t readyToRun(); + virtual void onFirstRef(); -private: - void waitForEvent(); - Region handleTransaction(uint32_t transactionFlags); - Region handleTransactionLocked(uint32_t transactionFlags); + /* ------------------------------------------------------------------------ + * Message handling + */ + void waitForEvent(); + void signalTransaction(); + void signalLayerUpdate(); + void signalRefresh(); - void computeVisibleRegions( - const LayerVector& currentLayers, - Region& dirtyRegion, - Region& wormholeRegion); + // called on the main thread in response to screenReleased() + void onScreenReleased(); + // called on the main thread in response to screenAcquired() + void onScreenAcquired(); - /* handlePageFilp: this is were we latch a new buffer - * if available and compute the dirty region. - * The return value is the dirty region expressed in the - * window manager's coordinate space (or the layer's state - * space, which is the same thing), in particular the dirty - * region is independent from a specific display's orientation. - */ - Region handlePageFlip(); + void handleMessageTransaction(); + void handleMessageInvalidate(); + void handleMessageRefresh(); - void handleRefresh(); - void handleWorkList(const DisplayHardware& hw); - void handleRepaint(const DisplayHardware& hw); - void postFramebuffer(); - void setupHardwareComposer(const DisplayHardware& hw); - void composeSurfaces(const DisplayHardware& hw, const Region& dirty); + Region handleTransaction(uint32_t transactionFlags); + Region handleTransactionLocked(uint32_t transactionFlags); + /* handlePageFilp: this is were we latch a new buffer + * if available and compute the dirty region. + * The return value is the dirty region expressed in the + * window manager's coordinate space (or the layer's state + * space, which is the same thing), in particular the dirty + * region is independent from a specific display's orientation. + */ + Region handlePageFlip(); - void setInvalidateRegion(const Region& reg); - Region getAndClearInvalidateRegion(); + void handleRefresh(); + void handleWorkList(const DisplayHardware& hw); + void handleRepaint(const DisplayHardware& hw); - ssize_t addClientLayer(const sp& client, - const sp& lbc); - status_t addLayer_l(const sp& layer); - status_t removeLayer_l(const sp& layer); - status_t purgatorizeLayer_l(const sp& layer); + /* ------------------------------------------------------------------------ + * Transactions + */ + uint32_t getTransactionFlags(uint32_t flags); + uint32_t peekTransactionFlags(uint32_t flags); + uint32_t setTransactionFlags(uint32_t flags); + void commitTransaction(); + uint32_t setClientStateLocked(const sp& client, + const layer_state_t& s); - uint32_t getTransactionFlags(uint32_t flags); - uint32_t peekTransactionFlags(uint32_t flags); - uint32_t setTransactionFlags(uint32_t flags); - void commitTransaction(); + /* ------------------------------------------------------------------------ + * Layer management + */ + sp createLayer(ISurfaceComposerClient::surface_data_t* params, + const String8& name, const sp& client, DisplayID display, + uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); + sp createNormalLayer(const sp& client, DisplayID display, + uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format); - status_t captureScreenImplLocked(DisplayID dpy, - sp* heap, - uint32_t* width, uint32_t* height, PixelFormat* format, - uint32_t reqWidth, uint32_t reqHeight, - uint32_t minLayerZ, uint32_t maxLayerZ); + sp createDimLayer(const sp& client, DisplayID display, + uint32_t w, uint32_t h, uint32_t flags); - status_t turnElectronBeamOffImplLocked(int32_t mode); - status_t turnElectronBeamOnImplLocked(int32_t mode); - status_t electronBeamOffAnimationImplLocked(); - status_t electronBeamOnAnimationImplLocked(); + sp createScreenshotLayer(const sp& client, + DisplayID display, uint32_t w, uint32_t h, uint32_t flags); - void debugFlashRegions(const DisplayHardware& hw); - void drawWormhole() const; + // called in response to the window-manager calling + // ISurfaceComposerClient::destroySurface() + // The specified layer is first placed in a purgatory list + // until all references from the client are released. + status_t onLayerRemoved(const sp& client, SurfaceID sid); - uint32_t getMaxTextureSize() const; - uint32_t getMaxViewportDims() const; + // 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); - static status_t selectConfigForPixelFormat( - EGLDisplay dpy, - EGLint const* attrs, - PixelFormat format, - EGLConfig* outConfig); - static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId); - static EGLContext createGLContext(EGLDisplay disp, EGLConfig config); - void initializeGL(EGLDisplay display, EGLSurface surface); + // remove a layer from SurfaceFlinger immediately + status_t removeLayer(const sp& layer); - void startBootAnim(); + // add a layer to SurfaceFlinger + ssize_t addClientLayer(const sp& client, + const sp& lbc); - void listLayersLocked(const Vector& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const; - void dumpStatsLocked(const Vector& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const; - void clearStatsLocked(const Vector& args, size_t& index, - String8& result, char* buffer, size_t SIZE) const; - void dumpAllLocked(String8& result, char* buffer, size_t SIZE) const; + status_t removeLayer_l(const sp& layer); + status_t purgatorizeLayer_l(const sp& layer); - mutable MessageQueue mEventQueue; + /* ------------------------------------------------------------------------ + * Boot animation, on/off animations and screen capture + */ - // access must be protected by mStateLock - mutable Mutex mStateLock; - State mCurrentState; - volatile int32_t mTransactionFlags; - Condition mTransactionCV; - SortedVector< sp > mLayerPurgatory; - bool mTransationPending; - Vector< sp > mLayersPendingRemoval; + void startBootAnim(); - // protected by mStateLock (but we could use another lock) - DisplayHardware* mDisplayHardwares[1]; - bool mLayersRemoved; - DefaultKeyedVector< wp, wp > mLayerMap; + status_t captureScreenImplLocked(DisplayID dpy, sp* heap, + uint32_t* width, uint32_t* height, PixelFormat* format, + uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, + uint32_t maxLayerZ); - // access must be protected by mInvalidateLock - mutable Mutex mInvalidateLock; - Region mInvalidateRegion; + status_t turnElectronBeamOffImplLocked(int32_t mode); + status_t turnElectronBeamOnImplLocked(int32_t mode); + status_t electronBeamOffAnimationImplLocked(); + status_t electronBeamOnAnimationImplLocked(); - // constant members (no synchronization needed for access) - sp mServerHeap; - surface_flinger_cblk_t* mServerCblk; - GLuint mWormholeTexName; - GLuint mProtectedTexName; - nsecs_t mBootTime; - sp mEventThread; - GLint mMaxViewportDims[2]; - GLint mMaxTextureSize; - EGLContext mEGLContext; - EGLConfig mEGLConfig; + /* ------------------------------------------------------------------------ + * EGL + */ + static status_t selectConfigForPixelFormat(EGLDisplay dpy, + EGLint const* attrs, PixelFormat format, EGLConfig* outConfig); + static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId); + static EGLContext createGLContext(EGLDisplay disp, EGLConfig config); + void initializeGL(EGLDisplay display, EGLSurface surface); + uint32_t getMaxTextureSize() const; + uint32_t getMaxViewportDims() const; + /* ------------------------------------------------------------------------ + * Display management + */ + const DisplayHardware& getDisplayHardware(DisplayID dpy) const { + return *mDisplayHardwares[dpy]; + } - // Can only accessed from the main thread, these members - // don't need synchronization - State mDrawingState; - Region mDirtyRegion; - Region mDirtyRegionRemovedLayer; - Region mSwapRegion; - Region mWormholeRegion; - bool mVisibleRegionsDirty; - bool mHwWorkListDirty; - int32_t mElectronBeamAnimationMode; + /* ------------------------------------------------------------------------ + * Compositing + */ + void invalidateHwcGeometry(); + void computeVisibleRegions(const LayerVector& currentLayers, + Region& dirtyRegion, Region& wormholeRegion); + void postFramebuffer(); + void setupHardwareComposer(const DisplayHardware& hw); + void composeSurfaces(const DisplayHardware& hw, const Region& dirty); + void setInvalidateRegion(const Region& reg); + Region getAndClearInvalidateRegion(); + void drawWormhole() const; + GLuint getProtectedTexName() const { + return mProtectedTexName; + } + /* ------------------------------------------------------------------------ + * Debugging & dumpsys + */ + void debugFlashRegions(const DisplayHardware& hw); + void listLayersLocked(const Vector& args, size_t& index, + String8& result, char* buffer, size_t SIZE) const; + void dumpStatsLocked(const Vector& args, size_t& index, + String8& result, char* buffer, size_t SIZE) const; + void clearStatsLocked(const Vector& args, size_t& index, + String8& result, char* buffer, size_t SIZE) const; + void dumpAllLocked(String8& result, char* buffer, size_t SIZE) const; - // don't use a lock for these, we don't care - int mDebugRegion; - int mDebugDDMS; - int mDebugDisableHWC; - int mDebugDisableTransformHint; - volatile nsecs_t mDebugInSwapBuffers; - nsecs_t mLastSwapBufferTime; - volatile nsecs_t mDebugInTransaction; - nsecs_t mLastTransactionTime; - bool mBootFinished; + /* ------------------------------------------------------------------------ + * Attributes + */ - // these are thread safe - mutable Barrier mReadyToRunBarrier; + // access must be protected by mStateLock + mutable Mutex mStateLock; + State mCurrentState; + volatile int32_t mTransactionFlags; + Condition mTransactionCV; + SortedVector > mLayerPurgatory; + bool mTransationPending; + Vector > mLayersPendingRemoval; + // protected by mStateLock (but we could use another lock) + DisplayHardware* mDisplayHardwares[1]; + bool mLayersRemoved; - // protected by mDestroyedLayerLock; - mutable Mutex mDestroyedLayerLock; - Vector mDestroyedLayers; + // access must be protected by mInvalidateLock + mutable Mutex mInvalidateLock; + Region mInvalidateRegion; + // constant members (no synchronization needed for access) + sp mServerHeap; + surface_flinger_cblk_t* mServerCblk; + GLuint mWormholeTexName; + GLuint mProtectedTexName; + nsecs_t mBootTime; + sp mEventThread; + GLint mMaxViewportDims[2]; + GLint mMaxTextureSize; + EGLContext mEGLContext; + EGLConfig mEGLConfig; - EGLSurface getExternalDisplaySurface() const; - sp mExternalDisplayNativeWindow; - EGLSurface mExternalDisplaySurface; + // Can only accessed from the main thread, these members + // don't need synchronization + State mDrawingState; + Region mDirtyRegion; + Region mDirtyRegionRemovedLayer; + Region mSwapRegion; + Region mWormholeRegion; + bool mVisibleRegionsDirty; + bool mHwWorkListDirty; + int32_t mElectronBeamAnimationMode; + + // don't use a lock for these, we don't care + int mDebugRegion; + int mDebugDDMS; + int mDebugDisableHWC; + int mDebugDisableTransformHint; + volatile nsecs_t mDebugInSwapBuffers; + nsecs_t mLastSwapBufferTime; + volatile nsecs_t mDebugInTransaction; + nsecs_t mLastTransactionTime; + bool mBootFinished; + + // these are thread safe + mutable MessageQueue mEventQueue; + mutable Barrier mReadyToRunBarrier; + + // protected by mDestroyedLayerLock; + mutable Mutex mDestroyedLayerLock; + Vector mDestroyedLayers; + + /* ------------------------------------------------------------------------ + * Feature prototyping + */ + + EGLSurface getExternalDisplaySurface() const; + sp mExternalDisplayNativeWindow; + EGLSurface mExternalDisplaySurface; +public: + surface_flinger_cblk_t* getControlBlock() const; }; // ---------------------------------------------------------------------------