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

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

Merge "allow re-targetting of surfaces" into kraken

parents 9cc61ca4 579b3f88
Loading
Loading
Loading
Loading
+6 −10
Original line number Original line Diff line number Diff line
@@ -44,15 +44,6 @@ namespace android {
 * dequeue-able buffer. When these various conditions are not met, the caller
 * dequeue-able buffer. When these various conditions are not met, the caller
 * waits until the condition is met.
 * waits until the condition is met.
 * 
 * 
 * 
 * CAVEATS:
 * 
 * In the current implementation there are several limitations:
 * - buffers must be locked in the same order they've been dequeued
 * - buffers must be enqueued in the same order they've been locked
 * - dequeue() is not reentrant
 * - no error checks are done on the condition above
 * 
 */
 */


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -269,7 +260,9 @@ private:


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


class SharedBufferServer : public SharedBufferBase
class SharedBufferServer
    : public SharedBufferBase,
      public LightRefBase<SharedBufferServer>
{
{
public:
public:
    SharedBufferServer(SharedClient* sharedClient, int surface, int num,
    SharedBufferServer(SharedClient* sharedClient, int surface, int num,
@@ -290,6 +283,9 @@ public:
    
    


private:
private:
    friend class LightRefBase<SharedBufferServer>;
    ~SharedBufferServer();

    /*
    /*
     * BufferList is basically a fixed-capacity sorted-vector of
     * BufferList is basically a fixed-capacity sorted-vector of
     * unsigned 5-bits ints using a 32-bits int as storage.
     * unsigned 5-bits ints using a 32-bits int as storage.
+3 −3
Original line number Original line Diff line number Diff line
@@ -60,7 +60,6 @@ public:
    static bool isSameSurface(
    static bool isSameSurface(
            const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
            const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
        
        
    SurfaceID   ID() const      { return mToken; }
    uint32_t    getFlags() const { return mFlags; }
    uint32_t    getFlags() const { return mFlags; }
    uint32_t    getIdentity() const { return mIdentity; }
    uint32_t    getIdentity() const { return mIdentity; }


@@ -145,6 +144,9 @@ public:
        uint32_t    reserved[2];
        uint32_t    reserved[2];
    };
    };


    static status_t writeToParcel(
            const sp<Surface>& control, Parcel* parcel);

    static sp<Surface> readFromParcel(
    static sp<Surface> readFromParcel(
            const Parcel& data, const sp<Surface>& other);
            const Parcel& data, const sp<Surface>& other);


@@ -153,7 +155,6 @@ public:
    }
    }


    bool        isValid();
    bool        isValid();
    SurfaceID   ID() const          { return mToken; }
    uint32_t    getFlags() const    { return mFlags; }
    uint32_t    getFlags() const    { return mFlags; }
    uint32_t    getIdentity() const { return mIdentity; }
    uint32_t    getIdentity() const { return mIdentity; }


@@ -267,7 +268,6 @@ private:
    SharedBufferClient*         mSharedBufferClient;
    SharedBufferClient*         mSharedBufferClient;
    status_t                    mInitCheck;
    status_t                    mInitCheck;
    sp<ISurface>                mSurface;
    sp<ISurface>                mSurface;
    SurfaceID                   mToken;
    uint32_t                    mIdentity;
    uint32_t                    mIdentity;
    PixelFormat                 mFormat;
    PixelFormat                 mFormat;
    uint32_t                    mFlags;
    uint32_t                    mFlags;
+35 −13
Original line number Original line Diff line number Diff line
@@ -76,15 +76,18 @@ Layer::~Layer()
status_t Layer::setToken(const sp<UserClient>& userClient,
status_t Layer::setToken(const sp<UserClient>& userClient,
        SharedClient* sharedClient, int32_t token)
        SharedClient* sharedClient, int32_t token)
{
{
    SharedBufferServer* lcblk = new SharedBufferServer(
    sp<SharedBufferServer> lcblk = new SharedBufferServer(
            sharedClient, token, mBufferManager.getDefaultBufferCount(),
            sharedClient, token, mBufferManager.getDefaultBufferCount(),
            getIdentity());
            getIdentity());


    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
    if (err != NO_ERROR) {

        LOGE("ClientRef::setToken(%p, %p, %u) failed",
    LOGE_IF(err != NO_ERROR,
                userClient.get(), lcblk, token);
            "ClientRef::setToken(%p, %p, %u) failed",
        delete lcblk;
            userClient.get(), lcblk.get(), token);

    if (err == NO_ERROR) {
        // we need to free the buffers associated with this surface
    }
    }


    return err;
    return err;
@@ -95,6 +98,11 @@ int32_t Layer::getToken() const
    return mUserClientRef.getToken();
    return mUserClientRef.getToken();
}
}


sp<UserClient> Layer::getClient() const
{
    return mUserClientRef.getClient();
}

// called with SurfaceFlinger::mStateLock as soon as the layer is entered
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
// in the purgatory list
// in the purgatory list
void Layer::onRemoved()
void Layer::onRemoved()
@@ -626,11 +634,10 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------


Layer::ClientRef::ClientRef()
Layer::ClientRef::ClientRef()
    : mToken(-1) {
    : mControlBlock(0), mToken(-1) {
}
}


Layer::ClientRef::~ClientRef() {
Layer::ClientRef::~ClientRef() {
    delete lcblk;
}
}


int32_t Layer::ClientRef::getToken() const {
int32_t Layer::ClientRef::getToken() const {
@@ -638,14 +645,25 @@ int32_t Layer::ClientRef::getToken() const {
    return mToken;
    return mToken;
}
}


sp<UserClient> Layer::ClientRef::getClient() const {
    Mutex::Autolock _l(mLock);
    return mUserClient.promote();
}

status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
        SharedBufferServer* sharedClient, int32_t token) {
        const sp<SharedBufferServer>& sharedClient, int32_t token) {
    Mutex::Autolock _l(mLock);
    Mutex::Autolock _l(mLock);
    if (mToken >= 0)

        return INVALID_OPERATION;
    { // scope for strong mUserClient reference
        sp<UserClient> userClient(mUserClient.promote());
        if (mUserClient != 0 && mControlBlock != 0) {
            mControlBlock->setStatus(NO_INIT);
        }
    }

    mUserClient = uc;
    mUserClient = uc;
    mToken = token;
    mToken = token;
    lcblk = sharedClient;
    mControlBlock = sharedClient;
    return NO_ERROR;
    return NO_ERROR;
}
}


@@ -657,12 +675,16 @@ sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
// it makes sure the UserClient (and its associated shared memory)
// it makes sure the UserClient (and its associated shared memory)
// won't go away while we're accessing it.
// won't go away while we're accessing it.
Layer::ClientRef::Access::Access(const ClientRef& ref)
Layer::ClientRef::Access::Access(const ClientRef& ref)
    : lcblk(0)
    : mControlBlock(0)
{
{
    Mutex::Autolock _l(ref.mLock);
    Mutex::Autolock _l(ref.mLock);
    mUserClientStrongRef = ref.mUserClient.promote();
    mUserClientStrongRef = ref.mUserClient.promote();
    if (mUserClientStrongRef != 0)
    if (mUserClientStrongRef != 0)
        lcblk = ref.lcblk;
        mControlBlock = ref.mControlBlock;
}

Layer::ClientRef::Access::~Access()
{
}
}


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
+7 −4
Original line number Original line Diff line number Diff line
@@ -60,6 +60,7 @@ public:
    // associate a UserClient to this Layer
    // associate a UserClient to this Layer
    status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx);
    status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx);
    int32_t getToken() const;
    int32_t getToken() const;
    sp<UserClient> getClient() const;


    // Set this Layer's buffers size
    // Set this Layer's buffers size
    void setBufferSize(uint32_t w, uint32_t h);
    void setBufferSize(uint32_t w, uint32_t h);
@@ -119,24 +120,26 @@ private:
        ClientRef& operator = (const ClientRef& rhs);
        ClientRef& operator = (const ClientRef& rhs);
        mutable Mutex mLock;
        mutable Mutex mLock;
        // binder thread, page-flip thread
        // binder thread, page-flip thread
        SharedBufferServer* lcblk;
        sp<SharedBufferServer> mControlBlock;
        wp<UserClient> mUserClient;
        wp<UserClient> mUserClient;
        int32_t mToken;
        int32_t mToken;
    public:
    public:
        ClientRef();
        ClientRef();
        ~ClientRef();
        ~ClientRef();
        int32_t getToken() const;
        int32_t getToken() const;
        sp<UserClient> getClient() const;
        status_t setToken(const sp<UserClient>& uc,
        status_t setToken(const sp<UserClient>& uc,
                SharedBufferServer* sharedClient, int32_t token);
                const sp<SharedBufferServer>& sharedClient, int32_t token);
        sp<UserClient> getUserClientUnsafe() const;
        sp<UserClient> getUserClientUnsafe() const;
        class Access {
        class Access {
            Access(const Access& rhs);
            Access(const Access& rhs);
            Access& operator = (const Access& rhs);
            Access& operator = (const Access& rhs);
            sp<UserClient> mUserClientStrongRef;
            sp<UserClient> mUserClientStrongRef;
            SharedBufferServer* lcblk;
            sp<SharedBufferServer> mControlBlock;
        public:
        public:
            Access(const ClientRef& ref);
            Access(const ClientRef& ref);
            inline SharedBufferServer* get() const { return lcblk; }
            ~Access();
            inline SharedBufferServer* get() const { return mControlBlock.get(); }
        };
        };
        friend class Access;
        friend class Access;
    };
    };
+14 −5
Original line number Original line Diff line number Diff line
@@ -1718,7 +1718,10 @@ void UserClient::detachLayer(const Layer* layer)
{
{
    int32_t name = layer->getToken();
    int32_t name = layer->getToken();
    if (name >= 0) {
    if (name >= 0) {
        android_atomic_and(~(1LU<<name), &mBitmap);
        int32_t mask = 1LU<<name;
        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
        }
    }
    }
}
}


@@ -1732,17 +1735,23 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
    sp<Layer> layer(mFlinger->getLayer(sur));
    sp<Layer> layer(mFlinger->getLayer(sur));
    if (layer == 0) return name;
    if (layer == 0) return name;


    // this layer already has a token, just return it
    // if this layer already has a token, just return it
    // FIXME: we should check that this token is for the same client
    name = layer->getToken();
    name = layer->getToken();
    if (name >= 0) return name;
    if ((name >= 0) && (layer->getClient() == this))
        return name;


    name = 0;
    name = 0;
    do {
    do {
        int32_t mask = 1LU<<name;
        int32_t mask = 1LU<<name;
        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
            // we found and locked that name
            // we found and locked that name
            layer->setToken(const_cast<UserClient*>(this), ctrlblk, name);
            status_t err = layer->setToken(
                    const_cast<UserClient*>(this), ctrlblk, name);
            if (err != NO_ERROR) {
                // free the name
                android_atomic_and(~mask, &mBitmap);
                name = err;
            }
            break;
            break;
        }
        }
        if (++name > 31)
        if (++name > 31)
Loading