Loading libs/gui/ISurfaceComposer.cpp +0 −78 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading libs/gui/SurfaceComposerClient.cpp +117 −32 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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), Loading Loading @@ -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); Loading Loading @@ -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); Loading libs/gui/include/gui/ISurfaceComposer.h +0 −7 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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. Loading libs/gui/include/gui/SurfaceComposerClient.h +0 −6 Original line number Diff line number Diff line Loading @@ -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); Loading libs/gui/tests/Surface_test.cpp +0 −5 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/gui/ISurfaceComposer.cpp +0 −78 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading
libs/gui/SurfaceComposerClient.cpp +117 −32 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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), Loading Loading @@ -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); Loading Loading @@ -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); Loading
libs/gui/include/gui/ISurfaceComposer.h +0 −7 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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. Loading
libs/gui/include/gui/SurfaceComposerClient.h +0 −6 Original line number Diff line number Diff line Loading @@ -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); Loading
libs/gui/tests/Surface_test.cpp +0 −5 Original line number Diff line number Diff line Loading @@ -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