1 /*
2  * Copyright 2018 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 #ifndef LOG_TAG
20 #warning "ComposerResources.h included without LOG_TAG"
21 #endif
22 
23 #include <memory>
24 #include <mutex>
25 #include <unordered_map>
26 #include <vector>
27 
28 #include <android/hardware/graphics/composer/2.1/types.h>
29 
30 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
31 #include <android/hardware/graphics/mapper/3.0/IMapper.h>
32 #include <android/hardware/graphics/mapper/4.0/IMapper.h>
33 #include <log/log.h>
34 
35 namespace android {
36 namespace hardware {
37 namespace graphics {
38 namespace composer {
39 namespace V2_1 {
40 namespace hal {
41 
42 // wrapper for IMapper to import buffers and sideband streams
43 class ComposerHandleImporter {
44   public:
45     bool init();
46 
47     Error importBuffer(const native_handle_t* rawHandle, const native_handle_t** outBufferHandle);
48     void freeBuffer(const native_handle_t* bufferHandle);
49     Error importStream(const native_handle_t* rawHandle, const native_handle_t** outStreamHandle);
50     void freeStream(const native_handle_t* streamHandle);
51 
52   private:
53     sp<mapper::V2_0::IMapper> mMapper2;
54     sp<mapper::V3_0::IMapper> mMapper3;
55     sp<mapper::V4_0::IMapper> mMapper4;
56 };
57 
58 class ComposerHandleCache {
59   public:
60     enum class HandleType {
61         INVALID,
62         BUFFER,
63         STREAM,
64     };
65 
66     ComposerHandleCache(ComposerHandleImporter& importer, HandleType type, uint32_t cacheSize);
67 
68     // must be initialized later with initCache
69     ComposerHandleCache(ComposerHandleImporter& importer);
70 
71     ~ComposerHandleCache();
72 
73     ComposerHandleCache(const ComposerHandleCache&) = delete;
74     ComposerHandleCache& operator=(const ComposerHandleCache&) = delete;
75 
76     bool initCache(HandleType type, uint32_t cacheSize);
77     size_t getCacheSize() const;
78     Error lookupCache(uint32_t slot, const native_handle_t** outHandle);
79     Error updateCache(uint32_t slot, const native_handle_t* handle,
80                       const native_handle** outReplacedHandle);
81 
82     // when fromCache is true, look up in the cache; otherwise, update the cache
83     Error getHandle(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
84                     const native_handle_t** outHandle, const native_handle** outReplacedHandle);
85 
86   private:
87     ComposerHandleImporter& mImporter;
88     HandleType mHandleType = HandleType::INVALID;
89     std::vector<const native_handle_t*> mHandles;
90 };
91 
92 // layer resource
93 class ComposerLayerResource {
94   public:
95     ComposerLayerResource(ComposerHandleImporter& importer, uint32_t bufferCacheSize);
96 
97     virtual ~ComposerLayerResource() = default;
98 
99     Error getBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
100                     const native_handle_t** outHandle, const native_handle** outReplacedHandle);
101     Error getSidebandStream(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
102                             const native_handle_t** outHandle,
103                             const native_handle** outReplacedHandle);
104 
105   protected:
106     ComposerHandleCache mBufferCache;
107     ComposerHandleCache mSidebandStreamCache;
108 };
109 
110 // display resource
111 class ComposerDisplayResource {
112   public:
113     enum class DisplayType {
114         PHYSICAL,
115         VIRTUAL,
116     };
117 
118     virtual ~ComposerDisplayResource() = default;
119 
120     ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
121                             uint32_t outputBufferCacheSize);
122 
123     bool initClientTargetCache(uint32_t cacheSize);
124     size_t getClientTargetCacheSize() const;
125     size_t getOutputBufferCacheSize() const;
126     bool isVirtual() const;
127 
128     Error getClientTarget(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
129                           const native_handle_t** outHandle,
130                           const native_handle** outReplacedHandle);
131 
132     Error getOutputBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
133                           const native_handle_t** outHandle,
134                           const native_handle** outReplacedHandle);
135 
136     bool addLayer(Layer layer, std::unique_ptr<ComposerLayerResource> layerResource);
137     bool removeLayer(Layer layer);
138     ComposerLayerResource* findLayerResource(Layer layer);
139     std::vector<Layer> getLayers() const;
140 
141     void setMustValidateState(bool mustValidate);
142 
143     bool mustValidate() const;
144 
145   protected:
146     const DisplayType mType;
147     ComposerHandleCache mClientTargetCache;
148     ComposerHandleCache mOutputBufferCache;
149     bool mMustValidate;
150 
151     std::unordered_map<Layer, std::unique_ptr<ComposerLayerResource>> mLayerResources;
152 };
153 
154 class ComposerResources {
155   public:
156     static std::unique_ptr<ComposerResources> create();
157 
158     ComposerResources() = default;
159     virtual ~ComposerResources() = default;
160 
161     bool init();
162 
163     using RemoveDisplay =
164             std::function<void(Display display, bool isVirtual, const std::vector<Layer>& layers)>;
165     void clear(RemoveDisplay removeDisplay);
166 
167     bool hasDisplay(Display display);
168     Error addPhysicalDisplay(Display display);
169     Error addVirtualDisplay(Display display, uint32_t outputBufferCacheSize);
170 
171     Error removeDisplay(Display display);
172 
173     Error setDisplayClientTargetCacheSize(Display display, uint32_t clientTargetCacheSize);
174     Error getDisplayClientTargetCacheSize(Display display, size_t* outCacheSize);
175     Error getDisplayOutputBufferCacheSize(Display display, size_t* outCacheSize);
176 
177     Error addLayer(Display display, Layer layer, uint32_t bufferCacheSize);
178     Error removeLayer(Display display, Layer layer);
179 
180     void setDisplayMustValidateState(Display display, bool mustValidate);
181 
182     bool mustValidateDisplay(Display display);
183 
184     // When a buffer in the cache is replaced by a new one, we must keep it
185     // alive until it has been replaced in ComposerHal because it is still using
186     // the old buffer.
187     class ReplacedHandle {
188       public:
ReplacedHandle(bool isBuffer)189         explicit ReplacedHandle(bool isBuffer) : mIsBuffer(isBuffer) {}
190         ReplacedHandle(const ReplacedHandle&) = delete;
191         ReplacedHandle& operator=(const ReplacedHandle&) = delete;
192 
~ReplacedHandle()193         ~ReplacedHandle() { reset(); }
194 
isBuffer()195         bool isBuffer() { return mIsBuffer; }
196 
197         void reset(ComposerHandleImporter* importer = nullptr,
198                    const native_handle_t* handle = nullptr) {
199             if (mHandle) {
200                 if (mIsBuffer) {
201                     mImporter->freeBuffer(mHandle);
202                 } else {
203                     mImporter->freeStream(mHandle);
204                 }
205             }
206 
207             mImporter = importer;
208             mHandle = handle;
209         }
210 
211       private:
212         bool mIsBuffer;
213         ComposerHandleImporter* mImporter = nullptr;
214         const native_handle_t* mHandle = nullptr;
215     };
216 
217     Error getDisplayClientTarget(Display display, uint32_t slot, bool fromCache,
218                                  const native_handle_t* rawHandle,
219                                  const native_handle_t** outBufferHandle,
220                                  ReplacedHandle* outReplacedBuffer);
221 
222     Error getDisplayOutputBuffer(Display display, uint32_t slot, bool fromCache,
223                                  const native_handle_t* rawHandle,
224                                  const native_handle_t** outBufferHandle,
225                                  ReplacedHandle* outReplacedBuffer);
226 
227     Error getLayerBuffer(Display display, Layer layer, uint32_t slot, bool fromCache,
228                          const native_handle_t* rawHandle, const native_handle_t** outBufferHandle,
229                          ReplacedHandle* outReplacedBuffer);
230 
231     Error getLayerSidebandStream(Display display, Layer layer, const native_handle_t* rawHandle,
232                                  const native_handle_t** outStreamHandle,
233                                  ReplacedHandle* outReplacedStream);
234 
235   protected:
236     virtual std::unique_ptr<ComposerDisplayResource> createDisplayResource(
237             ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize);
238 
239     virtual std::unique_ptr<ComposerLayerResource> createLayerResource(uint32_t bufferCacheSize);
240 
241     ComposerDisplayResource* findDisplayResourceLocked(Display display);
242 
243     ComposerHandleImporter mImporter;
244 
245     std::mutex mDisplayResourcesMutex;
246     std::unordered_map<Display, std::unique_ptr<ComposerDisplayResource>> mDisplayResources;
247 
248   private:
249     enum class Cache {
250         CLIENT_TARGET,
251         OUTPUT_BUFFER,
252         LAYER_BUFFER,
253         LAYER_SIDEBAND_STREAM,
254     };
255 
256     Error getHandle(Display display, Layer layer, uint32_t slot, Cache cache, bool fromCache,
257                     const native_handle_t* rawHandle, const native_handle_t** outHandle,
258                     ReplacedHandle* outReplacedHandle);
259 };
260 
261 }  // namespace hal
262 }  // namespace V2_1
263 }  // namespace composer
264 }  // namespace graphics
265 }  // namespace hardware
266 }  // namespace android
267