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

Commit c4d81bd1 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "blast: implicitly cache buffers"

parents 17977b7d 73411620
Loading
Loading
Loading
Loading
+0 −78
Original line number Diff line number Diff line
@@ -722,42 +722,6 @@ public:
        return error;
    }

    virtual status_t cacheBuffer(const sp<IBinder>& token, const sp<GraphicBuffer>& buffer,
                                 int32_t* outBufferId) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());

        data.writeStrongBinder(token);
        if (buffer) {
            data.writeBool(true);
            data.write(*buffer);
        } else {
            data.writeBool(false);
        }

        status_t result = remote()->transact(BnSurfaceComposer::CACHE_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }

        int32_t id = -1;
        result = reply.readInt32(&id);
        if (result == NO_ERROR) {
            *outBufferId = id;
        }
        return result;
    }

    virtual status_t uncacheBuffer(const sp<IBinder>& token, int32_t bufferId) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());

        data.writeStrongBinder(token);
        data.writeInt32(bufferId);

        return remote()->transact(BnSurfaceComposer::UNCACHE_BUFFER, data, &reply);
    }

    virtual status_t isWideColorDisplay(const sp<IBinder>& token,
                                        bool* outIsWideColorDisplay) const {
        Parcel data, reply;
@@ -1238,48 +1202,6 @@ status_t BnSurfaceComposer::onTransact(
            }
            return error;
        }
        case CACHE_BUFFER: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> token;
            status_t result = data.readStrongBinder(&token);
            if (result != NO_ERROR) {
                ALOGE("cache buffer failure in reading token: %d", result);
                return result;
            }

            sp<GraphicBuffer> buffer = new GraphicBuffer();
            if (data.readBool()) {
                result = data.read(*buffer);
                if (result != NO_ERROR) {
                    ALOGE("cache buffer failure in reading buffer: %d", result);
                    return result;
                }
            }
            int32_t bufferId = -1;
            status_t error = cacheBuffer(token, buffer, &bufferId);
            if (error == NO_ERROR) {
                reply->writeInt32(bufferId);
            }
            return error;
        }
        case UNCACHE_BUFFER: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> token;
            status_t result = data.readStrongBinder(&token);
            if (result != NO_ERROR) {
                ALOGE("uncache buffer failure in reading token: %d", result);
                return result;
            }

            int32_t bufferId = -1;
            result = data.readInt32(&bufferId);
            if (result != NO_ERROR) {
                ALOGE("uncache buffer failure in reading buffer id: %d", result);
                return result;
            }

            return uncacheBuffer(token, bufferId);
        }
        case IS_WIDE_COLOR_DISPLAY: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> display = nullptr;
+117 −32
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@

#include <private/gui/ComposerService.h>

// This server size should always be smaller than the server cache size
#define BUFFER_CACHE_MAX_SIZE 64

namespace android {

using ui::ColorMode;
@@ -230,6 +233,113 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener

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

class BufferCache : public Singleton<BufferCache> {
public:
    BufferCache() : token(new BBinder()) {}

    sp<IBinder> getToken() {
        return IInterface::asBinder(TransactionCompletedListener::getIInstance());
    }

    int32_t getId(const sp<GraphicBuffer>& buffer) {
        std::lock_guard lock(mMutex);

        auto itr = mBuffers.find(buffer);
        if (itr == mBuffers.end()) {
            return -1;
        }
        itr->second.counter = getCounter();
        return itr->second.id;
    }

    int32_t cache(const sp<GraphicBuffer>& buffer) {
        std::lock_guard lock(mMutex);

        int32_t bufferId = getNextAvailableId();

        mBuffers[buffer].id = bufferId;
        mBuffers[buffer].counter = getCounter();
        return bufferId;
    }

private:
    int32_t evictDestroyedBuffer() REQUIRES(mMutex) {
        auto itr = mBuffers.begin();
        while (itr != mBuffers.end()) {
            auto& buffer = itr->first;
            if (buffer == nullptr || buffer.promote() == nullptr) {
                int32_t bufferId = itr->second.id;
                mBuffers.erase(itr);
                return bufferId;
            }
            itr++;
        }
        return -1;
    }

    int32_t evictLeastRecentlyUsedBuffer() REQUIRES(mMutex) {
        if (mBuffers.size() < 0) {
            return -1;
        }
        auto itr = mBuffers.begin();
        uint64_t minCounter = itr->second.counter;
        auto minBuffer = itr;
        itr++;

        while (itr != mBuffers.end()) {
            uint64_t counter = itr->second.counter;
            if (counter < minCounter) {
                minCounter = counter;
                minBuffer = itr;
            }
            itr++;
        }
        int32_t minBufferId = minBuffer->second.id;
        mBuffers.erase(minBuffer);
        return minBufferId;
    }

    int32_t getNextAvailableId() REQUIRES(mMutex) {
        static int32_t id = 0;
        if (id + 1 < BUFFER_CACHE_MAX_SIZE) {
            return id++;
        }

        // There are no more valid cache ids. To set additional buffers, evict existing buffers
        // and reuse their cache ids.
        int32_t bufferId = evictDestroyedBuffer();
        if (bufferId > 0) {
            return bufferId;
        }
        return evictLeastRecentlyUsedBuffer();
    }

    uint64_t getCounter() REQUIRES(mMutex) {
        static uint64_t counter = 0;
        return counter++;
    }

    struct Metadata {
        // The cache id of a buffer that can be set to ISurfaceComposer. When ISurfaceComposer
        // recieves this id, it can retrieve the buffer from its cache. Caching GraphicBuffers
        // is important because sending them across processes is expensive.
        int32_t id = 0;
        // When a buffer is set, a counter is incremented and stored in the cache's metadata.
        // When an buffer must be evicted, the entry with the lowest counter value is chosen.
        uint64_t counter = 0;
    };

    std::mutex mMutex;
    std::map<wp<GraphicBuffer>, Metadata> mBuffers GUARDED_BY(mMutex);

    // Used by ISurfaceComposer to identify which process is sending the cached buffer.
    sp<IBinder> token;
};

ANDROID_SINGLETON_STATIC_INSTANCE(BufferCache);

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

SurfaceComposerClient::Transaction::Transaction(const Transaction& other)
      : mForceSynchronous(other.mForceSynchronous),
        mTransactionNestCount(other.mTransactionNestCount),
@@ -759,22 +869,17 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe
        mStatus = BAD_INDEX;
        return *this;
    }

    int32_t bufferId = BufferCache::getInstance().getId(buffer);
    if (bufferId < 0) {
        bufferId = BufferCache::getInstance().cache(buffer);

        s->what |= layer_state_t::eBufferChanged;
        s->buffer = buffer;

    registerSurfaceControlForCallback(sc);
    return *this;
    }

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCachedBuffer(
        const sp<SurfaceControl>& sc, int32_t bufferId) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    s->what |= layer_state_t::eCachedBufferChanged;
    s->cachedBuffer.token = IInterface::asBinder(TransactionCompletedListener::getIInstance());
    s->cachedBuffer.token = BufferCache::getInstance().getToken();
    s->cachedBuffer.bufferId = bufferId;

    registerSurfaceControlForCallback(sc);
@@ -1217,26 +1322,6 @@ status_t SurfaceComposerClient::getLayerFrameStats(const sp<IBinder>& token,

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

status_t SurfaceComposerClient::cacheBuffer(const sp<GraphicBuffer>& buffer, int32_t* outBufferId) {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (buffer == nullptr || outBufferId == nullptr) {
        return BAD_VALUE;
    }
    return sf->cacheBuffer(IInterface::asBinder(TransactionCompletedListener::getIInstance()),
                           buffer, outBufferId);
}

status_t SurfaceComposerClient::uncacheBuffer(int32_t bufferId) {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (bufferId < 0) {
        return BAD_VALUE;
    }
    return sf->uncacheBuffer(IInterface::asBinder(TransactionCompletedListener::getIInstance()),
                             bufferId);
}

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

status_t SurfaceComposerClient::enableVSyncInjections(bool enable) {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    return sf->enableVSyncInjections(enable);
+0 −7
Original line number Diff line number Diff line
@@ -320,11 +320,6 @@ public:
     */
    virtual status_t getProtectedContentSupport(bool* outSupported) const = 0;

    virtual status_t cacheBuffer(const sp<IBinder>& token, const sp<GraphicBuffer>& buffer,
                                 int32_t* outBufferId) = 0;

    virtual status_t uncacheBuffer(const sp<IBinder>& token, int32_t bufferId) = 0;

    /*
     * Queries whether the given display is a wide color display.
     * Requires the ACCESS_SURFACE_FLINGER permission.
@@ -373,8 +368,6 @@ public:
        SET_DISPLAY_CONTENT_SAMPLING_ENABLED,
        GET_DISPLAYED_CONTENT_SAMPLE,
        GET_PROTECTED_CONTENT_SUPPORT,
        CACHE_BUFFER,
        UNCACHE_BUFFER,
        IS_WIDE_COLOR_DISPLAY,
        GET_DISPLAY_NATIVE_PRIMARIES,
        // Always append new enum to the end.
+0 −6
Original line number Diff line number Diff line
@@ -152,12 +152,6 @@ public:
    static void doDropReferenceTransaction(const sp<IBinder>& handle,
            const sp<ISurfaceComposerClient>& client);

    // Caches a buffer with the ISurfaceComposer so the buffer does not need to be resent across
    // processes
    static status_t cacheBuffer(const sp<GraphicBuffer>& buffer, int32_t* outBufferId);
    // Uncaches a buffer set by cacheBuffer
    static status_t uncacheBuffer(int32_t bufferId);

    // Queries whether a given display is wide color display.
    static status_t isWideColorDisplay(const sp<IBinder>& display, bool* outIsWideColorDisplay);

+0 −5
Original line number Diff line number Diff line
@@ -664,11 +664,6 @@ public:
    status_t getColorManagement(bool* /*outGetColorManagement*/) const override { return NO_ERROR; }
    status_t getProtectedContentSupport(bool* /*outSupported*/) const override { return NO_ERROR; }

    status_t cacheBuffer(const sp<IBinder>& /*token*/, const sp<GraphicBuffer>& /*buffer*/,
                         int32_t* /*outBufferId*/) {
        return NO_ERROR;
    }
    status_t uncacheBuffer(const sp<IBinder>& /*token*/, int32_t /*bufferId*/) { return NO_ERROR; }
    status_t isWideColorDisplay(const sp<IBinder>&, bool*) const override { return NO_ERROR; }

protected:
Loading