am f84a2182: Merge change 24643 into eclair
Merge commit 'f84a21820b39dbfa983352b7d8ac949e560827d3' into eclair-plus-aosp * commit 'f84a21820b39dbfa983352b7d8ac949e560827d3': fix [2112575] stuck on DequeueCondition for a surface that doesn't exist anymore
This commit is contained in:
@@ -85,6 +85,7 @@ class SharedBufferStack
|
||||
|
||||
public:
|
||||
SharedBufferStack();
|
||||
void init(int32_t identity);
|
||||
status_t setDirtyRegion(int buffer, const Region& reg);
|
||||
Region getDirtyRegion(int buffer) const;
|
||||
|
||||
@@ -114,7 +115,6 @@ public:
|
||||
|
||||
status_t validate(size_t token) const;
|
||||
uint32_t getIdentity(size_t token) const;
|
||||
status_t setIdentity(size_t token, uint32_t identity);
|
||||
|
||||
private:
|
||||
friend class SharedBufferBase;
|
||||
@@ -262,7 +262,8 @@ private:
|
||||
class SharedBufferServer : public SharedBufferBase
|
||||
{
|
||||
public:
|
||||
SharedBufferServer(SharedClient* sharedClient, int surface, int num);
|
||||
SharedBufferServer(SharedClient* sharedClient, int surface, int num,
|
||||
int32_t identity);
|
||||
|
||||
ssize_t retireAndLock();
|
||||
status_t unlock(int buffer);
|
||||
|
||||
@@ -49,13 +49,12 @@ const char* const Layer::typeID = "Layer";
|
||||
|
||||
Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
|
||||
const sp<Client>& c, int32_t i)
|
||||
: LayerBaseClient(flinger, display, c, i), lcblk(NULL),
|
||||
: LayerBaseClient(flinger, display, c, i),
|
||||
mSecure(false),
|
||||
mNeedsBlending(true)
|
||||
{
|
||||
// no OpenGL operation is possible here, since we might not be
|
||||
// in the OpenGL thread.
|
||||
lcblk = new SharedBufferServer(c->ctrlblk, i, NUM_BUFFERS);
|
||||
mFrontBufferIndex = lcblk->getFrontBuffer();
|
||||
}
|
||||
|
||||
@@ -63,8 +62,14 @@ Layer::~Layer()
|
||||
{
|
||||
destroy();
|
||||
// the actual buffers will be destroyed here
|
||||
delete lcblk;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
void Layer::destroy()
|
||||
@@ -79,7 +84,9 @@ void Layer::destroy()
|
||||
eglDestroyImageKHR(dpy, mTextures[i].image);
|
||||
mTextures[i].image = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
Mutex::Autolock _l(mLock);
|
||||
mBuffers[i].clear();
|
||||
mWidth = mHeight = 0;
|
||||
}
|
||||
mSurface.clear();
|
||||
}
|
||||
@@ -213,6 +220,16 @@ void Layer::onDraw(const Region& clip) const
|
||||
|
||||
sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage)
|
||||
{
|
||||
sp<Buffer> buffer;
|
||||
|
||||
// this ensures our client doesn't go away while we're accessing
|
||||
// the shared area.
|
||||
sp<Client> ourClient(client.promote());
|
||||
if (ourClient == 0) {
|
||||
// oops, the client is already gone
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called from the client's Surface::dequeue(). This can happen
|
||||
* at any time, especially while we're in the middle of using the
|
||||
@@ -225,12 +242,21 @@ sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage)
|
||||
*/
|
||||
status_t err = lcblk->assertReallocate(index);
|
||||
LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
|
||||
if (err != NO_ERROR) {
|
||||
// the surface may have died
|
||||
return buffer;
|
||||
}
|
||||
|
||||
uint32_t w, h;
|
||||
{ // scope for the lock
|
||||
Mutex::Autolock _l(mLock);
|
||||
w = mWidth;
|
||||
h = mHeight;
|
||||
buffer = mBuffers[index];
|
||||
mBuffers[index].clear();
|
||||
}
|
||||
|
||||
|
||||
Mutex::Autolock _l(mLock);
|
||||
uint32_t w = mWidth;
|
||||
uint32_t h = mHeight;
|
||||
|
||||
sp<Buffer>& buffer(mBuffers[index]);
|
||||
if (buffer->getStrongCount() == 1) {
|
||||
err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags);
|
||||
} else {
|
||||
@@ -253,8 +279,16 @@ sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage)
|
||||
}
|
||||
|
||||
if (err == NO_ERROR && buffer->handle != 0) {
|
||||
// texture is now dirty...
|
||||
mTextures[index].dirty = true;
|
||||
Mutex::Autolock _l(mLock);
|
||||
if (mWidth && mHeight) {
|
||||
// and we have new buffer
|
||||
mBuffers[index] = buffer;
|
||||
// texture is now dirty...
|
||||
mTextures[index].dirty = true;
|
||||
} else {
|
||||
// oops we got killed while we were allocating the buffer
|
||||
buffer.clear();
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -51,10 +51,6 @@ public:
|
||||
static const char* const typeID;
|
||||
virtual char const* getTypeID() const { return typeID; }
|
||||
virtual uint32_t getTypeInfo() const { return typeInfo; }
|
||||
|
||||
|
||||
SharedBufferServer* lcblk;
|
||||
|
||||
|
||||
Layer(SurfaceFlinger* flinger, DisplayID display,
|
||||
const sp<Client>& client, int32_t i);
|
||||
@@ -88,6 +84,8 @@ private:
|
||||
return mBuffers[mFrontBufferIndex];
|
||||
}
|
||||
|
||||
virtual void onRemoved();
|
||||
|
||||
void reloadTexture(const Region& dirty);
|
||||
|
||||
sp<SurfaceBuffer> requestBuffer(int index, int usage);
|
||||
|
||||
@@ -642,9 +642,12 @@ int32_t LayerBaseClient::sIdentity = 0;
|
||||
|
||||
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
||||
const sp<Client>& client, int32_t i)
|
||||
: LayerBase(flinger, display), client(client),
|
||||
: LayerBase(flinger, display), lcblk(NULL), client(client),
|
||||
mIndex(i), mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
|
||||
{
|
||||
lcblk = new SharedBufferServer(
|
||||
client->ctrlblk, i, NUM_BUFFERS,
|
||||
mIdentity);
|
||||
}
|
||||
|
||||
void LayerBaseClient::onFirstRef()
|
||||
@@ -652,8 +655,6 @@ void LayerBaseClient::onFirstRef()
|
||||
sp<Client> client(this->client.promote());
|
||||
if (client != 0) {
|
||||
client->bindLayer(this, mIndex);
|
||||
// Initialize this layer's identity
|
||||
client->ctrlblk->setIdentity(mIndex, mIdentity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,6 +664,7 @@ LayerBaseClient::~LayerBaseClient()
|
||||
if (client != 0) {
|
||||
client->free(mIndex);
|
||||
}
|
||||
delete lcblk;
|
||||
}
|
||||
|
||||
int32_t LayerBaseClient::serverIndex() const
|
||||
|
||||
@@ -292,13 +292,16 @@ public:
|
||||
virtual char const* getTypeID() const { return typeID; }
|
||||
virtual uint32_t getTypeInfo() const { return typeInfo; }
|
||||
|
||||
// lcblk is (almost) only accessed from the main SF thread, in the places
|
||||
// where it's not, a reference to Client must be held
|
||||
SharedBufferServer* lcblk;
|
||||
|
||||
LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
|
||||
const sp<Client>& client, int32_t i);
|
||||
virtual ~LayerBaseClient();
|
||||
virtual void onFirstRef();
|
||||
|
||||
wp<Client> client;
|
||||
// SharedBufferServer* lcblk;
|
||||
const wp<Client> client;
|
||||
|
||||
inline uint32_t getIdentity() const { return mIdentity; }
|
||||
inline int32_t clientIndex() const { return mIndex; }
|
||||
@@ -308,6 +311,7 @@ public:
|
||||
sp<Surface> getSurface();
|
||||
virtual sp<Surface> createSurface() const;
|
||||
|
||||
virtual void onRemoved() { }
|
||||
|
||||
class Surface : public BnSurface
|
||||
{
|
||||
|
||||
@@ -654,6 +654,7 @@ void SurfaceFlinger::handleTransactionLocked(
|
||||
// some layers might have been removed, so
|
||||
// we need to update the regions they're exposing.
|
||||
if (mLayersRemoved) {
|
||||
mLayersRemoved = false;
|
||||
mVisibleRegionsDirty = true;
|
||||
const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
|
||||
const size_t count = previousLayers.size();
|
||||
@@ -1093,9 +1094,6 @@ status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
|
||||
|
||||
void SurfaceFlinger::free_resources_l()
|
||||
{
|
||||
// Destroy layers that were removed
|
||||
mLayersRemoved = false;
|
||||
|
||||
// free resources associated with disconnected clients
|
||||
Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
|
||||
const size_t count = disconnectedClients.size();
|
||||
@@ -1321,11 +1319,15 @@ status_t SurfaceFlinger::removeSurface(SurfaceID index)
|
||||
* to wait for all client's references to go away first).
|
||||
*/
|
||||
|
||||
status_t err = NAME_NOT_FOUND;
|
||||
Mutex::Autolock _l(mStateLock);
|
||||
sp<LayerBaseClient> layer = getLayerUser_l(index);
|
||||
status_t err = purgatorizeLayer_l(layer);
|
||||
if (err == NO_ERROR) {
|
||||
setTransactionFlags(eTransactionNeeded);
|
||||
if (layer != 0) {
|
||||
err = purgatorizeLayer_l(layer);
|
||||
if (err == NO_ERROR) {
|
||||
layer->onRemoved();
|
||||
setTransactionFlags(eTransactionNeeded);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -53,21 +53,20 @@ uint32_t SharedClient::getIdentity(size_t token) const {
|
||||
return uint32_t(surfaces[token].identity);
|
||||
}
|
||||
|
||||
status_t SharedClient::setIdentity(size_t token, uint32_t identity) {
|
||||
if (token >= NUM_LAYERS_MAX)
|
||||
return BAD_INDEX;
|
||||
surfaces[token].identity = identity;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
SharedBufferStack::SharedBufferStack()
|
||||
: inUse(-1), status(NO_ERROR), identity(-1)
|
||||
{
|
||||
}
|
||||
|
||||
void SharedBufferStack::init(int32_t i)
|
||||
{
|
||||
inUse = -1;
|
||||
status = NO_ERROR;
|
||||
identity = i;
|
||||
}
|
||||
|
||||
status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
|
||||
{
|
||||
if (uint32_t(buffer) >= NUM_BUFFER_MAX)
|
||||
@@ -312,9 +311,10 @@ status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
|
||||
int surface, int num)
|
||||
int surface, int num, int32_t identity)
|
||||
: SharedBufferBase(sharedClient, surface, num)
|
||||
{
|
||||
mSharedStack->init(identity);
|
||||
mSharedStack->head = num-1;
|
||||
mSharedStack->available = num;
|
||||
mSharedStack->queued = 0;
|
||||
|
||||
Reference in New Issue
Block a user