diff options
author | Mathias Agopian <mathias@google.com> | 2011-06-28 19:09:31 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2011-06-29 15:05:41 -0700 |
commit | 439863f3b3e725b5de1cba4940a21900369961c0 (patch) | |
tree | 90ab56432c2436c3392b02ba08876c86796a36ef /services | |
parent | f1bfa84ccf61cad2b6ea9f2e6a612a54a38b79bc (diff) | |
download | frameworks_base-439863f3b3e725b5de1cba4940a21900369961c0.zip frameworks_base-439863f3b3e725b5de1cba4940a21900369961c0.tar.gz frameworks_base-439863f3b3e725b5de1cba4940a21900369961c0.tar.bz2 |
SF transactions are now O(1) wrt IPC instead of O(N).
Change-Id: I57669852cbf6aabae244ea86940a08a5a27ffc43
Diffstat (limited to 'services')
-rw-r--r-- | services/input/SpriteController.cpp | 11 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 150 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 9 | ||||
-rw-r--r-- | services/surfaceflinger/tests/resize/resize.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/tests/surface/surface.cpp | 4 |
5 files changed, 80 insertions, 102 deletions
diff --git a/services/input/SpriteController.cpp b/services/input/SpriteController.cpp index 08cc75e..0ae2ab8 100644 --- a/services/input/SpriteController.cpp +++ b/services/input/SpriteController.cpp @@ -252,11 +252,7 @@ void SpriteController::doUpdateSprites() { | DIRTY_VISIBILITY | DIRTY_HOTSPOT))))) { status_t status; if (!haveTransaction) { - status = mSurfaceComposerClient->openTransaction(); - if (status) { - LOGE("Error %d opening transation to update sprite surface.", status); - break; - } + SurfaceComposerClient::openGlobalTransaction(); haveTransaction = true; } @@ -322,10 +318,7 @@ void SpriteController::doUpdateSprites() { } if (haveTransaction) { - status_t status = mSurfaceComposerClient->closeTransaction(); - if (status) { - LOGE("Error %d closing transaction to update sprite surface.", status); - } + SurfaceComposerClient::closeGlobalTransaction(); } // If any surfaces were changed, write back the new surface properties to the sprites. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index f0b19f2..1c57bc1 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -78,7 +78,6 @@ const String16 sDump("android.permission.DUMP"); SurfaceFlinger::SurfaceFlinger() : BnSurfaceComposer(), Thread(false), mTransactionFlags(0), - mTransactionCount(0), mResizeTransationPending(false), mLayersRemoved(false), mBootTime(systemTime()), @@ -385,13 +384,11 @@ bool SurfaceFlinger::threadLoop() handleConsoleEvents(); } - if (LIKELY(mTransactionCount == 0)) { - // if we're in a global transaction, don't do anything. - const uint32_t mask = eTransactionNeeded | eTraversalNeeded; - uint32_t transactionFlags = peekTransactionFlags(mask); - if (LIKELY(transactionFlags)) { - handleTransaction(transactionFlags); - } + // if we're in a global transaction, don't do anything. + const uint32_t mask = eTransactionNeeded | eTraversalNeeded; + uint32_t transactionFlags = peekTransactionFlags(mask); + if (UNLIKELY(transactionFlags)) { + handleTransaction(transactionFlags); } // post surfaces (if needed) @@ -1176,28 +1173,33 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) return old; } -void SurfaceFlinger::openGlobalTransaction() -{ - android_atomic_inc(&mTransactionCount); -} -void SurfaceFlinger::closeGlobalTransaction() -{ - if (android_atomic_dec(&mTransactionCount) == 1) { - signalEvent(); +void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state) { + Mutex::Autolock _l(mStateLock); - // if there is a transaction with a resize, wait for it to - // take effect before returning. - Mutex::Autolock _l(mStateLock); - while (mResizeTransationPending) { - status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); - if (CC_UNLIKELY(err != NO_ERROR)) { - // just in case something goes wrong in SF, return to the - // called after a few seconds. - LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); - mResizeTransationPending = false; - break; - } + uint32_t flags = 0; + const size_t count = state.size(); + for (size_t i=0 ; i<count ; i++) { + const ComposerState& s(state[i]); + sp<Client> client( static_cast<Client *>(s.client.get()) ); + flags |= setClientStateLocked(client, s.state); + } + if (flags) { + setTransactionFlags(flags); + } + + signalEvent(); + + // if there is a transaction with a resize, wait for it to + // take effect before returning. + while (mResizeTransationPending) { + status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); + if (CC_UNLIKELY(err != NO_ERROR)) { + // just in case something goes wrong in SF, return to the + // called after a few seconds. + LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); + mResizeTransationPending = false; + break; } } } @@ -1393,60 +1395,52 @@ status_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) return err; } -status_t SurfaceFlinger::setClientState( +uint32_t SurfaceFlinger::setClientStateLocked( const sp<Client>& client, - int32_t count, - const layer_state_t* states) + const layer_state_t& s) { - Mutex::Autolock _l(mStateLock); uint32_t flags = 0; - for (int i=0 ; i<count ; i++) { - const layer_state_t& s(states[i]); - sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); - if (layer != 0) { - const uint32_t what = s.what; - if (what & ePositionChanged) { - if (layer->setPosition(s.x, s.y)) - flags |= eTraversalNeeded; - } - if (what & eLayerChanged) { - ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); - if (layer->setLayer(s.z)) { - mCurrentState.layersSortedByZ.removeAt(idx); - mCurrentState.layersSortedByZ.add(layer); - // we need traversal (state changed) - // AND transaction (list changed) - flags |= eTransactionNeeded|eTraversalNeeded; - } - } - if (what & eSizeChanged) { - if (layer->setSize(s.w, s.h)) { - flags |= eTraversalNeeded; - mResizeTransationPending = true; - } - } - if (what & eAlphaChanged) { - if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) - flags |= eTraversalNeeded; - } - if (what & eMatrixChanged) { - if (layer->setMatrix(s.matrix)) - flags |= eTraversalNeeded; - } - if (what & eTransparentRegionChanged) { - if (layer->setTransparentRegionHint(s.transparentRegion)) - flags |= eTraversalNeeded; + sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); + if (layer != 0) { + const uint32_t what = s.what; + if (what & ePositionChanged) { + if (layer->setPosition(s.x, s.y)) + flags |= eTraversalNeeded; + } + if (what & eLayerChanged) { + ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); + if (layer->setLayer(s.z)) { + mCurrentState.layersSortedByZ.removeAt(idx); + mCurrentState.layersSortedByZ.add(layer); + // we need traversal (state changed) + // AND transaction (list changed) + flags |= eTransactionNeeded|eTraversalNeeded; } - if (what & eVisibilityChanged) { - if (layer->setFlags(s.flags, s.mask)) - flags |= eTraversalNeeded; + } + if (what & eSizeChanged) { + if (layer->setSize(s.w, s.h)) { + flags |= eTraversalNeeded; + mResizeTransationPending = true; } } + if (what & eAlphaChanged) { + if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) + flags |= eTraversalNeeded; + } + if (what & eMatrixChanged) { + if (layer->setMatrix(s.matrix)) + flags |= eTraversalNeeded; + } + if (what & eTransparentRegionChanged) { + if (layer->setTransparentRegionHint(s.transparentRegion)) + flags |= eTraversalNeeded; + } + if (what & eVisibilityChanged) { + if (layer->setFlags(s.flags, s.mask)) + flags |= eTraversalNeeded; + } } - if (flags) { - setTransactionFlags(flags); - } - return NO_ERROR; + return flags; } void SurfaceFlinger::screenReleased(int dpy) @@ -1588,8 +1582,7 @@ status_t SurfaceFlinger::onTransact( { switch (code) { case CREATE_CONNECTION: - case OPEN_GLOBAL_TRANSACTION: - case CLOSE_GLOBAL_TRANSACTION: + case SET_TRANSACTION_STATE: case SET_ORIENTATION: case FREEZE_DISPLAY: case UNFREEZE_DISPLAY: @@ -2469,9 +2462,6 @@ sp<ISurface> Client::createSurface( status_t Client::destroySurface(SurfaceID sid) { return mFlinger->removeSurface(this, sid); } -status_t Client::setState(int32_t count, const layer_state_t* states) { - return mFlinger->setClientState(this, count, states); -} // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 45f80ae..b49fa36 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -70,14 +70,12 @@ public: sp<LayerBaseClient> getLayerUser(int32_t i) const; private: - // ISurfaceComposerClient interface virtual sp<ISurface> createSurface( surface_data_t* params, 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); virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); @@ -168,8 +166,7 @@ public: virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc(); virtual sp<IMemoryHeap> getCblk() const; virtual void bootFinished(); - virtual void openGlobalTransaction(); - virtual void closeGlobalTransaction(); + virtual void setTransactionState(const Vector<ComposerState>& state); virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags); virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags); virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags); @@ -220,8 +217,7 @@ private: status_t removeSurface(const sp<Client>& client, SurfaceID sid); status_t destroySurface(const wp<LayerBaseClient>& layer); - status_t setClientState(const sp<Client>& client, - int32_t count, const layer_state_t* states); + uint32_t setClientStateLocked(const sp<Client>& client, const layer_state_t& s); class LayerVector : public SortedVector< sp<LayerBase> > { public: @@ -337,7 +333,6 @@ private: mutable Mutex mStateLock; State mCurrentState; volatile int32_t mTransactionFlags; - volatile int32_t mTransactionCount; Condition mTransactionCV; SortedVector< sp<LayerBase> > mLayerPurgatory; bool mResizeTransationPending; diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp index 18c54b3..56b2a8f 100644 --- a/services/surfaceflinger/tests/resize/resize.cpp +++ b/services/surfaceflinger/tests/resize/resize.cpp @@ -43,9 +43,9 @@ int main(int argc, char** argv) PIXEL_FORMAT_RGB_565); - client->openTransaction(); + SurfaceComposerClient::openGlobalTransaction(); surface->setLayer(100000); - client->closeTransaction(); + SurfaceComposerClient::closeGlobalTransaction(); Surface::SurfaceInfo info; surface->lock(&info); @@ -57,9 +57,9 @@ int main(int argc, char** argv) android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h); surface->unlockAndPost(); - client->openTransaction(); + SurfaceComposerClient::openGlobalTransaction(); surface->setSize(320, 240); - client->closeTransaction(); + SurfaceComposerClient::closeGlobalTransaction(); IPCThreadState::self()->joinThreadPool(); diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp index 5265f91..8e1c3fe 100644 --- a/services/surfaceflinger/tests/surface/surface.cpp +++ b/services/surfaceflinger/tests/surface/surface.cpp @@ -39,9 +39,9 @@ int main(int argc, char** argv) sp<SurfaceControl> surfaceControl = client->createSurface( getpid(), 0, 160, 240, PIXEL_FORMAT_RGB_565); - client->openTransaction(); + SurfaceComposerClient::openGlobalTransaction(); surfaceControl->setLayer(100000); - client->closeTransaction(); + SurfaceComposerClient::closeGlobalTransaction(); // pretend it went cross-process Parcel parcel; |