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

Commit 2f0e6753 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "SharedBufferStack now can grow up to 16 buffers." into kraken

parents 6a70cb8a 59751dbf
Loading
Loading
Loading
Loading
+52 −3
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ public:

// ----------------------------------------------------------------------------

// 4 KB max
// 32 KB max
class SharedClient
{
public:
@@ -166,7 +166,7 @@ public:
protected:
    SharedClient* const mSharedClient;
    SharedBufferStack* const mSharedStack;
    const int mNumBuffers;
    int mNumBuffers;
    const int mIdentity;
    int32_t computeTail() const;

@@ -217,6 +217,7 @@ public:
    bool needNewBuffer(int buffer) const;
    status_t setDirtyRegion(int buffer, const Region& reg);
    status_t setCrop(int buffer, const Rect& reg);
    status_t setBufferCount(int bufferCount);
    
private:
    friend struct Condition;
@@ -269,13 +270,61 @@ public:
    status_t reallocate();
    status_t assertReallocate(int buffer);
    int32_t getQueuedCount() const;
    
    Region getDirtyRegion(int buffer) const;

    status_t resize(int newNumBuffers);

    SharedBufferStack::Statistics getStats() const;
    

private:
    /*
     * BufferList is basically a fixed-capacity sorted-vector of
     * unsigned 5-bits ints using a 32-bits int as storage.
     * it has efficient iterators to find items in the list and not in the list.
     */
    class BufferList {
        size_t mCapacity;
        uint32_t mList;
    public:
        BufferList(size_t c = NUM_BUFFER_MAX) : mCapacity(c), mList(0) { }
        status_t add(int value);
        status_t remove(int value);

        class const_iterator {
            friend class BufferList;
            uint32_t mask, curr;
            const_iterator(uint32_t mask) :
                mask(mask), curr(31 - __builtin_clz(mask)) { }
        public:
            inline bool operator == (const const_iterator& rhs) const {
                return mask == rhs.mask;
            }
            inline bool operator != (const const_iterator& rhs) const {
                return mask != rhs.mask;
            }
            inline int operator *() const { return curr; }
            inline const const_iterator& operator ++(int) {
                mask &= ~curr;
                curr = 31 - __builtin_clz(mask);
                return *this;
            }
        };

        inline const_iterator begin() const {
            return const_iterator(mList);
        }
        inline const_iterator end() const   {
            return const_iterator(0);
        }
        inline const_iterator free_begin() const {
            uint32_t mask = (1 << (32-mCapacity)) - 1;
            return const_iterator( ~(mList | mask) );
        }
    };

    BufferList mBufferList;

    struct UnlockUpdate : public UpdateBase {
        const int lockedBuffer;
        inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
+2 −0
Original line number Diff line number Diff line
@@ -47,12 +47,14 @@ protected:
        POST_BUFFER, // one-way transaction
        CREATE_OVERLAY,
        REQUEST_BUFFER,
        SET_BUFFER_COUNT,
    };

public: 
    DECLARE_META_INTERFACE(Surface);

    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; 
    virtual status_t setBufferCount(int bufferCount) = 0;
    
    class BufferHeap {
    public:
+1 −0
Original line number Diff line number Diff line
@@ -217,6 +217,7 @@ private:
    int  connect(int api);
    int  disconnect(int api);
    int  crop(Rect const* rect);
    int  setBufferCount(int bufferCount);

    /*
     *  private stuff...
+34 −0
Original line number Diff line number Diff line
@@ -208,6 +208,30 @@ void Layer::onDraw(const Region& clip) const
    drawWithOpenGL(clip, tex);
}


status_t Layer::setBufferCount(int bufferCount)
{
    // 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 DEAD_OBJECT;
    }

    status_t err;

    // FIXME: resize() below is NOT thread-safe, we need to synchronize
    // the users of lcblk in our process (ie: retire), and we assume the
    // client is not mucking with the SharedStack, which is only enforced
    // by construction, therefore we need to protect ourselves against
    // buggy and malicious client (as always)

    err = lcblk->resize(bufferCount);

    return err;
}

sp<GraphicBuffer> Layer::requestBuffer(int index, int usage)
{
    sp<GraphicBuffer> buffer;
@@ -642,6 +666,16 @@ sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage)
    return buffer;
}

status_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
{
    status_t err = DEAD_OBJECT;
    sp<Layer> owner(getOwner());
    if (owner != 0) {
        err = owner->setBufferCount(bufferCount);
    }
    return err;
}

// ---------------------------------------------------------------------------


+2 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ private:
    uint32_t getEffectiveUsage(uint32_t usage) const;

    sp<GraphicBuffer> requestBuffer(int index, int usage);
    status_t setBufferCount(int bufferCount);
    void destroy();

    class SurfaceLayer : public LayerBaseClient::Surface {
@@ -98,6 +99,7 @@ private:
        ~SurfaceLayer();
    private:
        virtual sp<GraphicBuffer> requestBuffer(int index, int usage);
        virtual status_t setBufferCount(int bufferCount);
        sp<Layer> getOwner() const {
            return static_cast<Layer*>(Surface::getOwner().get());
        }
Loading