summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp72
1 files changed, 39 insertions, 33 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a9fa1ef..e8f0328 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -395,7 +395,7 @@ bool SurfaceFlinger::threadLoop()
if (LIKELY(mTransactionCount == 0)) {
// if we're in a global transaction, don't do anything.
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
- uint32_t transactionFlags = getTransactionFlags(mask);
+ uint32_t transactionFlags = peekTransactionFlags(mask);
if (LIKELY(transactionFlags)) {
handleTransaction(transactionFlags);
}
@@ -490,7 +490,17 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
Mutex::Autolock _l(mStateLock);
const nsecs_t now = systemTime();
mDebugInTransaction = now;
+
+ // Here we're guaranteed that some transaction flags are set
+ // so we can call handleTransactionLocked() unconditionally.
+ // We call getTransactionFlags(), which will also clear the flags,
+ // with mStateLock held to guarantee that mCurrentState won't change
+ // until the transaction is commited.
+
+ const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
+ transactionFlags = getTransactionFlags(mask);
handleTransactionLocked(transactionFlags, ditchedLayers);
+
mLastTransactionTime = systemTime() - now;
mDebugInTransaction = 0;
invalidateHwcGeometry();
@@ -600,7 +610,7 @@ sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
}
void SurfaceFlinger::computeVisibleRegions(
- LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
+ const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
{
const GraphicPlane& plane(graphicPlane(0));
const Transform& planeTransform(plane.transform());
@@ -735,8 +745,7 @@ void SurfaceFlinger::commitTransaction()
void SurfaceFlinger::handlePageFlip()
{
bool visibleRegions = mVisibleRegionsDirty;
- LayerVector& currentLayers(
- const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
+ const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
visibleRegions |= lockPageFlip(currentLayers);
const DisplayHardware& hw = graphicPlane(0).displayHardware();
@@ -748,9 +757,8 @@ void SurfaceFlinger::handlePageFlip()
/*
* rebuild the visible layer list
*/
+ const size_t count = currentLayers.size();
mVisibleLayersSortedByZ.clear();
- const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
- size_t count = currentLayers.size();
mVisibleLayersSortedByZ.setCapacity(count);
for (size_t i=0 ; i<count ; i++) {
if (!currentLayers[i]->visibleRegionScreen.isEmpty())
@@ -1096,15 +1104,15 @@ status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
const sp<LayerBaseClient>& lbc)
{
- Mutex::Autolock _l(mStateLock);
-
// attach this layer to the client
- ssize_t name = client->attachLayer(lbc);
+ size_t name = client->attachLayer(lbc);
+
+ Mutex::Autolock _l(mStateLock);
// add this layer to the current state list
addLayer_l(lbc);
- return name;
+ return ssize_t(name);
}
status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
@@ -1155,6 +1163,11 @@ status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
return NO_ERROR;
}
+uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
+{
+ return android_atomic_release_load(&mTransactionFlags);
+}
+
uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
{
return android_atomic_and(~flags, &mTransactionFlags) & flags;
@@ -1243,8 +1256,10 @@ int SurfaceFlinger::setOrientation(DisplayID dpy,
return orientation;
}
-sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
- const String8& name, ISurfaceComposerClient::surface_data_t* params,
+sp<ISurface> SurfaceFlinger::createSurface(
+ ISurfaceComposerClient::surface_data_t* params,
+ const String8& name,
+ const sp<Client>& client,
DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
@@ -2381,15 +2396,17 @@ status_t Client::initCheck() const {
return NO_ERROR;
}
-ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
+size_t Client::attachLayer(const sp<LayerBaseClient>& layer)
{
- int32_t name = android_atomic_inc(&mNameGenerator);
+ Mutex::Autolock _l(mLock);
+ size_t name = mNameGenerator++;
mLayers.add(name, layer);
return name;
}
void Client::detachLayer(const LayerBaseClient* layer)
{
+ Mutex::Autolock _l(mLock);
// we do a linear search here, because this doesn't happen often
const size_t count = mLayers.size();
for (size_t i=0 ; i<count ; i++) {
@@ -2399,9 +2416,11 @@ void Client::detachLayer(const LayerBaseClient* layer)
}
}
}
-sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
+sp<LayerBaseClient> Client::getLayerUser(int32_t i) const
+{
+ Mutex::Autolock _l(mLock);
sp<LayerBaseClient> lbc;
- const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
+ wp<LayerBaseClient> layer(mLayers.valueFor(i));
if (layer != 0) {
lbc = layer.promote();
LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
@@ -2416,12 +2435,12 @@ ssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
return -1;
}
sp<ISurface> Client::createSurface(
- ISurfaceComposerClient::surface_data_t* params, int pid,
+ ISurfaceComposerClient::surface_data_t* params,
const String8& name,
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
- return mFlinger->createSurface(this, pid, name, params,
+ return mFlinger->createSurface(params, name, this,
display, w, h, format, flags);
}
status_t Client::destroySurface(SurfaceID sid) {
@@ -2515,7 +2534,7 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
}
break;
}
- if (++name >= SharedBufferStack::NUM_LAYERS_MAX)
+ if (++name >= int32_t(SharedBufferStack::NUM_LAYERS_MAX))
name = NO_MEMORY;
} while(name >= 0);
@@ -2525,7 +2544,7 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
}
sp<ISurface> UserClient::createSurface(
- ISurfaceComposerClient::surface_data_t* params, int pid,
+ ISurfaceComposerClient::surface_data_t* params,
const String8& name,
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags) {
@@ -2555,22 +2574,9 @@ sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h
LOGE("createGraphicBuffer: unable to create GraphicBuffer");
return 0;
}
- Mutex::Autolock _l(mLock);
- mBuffers.add(graphicBuffer);
return graphicBuffer;
}
-void GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) {
- Mutex::Autolock _l(mLock);
- if (0 <= bufIdx && bufIdx < mBuffers.size()) {
- sp<GraphicBuffer> b(mBuffers[bufIdx]);
- mBuffers.clear();
- mBuffers.add(b);
- } else {
- mBuffers.clear();
- }
-}
-
// ---------------------------------------------------------------------------
GraphicPlane::GraphicPlane()