blob: 180015deb5ba8e7b52ccb0a2507fad2c3678d198 [file] [log] [blame]
Chia-I Wu731eb3d2016-12-12 21:48:29 +08001/*
2 * Copyright 2016 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
Chia-I Wu939e4012016-12-12 21:51:33 +080017#ifndef ANDROID_HARDWARE_GRALLOC_1_ON_0_ADAPTER_H
18#define ANDROID_HARDWARE_GRALLOC_1_ON_0_ADAPTER_H
Chia-I Wu731eb3d2016-12-12 21:48:29 +080019
20#include <hardware/gralloc1.h>
Chia-I Wu939e4012016-12-12 21:51:33 +080021#include <log/log.h>
Chia-I Wu731eb3d2016-12-12 21:48:29 +080022
Chia-I Wu939e4012016-12-12 21:51:33 +080023#include <atomic>
24#include <memory>
Chia-I Wu731eb3d2016-12-12 21:48:29 +080025#include <mutex>
26#include <string>
27#include <unordered_map>
Chia-I Wu939e4012016-12-12 21:51:33 +080028#include <utility>
Chia-I Wu731eb3d2016-12-12 21:48:29 +080029
30struct gralloc_module_t;
Chia-I Wu939e4012016-12-12 21:51:33 +080031struct alloc_device_t;
Chia-I Wu731eb3d2016-12-12 21:48:29 +080032
33namespace android {
Chia-I Wu939e4012016-12-12 21:51:33 +080034namespace hardware {
Chia-I Wu731eb3d2016-12-12 21:48:29 +080035
36class Gralloc1On0Adapter : public gralloc1_device_t
37{
38public:
39 Gralloc1On0Adapter(const hw_module_t* module);
40 ~Gralloc1On0Adapter();
41
42 gralloc1_device_t* getDevice() {
43 return static_cast<gralloc1_device_t*>(this);
44 }
45
46private:
47 static inline Gralloc1On0Adapter* getAdapter(gralloc1_device_t* device) {
48 return static_cast<Gralloc1On0Adapter*>(device);
49 }
50
Chia-I Wu939e4012016-12-12 21:51:33 +080051 static int closeHook(struct hw_device_t* device) {
52 delete getAdapter(reinterpret_cast<gralloc1_device_t*>(device));
53 return 0;
54 }
55
Chia-I Wu731eb3d2016-12-12 21:48:29 +080056 // getCapabilities
57
58 void doGetCapabilities(uint32_t* outCount,
59 int32_t* /*gralloc1_capability_t*/ outCapabilities);
60 static void getCapabilitiesHook(gralloc1_device_t* device,
61 uint32_t* outCount,
62 int32_t* /*gralloc1_capability_t*/ outCapabilities) {
63 getAdapter(device)->doGetCapabilities(outCount, outCapabilities);
64 }
65
66 // getFunction
67
68 gralloc1_function_pointer_t doGetFunction(
69 int32_t /*gralloc1_function_descriptor_t*/ descriptor);
70 static gralloc1_function_pointer_t getFunctionHook(
71 gralloc1_device_t* device,
72 int32_t /*gralloc1_function_descriptor_t*/ descriptor) {
73 return getAdapter(device)->doGetFunction(descriptor);
74 }
75
76 // dump
77
78 void dump(uint32_t* outSize, char* outBuffer);
79 static void dumpHook(gralloc1_device_t* device, uint32_t* outSize,
80 char* outBuffer) {
81 return getAdapter(device)->dump(outSize, outBuffer);
82 }
83 std::string mCachedDump;
84
85 // Buffer descriptor lifecycle functions
86
87 struct Descriptor;
88
89 gralloc1_error_t createDescriptor(
90 gralloc1_buffer_descriptor_t* outDescriptor);
91 static int32_t createDescriptorHook(gralloc1_device_t* device,
92 gralloc1_buffer_descriptor_t* outDescriptor) {
93 auto error = getAdapter(device)->createDescriptor(outDescriptor);
94 return static_cast<int32_t>(error);
95 }
96
97 gralloc1_error_t destroyDescriptor(gralloc1_buffer_descriptor_t descriptor);
98 static int32_t destroyDescriptorHook(gralloc1_device_t* device,
99 gralloc1_buffer_descriptor_t descriptor) {
100 auto error = getAdapter(device)->destroyDescriptor(descriptor);
101 return static_cast<int32_t>(error);
102 }
103
104 // Buffer descriptor modification functions
105
106 struct Descriptor : public std::enable_shared_from_this<Descriptor> {
Chia-I Wu939e4012016-12-12 21:51:33 +0800107 Descriptor()
108 : width(0),
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800109 height(0),
110 format(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
111 layerCount(1),
112 producerUsage(GRALLOC1_PRODUCER_USAGE_NONE),
113 consumerUsage(GRALLOC1_CONSUMER_USAGE_NONE) {}
114
115 gralloc1_error_t setDimensions(uint32_t w, uint32_t h) {
116 width = w;
117 height = h;
118 return GRALLOC1_ERROR_NONE;
119 }
120
121 gralloc1_error_t setFormat(int32_t f) {
122 format = f;
123 return GRALLOC1_ERROR_NONE;
124 }
125
126 gralloc1_error_t setLayerCount(uint32_t lc) {
127 layerCount = lc;
128 return GRALLOC1_ERROR_NONE;
129 }
130
131 gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage) {
132 producerUsage = usage;
133 return GRALLOC1_ERROR_NONE;
134 }
135
136 gralloc1_error_t setConsumerUsage(gralloc1_consumer_usage_t usage) {
137 consumerUsage = usage;
138 return GRALLOC1_ERROR_NONE;
139 }
140
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800141 uint32_t width;
142 uint32_t height;
143 int32_t format;
144 uint32_t layerCount;
145 gralloc1_producer_usage_t producerUsage;
146 gralloc1_consumer_usage_t consumerUsage;
147 };
148
149 template <typename ...Args>
150 static int32_t callDescriptorFunction(gralloc1_device_t* device,
151 gralloc1_buffer_descriptor_t descriptorId,
152 gralloc1_error_t (Descriptor::*member)(Args...), Args... args) {
153 auto descriptor = getAdapter(device)->getDescriptor(descriptorId);
154 if (!descriptor) {
155 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
156 }
157 auto error = ((*descriptor).*member)(std::forward<Args>(args)...);
158 return static_cast<int32_t>(error);
159 }
160
161 static int32_t setConsumerUsageHook(gralloc1_device_t* device,
162 gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
163 auto usage = static_cast<gralloc1_consumer_usage_t>(intUsage);
164 return callDescriptorFunction(device, descriptorId,
165 &Descriptor::setConsumerUsage, usage);
166 }
167
168 static int32_t setDimensionsHook(gralloc1_device_t* device,
169 gralloc1_buffer_descriptor_t descriptorId, uint32_t width,
170 uint32_t height) {
171 return callDescriptorFunction(device, descriptorId,
172 &Descriptor::setDimensions, width, height);
173 }
174
175 static int32_t setFormatHook(gralloc1_device_t* device,
176 gralloc1_buffer_descriptor_t descriptorId, int32_t format) {
177 return callDescriptorFunction(device, descriptorId,
178 &Descriptor::setFormat, format);
179 }
180
181 static int32_t setLayerCountHook(gralloc1_device_t* device,
182 gralloc1_buffer_descriptor_t descriptorId, uint32_t layerCount) {
183 return callDescriptorFunction(device, descriptorId,
184 &Descriptor::setLayerCount, layerCount);
185 }
186
187 static int32_t setProducerUsageHook(gralloc1_device_t* device,
188 gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
189 auto usage = static_cast<gralloc1_producer_usage_t>(intUsage);
190 return callDescriptorFunction(device, descriptorId,
191 &Descriptor::setProducerUsage, usage);
192 }
193
194 // Buffer handle query functions
195
196 class Buffer {
197 public:
198 Buffer(buffer_handle_t handle, gralloc1_backing_store_t store,
199 const Descriptor& descriptor, uint32_t stride,
Chia-I Wu939e4012016-12-12 21:51:33 +0800200 uint32_t numFlexPlanes, bool wasAllocated);
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800201
202 buffer_handle_t getHandle() const { return mHandle; }
203
204 void retain() { ++mReferenceCount; }
205
206 // Returns true if the reference count has dropped to 0, indicating that
207 // the buffer needs to be released
208 bool release() { return --mReferenceCount == 0; }
209
210 bool wasAllocated() const { return mWasAllocated; }
211
212 gralloc1_error_t getBackingStore(
213 gralloc1_backing_store_t* outStore) const {
214 *outStore = mStore;
215 return GRALLOC1_ERROR_NONE;
216 }
217
218 gralloc1_error_t getConsumerUsage(
219 gralloc1_consumer_usage_t* outUsage) const {
220 *outUsage = mDescriptor.consumerUsage;
221 return GRALLOC1_ERROR_NONE;
222 }
223
224 gralloc1_error_t getDimensions(uint32_t* outWidth,
225 uint32_t* outHeight) const {
226 *outWidth = mDescriptor.width;
227 *outHeight = mDescriptor.height;
228 return GRALLOC1_ERROR_NONE;
229 }
230
231 gralloc1_error_t getFormat(int32_t* outFormat) const {
232 *outFormat = mDescriptor.format;
233 return GRALLOC1_ERROR_NONE;
234 }
235
236 gralloc1_error_t getLayerCount(uint32_t* outLayerCount) const {
237 *outLayerCount = mDescriptor.layerCount;
238 return GRALLOC1_ERROR_NONE;
239 }
240
241 gralloc1_error_t getNumFlexPlanes(uint32_t* outNumPlanes) const {
Chia-I Wu939e4012016-12-12 21:51:33 +0800242 *outNumPlanes = mNumFlexPlanes;
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800243 return GRALLOC1_ERROR_NONE;
244 }
245
246 gralloc1_error_t getProducerUsage(
247 gralloc1_producer_usage_t* outUsage) const {
248 *outUsage = mDescriptor.producerUsage;
249 return GRALLOC1_ERROR_NONE;
250 }
251
252 gralloc1_error_t getStride(uint32_t* outStride) const {
253 *outStride = mStride;
254 return GRALLOC1_ERROR_NONE;
255 }
256
257 private:
258
259 const buffer_handle_t mHandle;
260 size_t mReferenceCount;
261
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800262 const gralloc1_backing_store_t mStore;
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800263 const Descriptor mDescriptor;
264 const uint32_t mStride;
Chia-I Wu939e4012016-12-12 21:51:33 +0800265 const uint32_t mNumFlexPlanes;
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800266
267 // Whether this buffer allocated in this process (as opposed to just
268 // being retained here), which determines whether to free or unregister
269 // the buffer when this Buffer is released
270 const bool mWasAllocated;
271 };
272
273 template <typename ...Args>
274 static int32_t callBufferFunction(gralloc1_device_t* device,
275 buffer_handle_t bufferHandle,
276 gralloc1_error_t (Buffer::*member)(Args...) const, Args... args) {
277 auto buffer = getAdapter(device)->getBuffer(bufferHandle);
278 if (!buffer) {
279 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
280 }
281 auto error = ((*buffer).*member)(std::forward<Args>(args)...);
282 return static_cast<int32_t>(error);
283 }
284
285 template <typename MF, MF memFunc, typename ...Args>
286 static int32_t bufferHook(gralloc1_device_t* device,
287 buffer_handle_t bufferHandle, Args... args) {
288 return Gralloc1On0Adapter::callBufferFunction(device, bufferHandle,
289 memFunc, std::forward<Args>(args)...);
290 }
291
292 static int32_t getConsumerUsageHook(gralloc1_device_t* device,
293 buffer_handle_t bufferHandle, uint64_t* outUsage) {
294 auto usage = GRALLOC1_CONSUMER_USAGE_NONE;
295 auto error = callBufferFunction(device, bufferHandle,
296 &Buffer::getConsumerUsage, &usage);
Chia-I Wu939e4012016-12-12 21:51:33 +0800297 if (error == GRALLOC1_ERROR_NONE) {
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800298 *outUsage = static_cast<uint64_t>(usage);
299 }
300 return error;
301 }
302
303 static int32_t getProducerUsageHook(gralloc1_device_t* device,
304 buffer_handle_t bufferHandle, uint64_t* outUsage) {
305 auto usage = GRALLOC1_PRODUCER_USAGE_NONE;
306 auto error = callBufferFunction(device, bufferHandle,
307 &Buffer::getProducerUsage, &usage);
Chia-I Wu939e4012016-12-12 21:51:33 +0800308 if (error == GRALLOC1_ERROR_NONE) {
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800309 *outUsage = static_cast<uint64_t>(usage);
310 }
311 return error;
312 }
313
314 // Buffer management functions
315
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800316 gralloc1_error_t allocate(
Chia-I Wu939e4012016-12-12 21:51:33 +0800317 gralloc1_buffer_descriptor_t id,
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800318 const std::shared_ptr<Descriptor>& descriptor,
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800319 buffer_handle_t* outBufferHandle);
Chia-I Wu939e4012016-12-12 21:51:33 +0800320 static int32_t allocateHook(gralloc1_device* device,
321 uint32_t numDescriptors,
322 const gralloc1_buffer_descriptor_t* descriptors,
323 buffer_handle_t* outBuffers);
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800324
325 gralloc1_error_t retain(const std::shared_ptr<Buffer>& buffer);
Chia-I Wu939e4012016-12-12 21:51:33 +0800326 gralloc1_error_t retain(buffer_handle_t bufferHandle);
327 static int32_t retainHook(gralloc1_device_t* device,
328 buffer_handle_t bufferHandle)
329 {
330 auto adapter = getAdapter(device);
331 return adapter->retain(bufferHandle);
332 }
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800333
Chia-I Wu939e4012016-12-12 21:51:33 +0800334 gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer);
335 static int32_t releaseHook(gralloc1_device_t* device,
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800336 buffer_handle_t bufferHandle) {
337 auto adapter = getAdapter(device);
338
339 auto buffer = adapter->getBuffer(bufferHandle);
340 if (!buffer) {
341 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
342 }
343
Chia-I Wu939e4012016-12-12 21:51:33 +0800344 auto error = adapter->release(buffer);
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800345 return static_cast<int32_t>(error);
346 }
347
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800348 // Buffer access functions
349
350 gralloc1_error_t lock(const std::shared_ptr<Buffer>& buffer,
351 gralloc1_producer_usage_t producerUsage,
352 gralloc1_consumer_usage_t consumerUsage,
353 const gralloc1_rect_t& accessRegion, void** outData,
Chia-I Wu939e4012016-12-12 21:51:33 +0800354 int acquireFence);
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800355 gralloc1_error_t lockFlex(const std::shared_ptr<Buffer>& buffer,
356 gralloc1_producer_usage_t producerUsage,
357 gralloc1_consumer_usage_t consumerUsage,
358 const gralloc1_rect_t& accessRegion,
359 struct android_flex_layout* outFlex,
Chia-I Wu939e4012016-12-12 21:51:33 +0800360 int acquireFence);
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800361
362 template <typename OUT, gralloc1_error_t (Gralloc1On0Adapter::*member)(
363 const std::shared_ptr<Buffer>&, gralloc1_producer_usage_t,
364 gralloc1_consumer_usage_t, const gralloc1_rect_t&, OUT*,
Chia-I Wu939e4012016-12-12 21:51:33 +0800365 int)>
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800366 static int32_t lockHook(gralloc1_device_t* device,
367 buffer_handle_t bufferHandle,
368 uint64_t /*gralloc1_producer_usage_t*/ uintProducerUsage,
369 uint64_t /*gralloc1_consumer_usage_t*/ uintConsumerUsage,
370 const gralloc1_rect_t* accessRegion, OUT* outData,
371 int32_t acquireFenceFd) {
372 auto adapter = getAdapter(device);
373
374 // Exactly one of producer and consumer usage must be *_USAGE_NONE,
375 // but we can't check this until the upper levels of the framework
376 // correctly distinguish between producer and consumer usage
377 /*
378 bool hasProducerUsage =
379 uintProducerUsage != GRALLOC1_PRODUCER_USAGE_NONE;
380 bool hasConsumerUsage =
381 uintConsumerUsage != GRALLOC1_CONSUMER_USAGE_NONE;
382 if (hasProducerUsage && hasConsumerUsage ||
383 !hasProducerUsage && !hasConsumerUsage) {
384 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
385 }
386 */
387
388 auto producerUsage =
389 static_cast<gralloc1_producer_usage_t>(uintProducerUsage);
390 auto consumerUsage =
391 static_cast<gralloc1_consumer_usage_t>(uintConsumerUsage);
392
393 if (!outData) {
394 const auto producerCpuUsage = GRALLOC1_PRODUCER_USAGE_CPU_READ |
395 GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
396 if ((producerUsage & producerCpuUsage) != 0) {
397 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
398 }
399 if ((consumerUsage & GRALLOC1_CONSUMER_USAGE_CPU_READ) != 0) {
400 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
401 }
402 }
403
404 auto buffer = adapter->getBuffer(bufferHandle);
405 if (!buffer) {
406 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
407 }
408
409 if (!accessRegion) {
410 ALOGE("accessRegion is null");
411 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
412 }
413
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800414 auto error = ((*adapter).*member)(buffer, producerUsage, consumerUsage,
Chia-I Wu939e4012016-12-12 21:51:33 +0800415 *accessRegion, outData, acquireFenceFd);
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800416 return static_cast<int32_t>(error);
417 }
418
419 gralloc1_error_t unlock(const std::shared_ptr<Buffer>& buffer,
Chia-I Wu939e4012016-12-12 21:51:33 +0800420 int* outReleaseFence);
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800421 static int32_t unlockHook(gralloc1_device_t* device,
422 buffer_handle_t bufferHandle, int32_t* outReleaseFenceFd) {
423 auto adapter = getAdapter(device);
424
425 auto buffer = adapter->getBuffer(bufferHandle);
426 if (!buffer) {
427 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
428 }
429
Chia-I Wu939e4012016-12-12 21:51:33 +0800430 int releaseFence = -1;
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800431 auto error = adapter->unlock(buffer, &releaseFence);
432 if (error == GRALLOC1_ERROR_NONE) {
Chia-I Wu939e4012016-12-12 21:51:33 +0800433 *outReleaseFenceFd = releaseFence;
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800434 }
435 return static_cast<int32_t>(error);
436 }
437
438 // Adapter internals
439 const gralloc_module_t* mModule;
440 uint8_t mMinorVersion;
441 alloc_device_t* mDevice;
442
443 std::shared_ptr<Descriptor> getDescriptor(
444 gralloc1_buffer_descriptor_t descriptorId);
445 std::shared_ptr<Buffer> getBuffer(buffer_handle_t bufferHandle);
446
447 static std::atomic<gralloc1_buffer_descriptor_t> sNextBufferDescriptorId;
448 std::mutex mDescriptorMutex;
449 std::unordered_map<gralloc1_buffer_descriptor_t,
450 std::shared_ptr<Descriptor>> mDescriptors;
451 std::mutex mBufferMutex;
452 std::unordered_map<buffer_handle_t, std::shared_ptr<Buffer>> mBuffers;
453};
454
Chia-I Wu939e4012016-12-12 21:51:33 +0800455} // namespace hardware
Chia-I Wu731eb3d2016-12-12 21:48:29 +0800456} // namespace android
457
Chia-I Wu939e4012016-12-12 21:51:33 +0800458#endif // ANDROID_HARDWARE_GRALLOC_1_ON_0_ADAPTER_H