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