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     Error lookupCache(uint32_t slot, const native_handle_t** outHandle);
78     Error updateCache(uint32_t slot, const native_handle_t* handle,
79                       const native_handle** outReplacedHandle);
80 
81     // when fromCache is true, look up in the cache; otherwise, update the cache
82     Error getHandle(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
83                     const native_handle_t** outHandle, const native_handle** outReplacedHandle);
84 
85   private:
86     ComposerHandleImporter& mImporter;
87     HandleType mHandleType = HandleType::INVALID;
88     std::vector<const native_handle_t*> mHandles;
89 };
90 
91 // layer resource
92 class ComposerLayerResource {
93   public:
94     ComposerLayerResource(ComposerHandleImporter& importer, uint32_t bufferCacheSize);
95 
96     virtual ~ComposerLayerResource() = default;
97 
98     Error getBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
99                     const native_handle_t** outHandle, const native_handle** outReplacedHandle);
100     Error getSidebandStream(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
101                             const native_handle_t** outHandle,
102                             const native_handle** outReplacedHandle);
103 
104   protected:
105     ComposerHandleCache mBufferCache;
106     ComposerHandleCache mSidebandStreamCache;
107 };
108 
109 // display resource
110 class ComposerDisplayResource {
111   public:
112     enum class DisplayType {
113         PHYSICAL,
114         VIRTUAL,
115     };
116 
117     virtual ~ComposerDisplayResource() = default;
118 
119     ComposerDisplayResource(DisplayType type, ComposerHandleImporter& importer,
120                             uint32_t outputBufferCacheSize);
121 
122     bool initClientTargetCache(uint32_t cacheSize);
123 
124     bool isVirtual() const;
125 
126     Error getClientTarget(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
127                           const native_handle_t** outHandle,
128                           const native_handle** outReplacedHandle);
129 
130     Error getOutputBuffer(uint32_t slot, bool fromCache, const native_handle_t* inHandle,
131                           const native_handle_t** outHandle,
132                           const native_handle** outReplacedHandle);
133 
134     bool addLayer(Layer layer, std::unique_ptr<ComposerLayerResource> layerResource);
135     bool removeLayer(Layer layer);
136     ComposerLayerResource* findLayerResource(Layer layer);
137     std::vector<Layer> getLayers() const;
138 
139     void setMustValidateState(bool mustValidate);
140 
141     bool mustValidate() const;
142 
143   protected:
144     const DisplayType mType;
145     ComposerHandleCache mClientTargetCache;
146     ComposerHandleCache mOutputBufferCache;
147     bool mMustValidate;
148 
149     std::unordered_map<Layer, std::unique_ptr<ComposerLayerResource>> mLayerResources;
150 };
151 
152 class ComposerResources {
153   public:
154     static std::unique_ptr<ComposerResources> create();
155 
156     ComposerResources() = default;
157     virtual ~ComposerResources() = default;
158 
159     bool init();
160 
161     using RemoveDisplay =
162             std::function<void(Display display, bool isVirtual, const std::vector<Layer>& layers)>;
163     void clear(RemoveDisplay removeDisplay);
164 
165     Error addPhysicalDisplay(Display display);
166     Error addVirtualDisplay(Display display, uint32_t outputBufferCacheSize);
167 
168     Error removeDisplay(Display display);
169 
170     Error setDisplayClientTargetCacheSize(Display display, uint32_t clientTargetCacheSize);
171 
172     Error addLayer(Display display, Layer layer, uint32_t bufferCacheSize);
173     Error removeLayer(Display display, Layer layer);
174 
175     void setDisplayMustValidateState(Display display, bool mustValidate);
176 
177     bool mustValidateDisplay(Display display);
178 
179     // When a buffer in the cache is replaced by a new one, we must keep it
180     // alive until it has been replaced in ComposerHal.
181     class ReplacedHandle {
182       public:
ReplacedHandle(bool isBuffer)183         explicit ReplacedHandle(bool isBuffer) : mIsBuffer(isBuffer) {}
184         ReplacedHandle(const ReplacedHandle&) = delete;
185         ReplacedHandle& operator=(const ReplacedHandle&) = delete;
186 
~ReplacedHandle()187         ~ReplacedHandle() { reset(); }
188 
isBuffer()189         bool isBuffer() { return mIsBuffer; }
190 
191         void reset(ComposerHandleImporter* importer = nullptr,
192                    const native_handle_t* handle = nullptr) {
193             if (mHandle) {
194                 if (mIsBuffer) {
195                     mImporter->freeBuffer(mHandle);
196                 } else {
197                     mImporter->freeStream(mHandle);
198                 }
199             }
200 
201             mImporter = importer;
202             mHandle = handle;
203         }
204 
205       private:
206         bool mIsBuffer;
207         ComposerHandleImporter* mImporter = nullptr;
208         const native_handle_t* mHandle = nullptr;
209     };
210 
211     Error getDisplayClientTarget(Display display, uint32_t slot, bool fromCache,
212                                  const native_handle_t* rawHandle,
213                                  const native_handle_t** outBufferHandle,
214                                  ReplacedHandle* outReplacedBuffer);
215 
216     Error getDisplayOutputBuffer(Display display, uint32_t slot, bool fromCache,
217                                  const native_handle_t* rawHandle,
218                                  const native_handle_t** outBufferHandle,
219                                  ReplacedHandle* outReplacedBuffer);
220 
221     Error getLayerBuffer(Display display, Layer layer, uint32_t slot, bool fromCache,
222                          const native_handle_t* rawHandle, const native_handle_t** outBufferHandle,
223                          ReplacedHandle* outReplacedBuffer);
224 
225     Error getLayerSidebandStream(Display display, Layer layer, const native_handle_t* rawHandle,
226                                  const native_handle_t** outStreamHandle,
227                                  ReplacedHandle* outReplacedStream);
228 
229   protected:
230     virtual std::unique_ptr<ComposerDisplayResource> createDisplayResource(
231             ComposerDisplayResource::DisplayType type, uint32_t outputBufferCacheSize);
232 
233     virtual std::unique_ptr<ComposerLayerResource> createLayerResource(uint32_t bufferCacheSize);
234 
235     ComposerDisplayResource* findDisplayResourceLocked(Display display);
236 
237     ComposerHandleImporter mImporter;
238 
239     std::mutex mDisplayResourcesMutex;
240     std::unordered_map<Display, std::unique_ptr<ComposerDisplayResource>> mDisplayResources;
241 
242   private:
243     enum class Cache {
244         CLIENT_TARGET,
245         OUTPUT_BUFFER,
246         LAYER_BUFFER,
247         LAYER_SIDEBAND_STREAM,
248     };
249 
250     Error getHandle(Display display, Layer layer, uint32_t slot, Cache cache, bool fromCache,
251                     const native_handle_t* rawHandle, const native_handle_t** outHandle,
252                     ReplacedHandle* outReplacedHandle);
253 };
254 
255 }  // namespace hal
256 }  // namespace V2_1
257 }  // namespace composer
258 }  // namespace graphics
259 }  // namespace hardware
260 }  // namespace android
261