1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <android-base/thread_annotations.h> 20 #include <binder/IBinder.h> 21 #include <gui/LayerState.h> 22 #include <renderengine/RenderEngine.h> 23 #include <ui/GraphicBuffer.h> 24 #include <utils/RefBase.h> 25 #include <utils/Singleton.h> 26 27 #include <map> 28 #include <mutex> 29 #include <set> 30 #include <unordered_map> 31 32 // 4096 is based on 64 buffers * 64 layers. Once this limit is reached, the least recently used 33 // buffer is uncached before the new buffer is cached. 34 #define BUFFER_CACHE_MAX_SIZE 4096 35 36 namespace android { 37 38 // This class manages a cache of buffer handles between SurfaceFlinger clients 39 // and the SurfaceFlinger process which optimizes away some of the cost of 40 // sending buffer handles across processes. 41 // 42 // Buffers are explicitly cached and uncached by the SurfaceFlinger client. When 43 // a buffer is uncached, it is not only purged from this cache, but the buffer 44 // ID is also passed down to CompositionEngine to purge it from a similar cache 45 // used between SurfaceFlinger and Composer HAL. The buffer ID used to purge 46 // both the SurfaceFlinger side of this other cache, as well as Composer HAL's 47 // side of the cache. 48 // 49 class ClientCache : public Singleton<ClientCache> { 50 public: 51 ClientCache(); 52 53 enum class AddError { CacheFull, Unspecified }; 54 55 base::expected<std::shared_ptr<renderengine::ExternalTexture>, AddError> add( 56 const client_cache_t& cacheId, const sp<GraphicBuffer>& buffer); 57 58 sp<GraphicBuffer> erase(const client_cache_t& cacheId); 59 60 std::shared_ptr<renderengine::ExternalTexture> get(const client_cache_t& cacheId); 61 62 // Always called immediately after setup. Will be set to non-null, and then should never be 63 // called again. setRenderEngine(renderengine::RenderEngine * renderEngine)64 void setRenderEngine(renderengine::RenderEngine* renderEngine) { mRenderEngine = renderEngine; } 65 66 void removeProcess(const wp<IBinder>& processToken); 67 68 class ErasedRecipient : public virtual RefBase { 69 public: 70 virtual void bufferErased(const client_cache_t& clientCacheId) = 0; 71 }; 72 73 bool registerErasedRecipient(const client_cache_t& cacheId, 74 const wp<ErasedRecipient>& recipient); 75 void unregisterErasedRecipient(const client_cache_t& cacheId, 76 const wp<ErasedRecipient>& recipient); 77 78 void dump(std::string& result); 79 80 private: 81 std::mutex mMutex; 82 83 struct ClientCacheBuffer { 84 std::shared_ptr<renderengine::ExternalTexture> buffer; 85 std::set<wp<ErasedRecipient>> recipients; 86 }; 87 std::map<wp<IBinder> /*caching process*/, 88 std::pair<sp<IBinder> /*strong ref to caching process*/, 89 std::unordered_map<uint64_t /*cache id*/, ClientCacheBuffer>>> 90 mBuffers GUARDED_BY(mMutex); 91 92 class CacheDeathRecipient : public IBinder::DeathRecipient { 93 public: 94 void binderDied(const wp<IBinder>& who) override; 95 }; 96 97 sp<CacheDeathRecipient> mDeathRecipient; 98 renderengine::RenderEngine* mRenderEngine = nullptr; 99 100 bool getBuffer(const client_cache_t& cacheId, ClientCacheBuffer** outClientCacheBuffer) 101 REQUIRES(mMutex); 102 }; 103 104 }; // namespace android 105