diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk index b8a0630ac..0879a66de 100644 --- a/libs/surfaceflinger/Android.mk +++ b/libs/surfaceflinger/Android.mk @@ -14,7 +14,6 @@ LOCAL_SRC_FILES:= \ MessageQueue.cpp \ SurfaceFlinger.cpp \ TextureManager.cpp \ - Tokenizer.cpp \ Transform.cpp LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\" diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 3fbb4d386..85149f5f5 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -47,9 +47,9 @@ template inline T min(T a, T b) { // --------------------------------------------------------------------------- -Layer::Layer(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i) - : LayerBaseClient(flinger, display, client, i), +Layer::Layer(SurfaceFlinger* flinger, + DisplayID display, const sp& client) + : LayerBaseClient(flinger, display, client), lcblk(NULL), mSecure(false), mNeedsBlending(true), @@ -58,13 +58,6 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display, mBufferManager(mTextureManager), mWidth(0), mHeight(0), mFixedSize(false) { - // no OpenGL operation is possible here, since we might not be - // in the OpenGL thread. - lcblk = new SharedBufferServer( - client->ctrlblk, i, mBufferManager.getDefaultBufferCount(), - getIdentity()); - - mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() ); } Layer::~Layer() @@ -77,12 +70,31 @@ Layer::~Layer() delete lcblk; } +// TODO: get rid of this +void Layer::setToken(int32_t token) +{ + sp ourClient(client.promote()); + + mToken = token; + + // no OpenGL operation is possible here, since we might not be + // in the OpenGL thread. + lcblk = new SharedBufferServer( + ourClient->ctrlblk, token, mBufferManager.getDefaultBufferCount(), + getIdentity()); + + mBufferManager.setActiveBufferIndex( lcblk->getFrontBuffer() ); +} + // called with SurfaceFlinger::mStateLock as soon as the layer is entered // in the purgatory list void Layer::onRemoved() { - // wake up the condition - lcblk->setStatus(NO_INIT); + sp ourClient(client.promote()); + if (ourClient != 0) { + // wake up the condition + lcblk->setStatus(NO_INIT); + } } sp Layer::createSurface() const @@ -140,7 +152,7 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); mNeedsDithering = layerRedsize > displayRedSize; - mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); + mSurface = new SurfaceLayer(mFlinger, this); return NO_ERROR; } @@ -391,8 +403,11 @@ uint32_t Layer::doTransaction(uint32_t flags) // a buffer, it'll get the new size. setBufferSize(temp.requested_w, temp.requested_h); - // all buffers need reallocation - lcblk->reallocateAll(); + sp ourClient(client.promote()); + if (ourClient != 0) { + // all buffers need reallocation + lcblk->reallocateAll(); + } } else { // record the new size setBufferSize(temp.requested_w, temp.requested_h); @@ -427,6 +442,13 @@ bool Layer::isFixedSize() const { void Layer::lockPageFlip(bool& recomputeVisibleRegions) { + sp ourClient(client.promote()); + if (ourClient == 0) { + // client died + recomputeVisibleRegions = true; + return; + } + ssize_t buf = lcblk->retireAndLock(); if (buf == NOT_ENOUGH_DATA) { // NOTE: This is not an error, it simply means there is nothing to @@ -538,9 +560,12 @@ void Layer::unlockPageFlip( void Layer::finishPageFlip() { - int buf = mBufferManager.getActiveBufferIndex(); - status_t err = lcblk->unlock( buf ); - LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf); + sp ourClient(client.promote()); + if (ourClient != 0) { + int buf = mBufferManager.getActiveBufferIndex(); + status_t err = lcblk->unlock( buf ); + LOGE_IF(err!=NO_ERROR, "layer %p, buffer=%d wasn't locked!", this, buf); + } } @@ -707,8 +732,8 @@ status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) // --------------------------------------------------------------------------- Layer::SurfaceLayer::SurfaceLayer(const sp& flinger, - SurfaceID id, const sp& owner) - : Surface(flinger, id, owner->getIdentity(), owner) + const sp& owner) + : Surface(flinger, owner->getIdentity(), owner) { } diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h index 59603a587..b42757668 100644 --- a/libs/surfaceflinger/Layer.h +++ b/libs/surfaceflinger/Layer.h @@ -50,7 +50,7 @@ public: SharedBufferServer* lcblk; Layer(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i); + const sp& client); virtual ~Layer(); @@ -96,8 +96,7 @@ private: class SurfaceLayer : public LayerBaseClient::Surface { public: - SurfaceLayer(const sp& flinger, - SurfaceID id, const sp& owner); + SurfaceLayer(const sp& flinger, const sp& owner); ~SurfaceLayer(); private: virtual sp requestBuffer(int bufferIdx, @@ -189,6 +188,12 @@ private: uint32_t mReqHeight; uint32_t mReqFormat; bool mFixedSize; + + // TODO: get rid of this +private: + virtual void setToken(int32_t token); + virtual int32_t getToken() const { return mToken; } + int32_t mToken; }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 7ab74b427..80b001e41 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -488,37 +488,20 @@ void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const int32_t LayerBaseClient::sIdentity = 1; LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i) - : LayerBase(flinger, display), client(client), mIndex(i), + const sp& client) + : LayerBase(flinger, display), client(client), mIdentity(uint32_t(android_atomic_inc(&sIdentity))) { } -void LayerBaseClient::onFirstRef() -{ - sp client(this->client.promote()); - if (client != 0) { - client->bindLayer(this, mIndex); - } -} - LayerBaseClient::~LayerBaseClient() { - sp client(this->client.promote()); - if (client != 0) { - client->free(mIndex); + sp c(client.promote()); + if (c != 0) { + c->free(this); } } -ssize_t LayerBaseClient::serverIndex() const -{ - sp client(this->client.promote()); - if (client != 0) { - return (client->cid<<16)|mIndex; - } - return ssize_t(0xFFFF0000 | mIndex); -} - sp LayerBaseClient::getSurface() { sp s; @@ -533,7 +516,7 @@ sp LayerBaseClient::getSurface() sp LayerBaseClient::createSurface() const { - return new Surface(mFlinger, clientIndex(), mIdentity, + return new Surface(mFlinger, mIdentity, const_cast(this)); } @@ -544,10 +527,9 @@ void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const sp client(this->client.promote()); snprintf(buffer, SIZE, " name=%s\n" - " id=0x%08x, client=0x%08x, identity=%u\n", + " client=%p, identity=%u\n", getName().string(), - clientIndex(), client.get() ? client->cid : 0, - getIdentity()); + client.get(), getIdentity()); result.append(buffer); } @@ -556,9 +538,9 @@ void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const LayerBaseClient::Surface::Surface( const sp& flinger, - SurfaceID id, int identity, + int identity, const sp& owner) - : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner) + : mFlinger(flinger), mIdentity(identity), mOwner(owner) { } diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 2e2f2df89..c9a516f73 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -101,7 +101,6 @@ public: void invalidate(); virtual const char* getTypeId() const { return "LayerBase"; } - virtual ssize_t serverIndex() const { return -1; } /** * draw - performs some global clipping optimizations @@ -269,30 +268,24 @@ class LayerBaseClient : public LayerBase public: class Surface; - LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i); + const wp client; + + LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, + const sp& client); virtual ~LayerBaseClient(); - virtual void onFirstRef(); - const wp client; - - inline uint32_t getIdentity() const { return mIdentity; } - inline int32_t clientIndex() const { return mIndex; } - sp getSurface(); virtual sp createSurface() const; - virtual ssize_t serverIndex() const; virtual const char* getTypeId() const { return "LayerBaseClient"; } - class Surface : public BnSurface - { + uint32_t getIdentity() const { return mIdentity; } + + class Surface : public BnSurface { public: - int32_t getToken() const { return mToken; } int32_t getIdentity() const { return mIdentity; } protected: - Surface(const sp& flinger, - SurfaceID id, int identity, + Surface(const sp& flinger, int identity, const sp& owner); virtual ~Surface(); virtual status_t onTransact(uint32_t code, const Parcel& data, @@ -313,7 +306,6 @@ public: protected: friend class LayerBaseClient; sp mFlinger; - int32_t mToken; int32_t mIdentity; wp mOwner; }; @@ -324,12 +316,16 @@ protected: virtual void dump(String8& result, char* scratch, size_t size) const; private: - int32_t mIndex; - mutable Mutex mLock; - mutable wp mClientSurface; + mutable Mutex mLock; + mutable wp mClientSurface; // only read - const uint32_t mIdentity; - static int32_t sIdentity; + const uint32_t mIdentity; + static int32_t sIdentity; + + // TODO: get rid of this +public: + virtual void setToken(int32_t token) { } + virtual int32_t getToken() const { return -1; } }; // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp index 09c90e800..4c8bae8f6 100644 --- a/libs/surfaceflinger/LayerBlur.cpp +++ b/libs/surfaceflinger/LayerBlur.cpp @@ -34,8 +34,8 @@ namespace android { // --------------------------------------------------------------------------- LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i) - : LayerBaseClient(flinger, display, client, i), mCacheDirty(true), + const sp& client) + : LayerBaseClient(flinger, display, client), mCacheDirty(true), mRefreshCache(true), mCacheAge(0), mTextureName(-1U), mWidthScale(1.0f), mHeightScale(1.0f), mBlurFormat(GGL_PIXEL_FORMAT_RGB_565) diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h index 380f58715..4c9ec647a 100644 --- a/libs/surfaceflinger/LayerBlur.h +++ b/libs/surfaceflinger/LayerBlur.h @@ -32,7 +32,7 @@ class LayerBlur : public LayerBaseClient { public: LayerBlur(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i); + const sp& client); virtual ~LayerBlur(); virtual void onDraw(const Region& clip) const; diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp index 8a582daa7..732a4ec1d 100644 --- a/libs/surfaceflinger/LayerBuffer.cpp +++ b/libs/surfaceflinger/LayerBuffer.cpp @@ -44,8 +44,8 @@ gralloc_module_t const* LayerBuffer::sGrallocModule = 0; // --------------------------------------------------------------------------- LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i) - : LayerBaseClient(flinger, display, client, i), + const sp& client) + : LayerBaseClient(flinger, display, client), mNeedsBlending(false), mBlitEngine(0) { } @@ -60,8 +60,7 @@ LayerBuffer::~LayerBuffer() void LayerBuffer::onFirstRef() { LayerBaseClient::onFirstRef(); - mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(), - const_cast(this)); + mSurface = new SurfaceLayerBuffer(mFlinger, this); hw_module_t const* module = (hw_module_t const*)sGrallocModule; if (!module) { @@ -204,9 +203,9 @@ sp LayerBuffer::clearSource() { // LayerBuffer::SurfaceLayerBuffer // ============================================================================ -LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(const sp& flinger, - SurfaceID id, const sp& owner) - : LayerBaseClient::Surface(flinger, id, owner->getIdentity(), owner) +LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer( + const sp& flinger, const sp& owner) + : LayerBaseClient::Surface(flinger, owner->getIdentity(), owner) { } diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h index d38dde225..413b8a45b 100644 --- a/libs/surfaceflinger/LayerBuffer.h +++ b/libs/surfaceflinger/LayerBuffer.h @@ -53,7 +53,7 @@ class LayerBuffer : public LayerBaseClient public: LayerBuffer(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i); + const sp& client); virtual ~LayerBuffer(); virtual void onFirstRef(); @@ -189,7 +189,7 @@ private: { public: SurfaceLayerBuffer(const sp& flinger, - SurfaceID id, const sp& owner); + const sp& owner); virtual ~SurfaceLayerBuffer(); virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp index 568fedbf0..d528d2ff7 100644 --- a/libs/surfaceflinger/LayerDim.cpp +++ b/libs/surfaceflinger/LayerDim.cpp @@ -39,8 +39,8 @@ int32_t LayerDim::sHeight; // --------------------------------------------------------------------------- LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i) - : LayerBaseClient(flinger, display, client, i) + const sp& client) + : LayerBaseClient(flinger, display, client) { } diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h index 19a9990a0..f0323149a 100644 --- a/libs/surfaceflinger/LayerDim.h +++ b/libs/surfaceflinger/LayerDim.h @@ -38,7 +38,7 @@ class LayerDim : public LayerBaseClient static int32_t sHeight; public: LayerDim(SurfaceFlinger* flinger, DisplayID display, - const sp& client, int32_t i); + const sp& client); virtual ~LayerDim(); virtual void onDraw(const Region& clip) const; diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index fff085392..e8d0d5b4e 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -227,54 +227,15 @@ sp SurfaceFlinger::getCblk() const sp SurfaceFlinger::createConnection() { - Mutex::Autolock _l(mStateLock); - uint32_t token = mTokens.acquire(); - - sp client = new Client(token, this); - if (client->ctrlblk == 0) { - mTokens.release(token); - return 0; + sp bclient; + sp client(new Client(this)); + status_t err = client->initCheck(); + if (err == NO_ERROR) { + bclient = client; } - status_t err = mClientsMap.add(token, client); - if (err < 0) { - mTokens.release(token); - return 0; - } - sp bclient = - new BClient(this, token, client->getControlBlockMemory()); return bclient; } -void SurfaceFlinger::destroyConnection(ClientID cid) -{ - Mutex::Autolock _l(mStateLock); - sp client = mClientsMap.valueFor(cid); - if (client != 0) { - // free all the layers this client owns - Vector< wp > layers(client->getLayers()); - const size_t count = layers.size(); - for (size_t i=0 ; i layer(layers[i].promote()); - if (layer != 0) { - purgatorizeLayer_l(layer); - } - } - - // the resources associated with this client will be freed - // during the next transaction, after these surfaces have been - // properly removed from the screen - - // remove this client from our ClientID->Client mapping. - mClientsMap.removeItem(cid); - - // and add it to the list of disconnected clients - mDisconnectedClients.add(client); - - // request a transaction - setTransactionFlags(eTransactionNeeded); - } -} - const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const { LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); @@ -665,10 +626,6 @@ void SurfaceFlinger::handleTransactionLocked( } } } - - // get rid of all resources we don't need anymore - // (layers and clients) - free_resources_l(); } commitTransaction(); @@ -1071,6 +1028,27 @@ status_t SurfaceFlinger::addLayer(const sp& layer) return NO_ERROR; } +status_t SurfaceFlinger::addLayer_l(const sp& layer) +{ + ssize_t i = mCurrentState.layersSortedByZ.add( + layer, &LayerBase::compareCurrentStateZ); + return (i < 0) ? status_t(i) : status_t(NO_ERROR); +} + +ssize_t SurfaceFlinger::addClientLayer(const sp& client, + const sp& lbc) +{ + Mutex::Autolock _l(mStateLock); + + // attach this layer to the client + ssize_t name = client->attachLayer(lbc); + + // add this layer to the current state list + addLayer_l(lbc); + + return name; +} + status_t SurfaceFlinger::removeLayer(const sp& layer) { Mutex::Autolock _l(mStateLock); @@ -1080,35 +1058,11 @@ status_t SurfaceFlinger::removeLayer(const sp& layer) return err; } -status_t SurfaceFlinger::invalidateLayerVisibility(const sp& layer) -{ - layer->forceVisibilityTransaction(); - setTransactionFlags(eTraversalNeeded); - return NO_ERROR; -} - -status_t SurfaceFlinger::addLayer_l(const sp& layer) -{ - ssize_t i = mCurrentState.layersSortedByZ.add( - layer, &LayerBase::compareCurrentStateZ); - return (i < 0) ? status_t(i) : status_t(NO_ERROR); -} - -status_t SurfaceFlinger::addClientLayer_l(const sp& lbc) -{ - ssize_t serverIndex = lbc->serverIndex(); - return mLayerMap.add(serverIndex, lbc); -} - status_t SurfaceFlinger::removeLayer_l(const sp& layerBase) { ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); if (index >= 0) { mLayersRemoved = true; - ssize_t serverIndex = layerBase->serverIndex(); - if (serverIndex >= 0) { - mLayerMap.removeItem(serverIndex); - } return NO_ERROR; } return status_t(index); @@ -1123,22 +1077,16 @@ status_t SurfaceFlinger::purgatorizeLayer_l(const sp& layerBase) // it's possible that we don't find a layer, because it might // have been destroyed already -- this is not technically an error - // from the user because there is a race between BClient::destroySurface(), - // ~BClient() and ~ISurface(). + // from the user because there is a race between Client::destroySurface(), + // ~Client() and ~ISurface(). return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; } - -void SurfaceFlinger::free_resources_l() +status_t SurfaceFlinger::invalidateLayerVisibility(const sp& layer) { - // free resources associated with disconnected clients - Vector< sp >& disconnectedClients(mDisconnectedClients); - const size_t count = disconnectedClients.size(); - for (size_t i=0 ; i client = disconnectedClients[i]; - mTokens.release(client->cid); - } - disconnectedClients.clear(); + layer->forceVisibilityTransaction(); + setTransactionFlags(eTraversalNeeded); + return NO_ERROR; } uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) @@ -1229,7 +1177,7 @@ int SurfaceFlinger::setOrientation(DisplayID dpy, return orientation; } -sp SurfaceFlinger::createSurface(ClientID clientId, int pid, +sp SurfaceFlinger::createSurface(const sp& client, int pid, const String8& name, ISurfaceComposerClient::surface_data_t* params, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) @@ -1243,57 +1191,44 @@ sp SurfaceFlinger::createSurface(ClientID clientId, int pid, return surfaceHandle; } - Mutex::Autolock _l(mStateLock); - sp client = mClientsMap.valueFor(clientId); - if (UNLIKELY(client == 0)) { - LOGE("createSurface() failed, client not found (id=%d)", clientId); - return surfaceHandle; - } - //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); - int32_t id = client->generateId(pid); - if (uint32_t(id) >= SharedBufferStack::NUM_LAYERS_MAX) { - LOGE("createSurface() failed, generateId = %d", id); - return surfaceHandle; - } - switch (flags & eFXSurfaceMask) { case eFXSurfaceNormal: if (UNLIKELY(flags & ePushBuffers)) { - layer = createPushBuffersSurfaceLocked(client, d, id, - w, h, flags); + layer = createPushBuffersSurface(client, d, w, h, flags); } else { - layer = createNormalSurfaceLocked(client, d, id, - w, h, flags, format); + layer = createNormalSurface(client, d, w, h, flags, format); } break; case eFXSurfaceBlur: - layer = createBlurSurfaceLocked(client, d, id, w, h, flags); + layer = createBlurSurface(client, d, w, h, flags); break; case eFXSurfaceDim: - layer = createDimSurfaceLocked(client, d, id, w, h, flags); + layer = createDimSurface(client, d, w, h, flags); break; } if (layer != 0) { + layer->initStates(w, h, flags); layer->setName(name); - setTransactionFlags(eTransactionNeeded); + ssize_t token = addClientLayer(client, layer); surfaceHandle = layer->getSurface(); if (surfaceHandle != 0) { - params->token = surfaceHandle->getToken(); + params->token = token; params->identity = surfaceHandle->getIdentity(); params->width = w; params->height = h; params->format = format; } + setTransactionFlags(eTransactionNeeded); } return surfaceHandle; } -sp SurfaceFlinger::createNormalSurfaceLocked( +sp SurfaceFlinger::createNormalSurface( const sp& client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, uint32_t flags, + uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format) { // initialize the surfaces @@ -1307,53 +1242,43 @@ sp SurfaceFlinger::createNormalSurfaceLocked( break; } - sp layer = new Layer(this, display, client, id); + sp layer = new Layer(this, display, client); status_t err = layer->setBuffers(w, h, format, flags); - if (LIKELY(err == NO_ERROR)) { - layer->initStates(w, h, flags); - addLayer_l(layer); - addClientLayer_l(layer); - } else { + if (LIKELY(err != NO_ERROR)) { LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); layer.clear(); } return layer; } -sp SurfaceFlinger::createBlurSurfaceLocked( +sp SurfaceFlinger::createBlurSurface( const sp& client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, uint32_t flags) + uint32_t w, uint32_t h, uint32_t flags) { - sp layer = new LayerBlur(this, display, client, id); + sp layer = new LayerBlur(this, display, client); layer->initStates(w, h, flags); - addLayer_l(layer); - addClientLayer_l(layer); return layer; } -sp SurfaceFlinger::createDimSurfaceLocked( +sp SurfaceFlinger::createDimSurface( const sp& client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, uint32_t flags) + uint32_t w, uint32_t h, uint32_t flags) { - sp layer = new LayerDim(this, display, client, id); + sp layer = new LayerDim(this, display, client); layer->initStates(w, h, flags); - addLayer_l(layer); - addClientLayer_l(layer); return layer; } -sp SurfaceFlinger::createPushBuffersSurfaceLocked( +sp SurfaceFlinger::createPushBuffersSurface( const sp& client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, uint32_t flags) + uint32_t w, uint32_t h, uint32_t flags) { - sp layer = new LayerBuffer(this, display, client, id); + sp layer = new LayerBuffer(this, display, client); layer->initStates(w, h, flags); - addLayer_l(layer); - addClientLayer_l(layer); return layer; } -status_t SurfaceFlinger::removeSurface(SurfaceID index) +status_t SurfaceFlinger::removeSurface(const sp& client, SurfaceID sid) { /* * called by the window manager, when a surface should be marked for @@ -1366,7 +1291,7 @@ status_t SurfaceFlinger::removeSurface(SurfaceID index) status_t err = NAME_NOT_FOUND; Mutex::Autolock _l(mStateLock); - sp layer = getLayerUser_l(index); + sp layer = client->getLayerUser(sid); if (layer != 0) { err = purgatorizeLayer_l(layer); if (err == NO_ERROR) { @@ -1411,16 +1336,15 @@ status_t SurfaceFlinger::destroySurface(const sp& layer) } status_t SurfaceFlinger::setClientState( - ClientID cid, + const sp& client, int32_t count, const layer_state_t* states) { Mutex::Autolock _l(mStateLock); uint32_t flags = 0; - cid <<= 16; for (int i=0 ; i layer(getLayerUser_l(s.surface | cid)); + const layer_state_t& s(states[i]); + sp layer(client->getLayerUser(s.surface)); if (layer != 0) { const uint32_t what = s.what; if (what & ePositionChanged) { @@ -1466,12 +1390,6 @@ status_t SurfaceFlinger::setClientState( return NO_ERROR; } -sp SurfaceFlinger::getLayerUser_l(SurfaceID s) const -{ - sp layer = mLayerMap.valueFor(s); - return layer; -} - void SurfaceFlinger::screenReleased(int dpy) { // this may be called by a signal handler, we can't do too much in here @@ -1557,8 +1475,6 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) result.append(buffer); } - snprintf(buffer, SIZE, " client count: %d\n", mClientsMap.size()); - result.append(buffer); const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); alloc.dump(result); @@ -1655,8 +1571,8 @@ status_t SurfaceFlinger::onTransact( #pragma mark - #endif -Client::Client(ClientID clientID, const sp& flinger) - : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger) +Client::Client(const sp& flinger) + : ctrlblk(0), mBitmap(0), mFlinger(flinger) { const int pgsize = getpagesize(); const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1)); @@ -1668,96 +1584,87 @@ Client::Client(ClientID clientID, const sp& flinger) if (ctrlblk) { // construct the shared structure in-place. new(ctrlblk) SharedClient; } + } -Client::~Client() { +Client::~Client() +{ if (ctrlblk) { ctrlblk->~SharedClient(); // destroy our shared-structure. } -} -int32_t Client::generateId(int pid) -{ - const uint32_t i = clz( ~mBitmap ); - if (i >= SharedBufferStack::NUM_LAYERS_MAX) { - return NO_MEMORY; - } - mPid = pid; - mInUse.add(uint8_t(i)); - mBitmap |= 1<<(31-i); - return i; -} - -status_t Client::bindLayer(const sp& layer, int32_t id) -{ - ssize_t idx = mInUse.indexOf(id); - if (idx < 0) - return NAME_NOT_FOUND; - return mLayers.insertAt(layer, idx); -} - -void Client::free(int32_t id) -{ - ssize_t idx = mInUse.remove(uint8_t(id)); - if (idx >= 0) { - mBitmap &= ~(1<<(31-id)); - mLayers.removeItemsAt(idx); + const size_t count = mLayers.size(); + for (size_t i=0 ; i layer(mLayers.valueAt(i).promote()); + if (layer != 0) { + mFlinger->removeLayer(layer); + } } } -bool Client::isValid(int32_t i) const { - return (uint32_t(i)& layer) +{ + // TODO: get rid of this + int32_t name = 0; + while (mBitmap & (1LU<= 31) + return NO_MEMORY; + } + mBitmap |= 1LU<setToken(name); + mLayers.add(name, layer); + return name; +} + +void Client::free(LayerBaseClient const* layer) +{ + // TODO: get rid of this + int32_t name = layer->getToken(); + if (name >= 0) { + mBitmap &= ~(1LU< Client::getLayerUser(int32_t i) const { sp lbc; - ssize_t idx = mInUse.indexOf(uint8_t(i)); - if (idx >= 0) { - lbc = mLayers[idx].promote(); - LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx)); + const wp& layer(mLayers.valueFor(i)); + if (layer != 0) { + lbc = layer.promote(); + LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); } return lbc; } -// --------------------------------------------------------------------------- -#if 0 -#pragma mark - -#endif - -BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp& cblk) - : mId(cid), mFlinger(flinger), mCblk(cblk) -{ +sp Client::getControlBlock() const { + return mCblkHeap; } - -BClient::~BClient() { - // destroy all resources attached to this client - mFlinger->destroyConnection(mId); -} - -sp BClient::getControlBlock() const { - return mCblk; -} - -sp BClient::createSurface( - ISurfaceComposerClient::surface_data_t* params, int pid, - const String8& name, - DisplayID display, uint32_t w, uint32_t h, PixelFormat format, +sp Client::createSurface( + ISurfaceComposerClient::surface_data_t* params, + int pid, const String8& name, + DisplayID display, uint32_t w, uint32_t h,PixelFormat format, uint32_t flags) { - return mFlinger->createSurface(mId, pid, name, params, display, w, h, - format, flags); + return mFlinger->createSurface(this, pid, name, params, + display, w, h, format, flags); } - -status_t BClient::destroySurface(SurfaceID sid) -{ - sid |= (mId << 16); // add the client-part to id - return mFlinger->removeSurface(sid); +status_t Client::destroySurface(SurfaceID sid) { + return mFlinger->removeSurface(this, sid); } - -status_t BClient::setState(int32_t count, const layer_state_t* states) -{ - return mFlinger->setClientState(mId, count, states); +status_t Client::setState(int32_t count, const layer_state_t* states) { + return mFlinger->setClientState(this, count, states); } // --------------------------------------------------------------------------- diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index d8fe98cf1..84134e0f6 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -36,7 +36,6 @@ #include "Barrier.h" #include "Layer.h" -#include "Tokenizer.h" #include "MessageQueue.h" @@ -48,54 +47,48 @@ namespace android { // --------------------------------------------------------------------------- class Client; -class BClient; class DisplayHardware; class FreezeLock; class Layer; class LayerBuffer; -typedef int32_t ClientID; - #define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) #define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) // --------------------------------------------------------------------------- -class Client : public RefBase +class Client : public BnSurfaceComposerClient { public: - Client(ClientID cid, const sp& flinger); - ~Client(); - - int32_t generateId(int pid); - void free(int32_t id); - status_t bindLayer(const sp& layer, int32_t id); - - inline bool isValid(int32_t i) const; - sp getLayerUser(int32_t i) const; - - const Vector< wp >& getLayers() const { - return mLayers; - } - - const sp& getControlBlockMemory() const { - return mCblkHeap; - } - // pointer to this client's control block - SharedClient* ctrlblk; - ClientID cid; + SharedClient* ctrlblk; + +public: + Client(const sp& flinger); + ~Client(); + + status_t initCheck() const; + + // protected by SurfaceFlinger::mStateLock + ssize_t attachLayer(const sp& layer); + sp getLayerUser(int32_t i) const; + void free(LayerBaseClient const* layer); - private: - int getClientPid() const { return mPid; } - - int mPid; - uint32_t mBitmap; - SortedVector mInUse; - Vector< wp > mLayers; - sp mCblkHeap; - sp mFlinger; + + // ISurfaceComposerClient interface + virtual sp getControlBlock() const; + virtual sp createSurface( + surface_data_t* params, int pid, const String8& name, + DisplayID display, uint32_t w, uint32_t h,PixelFormat format, + uint32_t flags); + virtual status_t destroySurface(SurfaceID surfaceId); + virtual status_t setState(int32_t count, const layer_state_t* states); + + uint32_t mBitmap; + DefaultKeyedVector< size_t, wp > mLayers; + sp mCblkHeap; + sp mFlinger; }; // --------------------------------------------------------------------------- @@ -179,7 +172,7 @@ public: status_t invalidateLayerVisibility(const sp& layer); private: - friend class BClient; + friend class Client; friend class LayerBase; friend class LayerBuffer; friend class LayerBaseClient; @@ -188,31 +181,33 @@ private: friend class LayerBlur; friend class LayerDim; - sp createSurface(ClientID client, int pid, const String8& name, + sp createSurface(const sp& client, + int pid, const String8& name, ISurfaceComposerClient::surface_data_t* params, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); - sp createNormalSurfaceLocked( + sp createNormalSurface( const sp& client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, uint32_t flags, + uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format); - sp createBlurSurfaceLocked( + sp createBlurSurface( const sp& client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, uint32_t flags); + uint32_t w, uint32_t h, uint32_t flags); - sp createDimSurfaceLocked( + sp createDimSurface( const sp& client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, uint32_t flags); + uint32_t w, uint32_t h, uint32_t flags); - sp createPushBuffersSurfaceLocked( + sp createPushBuffersSurface( const sp& client, DisplayID display, - int32_t id, uint32_t w, uint32_t h, uint32_t flags); + uint32_t w, uint32_t h, uint32_t flags); - status_t removeSurface(SurfaceID surface_id); + status_t removeSurface(const sp& client, SurfaceID sid); status_t destroySurface(const sp& layer); - status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states); + status_t setClientState(const sp& client, + int32_t count, const layer_state_t* states); class LayerVector { @@ -275,13 +270,11 @@ private: void unlockClients(); - void destroyConnection(ClientID cid); - sp getLayerUser_l(SurfaceID index) const; + ssize_t addClientLayer(const sp& client, + const sp& lbc); status_t addLayer_l(const sp& layer); - status_t addClientLayer_l(const sp& lbc); status_t removeLayer_l(const sp& layer); status_t purgatorizeLayer_l(const sp& layer); - void free_resources_l(); uint32_t getTransactionFlags(uint32_t flags); uint32_t setTransactionFlags(uint32_t flags); @@ -324,14 +317,10 @@ private: volatile int32_t mTransactionCount; Condition mTransactionCV; bool mResizeTransationPending; - + // protected by mStateLock (but we could use another lock) - Tokenizer mTokens; - DefaultKeyedVector > mClientsMap; - DefaultKeyedVector > mLayerMap; - GraphicPlane mGraphicPlanes[1]; - bool mLayersRemoved; - Vector< sp > mDisconnectedClients; + GraphicPlane mGraphicPlanes[1]; + bool mLayersRemoved; // constant members (no synchronization needed for access) sp mServerHeap; @@ -391,32 +380,6 @@ public: } }; -// --------------------------------------------------------------------------- - -class BClient : public BnSurfaceComposerClient -{ -public: - BClient(SurfaceFlinger *flinger, ClientID cid, - const sp& cblk); - ~BClient(); - - // ISurfaceComposerClient interface - virtual sp getControlBlock() const; - - virtual sp createSurface( - surface_data_t* params, int pid, const String8& name, - DisplayID display, uint32_t w, uint32_t h,PixelFormat format, - uint32_t flags); - - virtual status_t destroySurface(SurfaceID surfaceId); - virtual status_t setState(int32_t count, const layer_state_t* states); - -private: - ClientID mId; - SurfaceFlinger* mFlinger; - sp mCblk; -}; - // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp deleted file mode 100644 index be3a23983..000000000 --- a/libs/surfaceflinger/Tokenizer.cpp +++ /dev/null @@ -1,173 +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 "Tokenizer.h" - -// ---------------------------------------------------------------------------- - -namespace android { - -ANDROID_BASIC_TYPES_TRAITS(Tokenizer::run_t) - -Tokenizer::Tokenizer() -{ -} - -Tokenizer::Tokenizer(const Tokenizer& other) - : mRanges(other.mRanges) -{ -} - -Tokenizer::~Tokenizer() -{ -} - -uint32_t Tokenizer::acquire() -{ - if (!mRanges.size() || mRanges[0].first) { - _insertTokenAt(0,0); - return 0; - } - - // just extend the first run - const run_t& run = mRanges[0]; - uint32_t token = run.first + run.length; - _insertTokenAt(token, 1); - return token; -} - -bool Tokenizer::isAcquired(uint32_t token) const -{ - return (_indexOrderOf(token) >= 0); -} - -status_t Tokenizer::reserve(uint32_t token) -{ - size_t o; - const ssize_t i = _indexOrderOf(token, &o); - if (i >= 0) { - return BAD_VALUE; // this token is already taken - } - ssize_t err = _insertTokenAt(token, o); - return (err<0) ? err : status_t(NO_ERROR); -} - -status_t Tokenizer::release(uint32_t token) -{ - const ssize_t i = _indexOrderOf(token); - if (i >= 0) { - const run_t& run = mRanges[i]; - if ((token >= run.first) && (token < run.first+run.length)) { - // token in this range, we need to split - run_t& run = mRanges.editItemAt(i); - if ((token == run.first) || (token == run.first+run.length-1)) { - if (token == run.first) { - run.first += 1; - } - run.length -= 1; - if (run.length == 0) { - // XXX: should we systematically remove a run that's empty? - mRanges.removeItemsAt(i); - } - } else { - // split the run - run_t new_run; - new_run.first = token+1; - new_run.length = run.first+run.length - new_run.first; - run.length = token - run.first; - mRanges.insertAt(new_run, i+1); - } - return NO_ERROR; - } - } - return NAME_NOT_FOUND; -} - -ssize_t Tokenizer::_indexOrderOf(uint32_t token, size_t* order) const -{ - // binary search - ssize_t err = NAME_NOT_FOUND; - ssize_t l = 0; - ssize_t h = mRanges.size()-1; - ssize_t mid; - const run_t* a = mRanges.array(); - while (l <= h) { - mid = l + (h - l)/2; - const run_t* const curr = a + mid; - int c = 0; - if (token < curr->first) c = 1; - else if (token >= curr->first+curr->length) c = -1; - if (c == 0) { - err = l = mid; - break; - } else if (c < 0) { - l = mid + 1; - } else { - h = mid - 1; - } - } - if (order) *order = l; - return err; -} - -ssize_t Tokenizer::_insertTokenAt(uint32_t token, size_t index) -{ - const size_t c = mRanges.size(); - - if (index >= 1) { - // do we need to merge with the previous run? - run_t& p = mRanges.editItemAt(index-1); - if (p.first+p.length == token) { - p.length += 1; - if (index < c) { - const run_t& n = mRanges[index]; - if (token+1 == n.first) { - p.length += n.length; - mRanges.removeItemsAt(index); - } - } - return index; - } - } - - if (index < c) { - // do we need to merge with the next run? - run_t& n = mRanges.editItemAt(index); - if (token+1 == n.first) { - n.first -= 1; - n.length += 1; - return index; - } - } - - return mRanges.insertAt(run_t(token,1), index); -} - -void Tokenizer::dump() const -{ - const run_t* ranges = mRanges.array(); - const size_t c = mRanges.size(); - printf("Tokenizer (%p, size = %d)\n", this, int(c)); - for (size_t i=0 ; i -#include - -// ---------------------------------------------------------------------------- - -namespace android { - -class Tokenizer -{ -public: - Tokenizer(); - Tokenizer(const Tokenizer& other); - ~Tokenizer(); - - uint32_t acquire(); - status_t reserve(uint32_t token); - status_t release(uint32_t token); - bool isAcquired(uint32_t token) const; - - void dump() const; - - struct run_t { - run_t() {}; - run_t(uint32_t f, uint32_t l) : first(f), length(l) {} - uint32_t first; - uint32_t length; - }; -private: - ssize_t _indexOrderOf(uint32_t token, size_t* order=0) const; - ssize_t _insertTokenAt(uint32_t token, size_t index); - Vector mRanges; -}; - -}; // namespace android - -// ---------------------------------------------------------------------------- - -#endif // ANDROID_TOKENIZER_H