Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48d819a1 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

fix [2112575] stuck on DequeueCondition for a surface that doesn't exist anymore

this also fixes part of [2111536] Device is soft rebooted after ending the call through voice dialer
parent b58b5d72
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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);
+44 −10
Original line number Diff line number Diff line
@@ -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);
    uint32_t w = mWidth;
    uint32_t h = mHeight;
        w = mWidth;
        h = mHeight;
        buffer = mBuffers[index];
        mBuffers[index].clear();
    }


    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) {
        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;
}
+2 −4
Original line number Diff line number Diff line
@@ -52,10 +52,6 @@ public:
    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);
+5 −3
Original line number Diff line number Diff line
@@ -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 
+6 −2
Original line number Diff line number Diff line
@@ -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 
    {
Loading