blob: 97c9a89d32feaf82feff626a6c9f92aac41af89e [file] [log] [blame]
Dan Stozaeb03fd32016-01-11 15:21:07 -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
17#ifndef ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
18#define ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
19
20#include <ui/Fence.h>
21#include <ui/GraphicBuffer.h>
22
23#include <hardware/gralloc1.h>
24
25#include <mutex>
26#include <string>
27#include <unordered_map>
28#include <vector>
29
30struct gralloc_module_t;
31
32// This is not an "official" capability (i.e., it is not found in gralloc1.h),
33// but we will use it to detect that we are running through the adapter, which
34// is capable of collaborating with GraphicBuffer such that queries on a
35// buffer_handle_t succeed
36static const auto GRALLOC1_CAPABILITY_ON_ADAPTER =
37 static_cast<gralloc1_capability_t>(GRALLOC1_LAST_CAPABILITY + 1);
38
39static const auto GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER =
40 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 1);
41static const auto GRALLOC1_FUNCTION_ALLOCATE_WITH_ID =
42 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 2);
43static const auto GRALLOC1_FUNCTION_LOCK_YCBCR =
44 static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 3);
45static const auto GRALLOC1_LAST_ADAPTER_FUNCTION = GRALLOC1_FUNCTION_LOCK_YCBCR;
46
47typedef gralloc1_error_t (*GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER)(
48 gralloc1_device_t* device, const android::GraphicBuffer* buffer);
49typedef gralloc1_error_t (*GRALLOC1_PFN_ALLOCATE_WITH_ID)(
50 gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
51 gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
52typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK_YCBCR)(
53 gralloc1_device_t* device, buffer_handle_t buffer,
54 uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
55 uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
56 const gralloc1_rect_t* accessRegion, struct android_ycbcr* outYCbCr,
57 int32_t acquireFence);
58
59namespace android {
60
61class Gralloc1On0Adapter : public gralloc1_device_t
62{
63public:
64 Gralloc1On0Adapter(const hw_module_t* module);
65 ~Gralloc1On0Adapter();
66
67 gralloc1_device_t* getDevice() {
68 return static_cast<gralloc1_device_t*>(this);
69 }
70
71private:
72 static inline Gralloc1On0Adapter* getAdapter(gralloc1_device_t* device) {
73 return static_cast<Gralloc1On0Adapter*>(device);
74 }
75
76 // getCapabilities
77
78 void doGetCapabilities(uint32_t* outCount,
79 int32_t* /*gralloc1_capability_t*/ outCapabilities);
80 static void getCapabilitiesHook(gralloc1_device_t* device,
81 uint32_t* outCount,
82 int32_t* /*gralloc1_capability_t*/ outCapabilities) {
83 getAdapter(device)->doGetCapabilities(outCount, outCapabilities);
84 };
85
86 // getFunction
87
88 gralloc1_function_pointer_t doGetFunction(
89 int32_t /*gralloc1_function_descriptor_t*/ descriptor);
90 static gralloc1_function_pointer_t getFunctionHook(
91 gralloc1_device_t* device,
92 int32_t /*gralloc1_function_descriptor_t*/ descriptor) {
93 return getAdapter(device)->doGetFunction(descriptor);
94 }
95
96 // dump
97
98 void dump(uint32_t* outSize, char* outBuffer);
99 static void dumpHook(gralloc1_device_t* device, uint32_t* outSize,
100 char* outBuffer) {
101 return getAdapter(device)->dump(outSize, outBuffer);
102 }
103 std::string mCachedDump;
104
105 // Buffer descriptor lifecycle functions
106
107 class Descriptor;
108
109 gralloc1_error_t createDescriptor(
110 gralloc1_buffer_descriptor_t* outDescriptor);
111 static int32_t createDescriptorHook(gralloc1_device_t* device,
112 gralloc1_buffer_descriptor_t* outDescriptor) {
113 auto error = getAdapter(device)->createDescriptor(outDescriptor);
114 return static_cast<int32_t>(error);
115 }
116
117 gralloc1_error_t destroyDescriptor(gralloc1_buffer_descriptor_t descriptor);
118 static int32_t destroyDescriptorHook(gralloc1_device_t* device,
119 gralloc1_buffer_descriptor_t descriptor) {
120 auto error = getAdapter(device)->destroyDescriptor(descriptor);
121 return static_cast<int32_t>(error);
122 }
123
124 // Buffer descriptor modification functions
125
126 struct Descriptor : public std::enable_shared_from_this<Descriptor> {
127 Descriptor(Gralloc1On0Adapter* adapter,
128 gralloc1_buffer_descriptor_t id)
129 : adapter(adapter),
130 id(id),
131 width(0),
132 height(0),
133 format(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
134 producerUsage(GRALLOC1_PRODUCER_USAGE_NONE),
135 consumerUsage(GRALLOC1_CONSUMER_USAGE_NONE) {}
136
137 gralloc1_error_t setDimensions(uint32_t w, uint32_t h) {
138 width = w;
139 height = h;
140 return GRALLOC1_ERROR_NONE;
141 }
142
143 gralloc1_error_t setFormat(int32_t f) {
144 format = f;
145 return GRALLOC1_ERROR_NONE;
146 }
147
148 gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage) {
149 producerUsage = usage;
150 return GRALLOC1_ERROR_NONE;
151 }
152
153 gralloc1_error_t setConsumerUsage(gralloc1_consumer_usage_t usage) {
154 consumerUsage = usage;
155 return GRALLOC1_ERROR_NONE;
156 }
157
158 Gralloc1On0Adapter* const adapter;
159 const gralloc1_buffer_descriptor_t id;
160
161 uint32_t width;
162 uint32_t height;
163 int32_t format;
164 gralloc1_producer_usage_t producerUsage;
165 gralloc1_consumer_usage_t consumerUsage;
166 };
167
168 template <typename ...Args>
169 static int32_t callDescriptorFunction(gralloc1_device_t* device,
170 gralloc1_buffer_descriptor_t descriptorId,
171 gralloc1_error_t (Descriptor::*member)(Args...), Args... args) {
172 auto descriptor = getAdapter(device)->getDescriptor(descriptorId);
173 if (!descriptor) {
174 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
175 }
176 auto error = ((*descriptor).*member)(std::forward<Args>(args)...);
177 return static_cast<int32_t>(error);
178 }
179
180 static int32_t setConsumerUsageHook(gralloc1_device_t* device,
181 gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
182 auto usage = static_cast<gralloc1_consumer_usage_t>(intUsage);
183 return callDescriptorFunction(device, descriptorId,
184 &Descriptor::setConsumerUsage, usage);
185 }
186
187 static int32_t setDimensionsHook(gralloc1_device_t* device,
188 gralloc1_buffer_descriptor_t descriptorId, uint32_t width,
189 uint32_t height) {
190 return callDescriptorFunction(device, descriptorId,
191 &Descriptor::setDimensions, width, height);
192 }
193
194 static int32_t setFormatHook(gralloc1_device_t* device,
195 gralloc1_buffer_descriptor_t descriptorId, int32_t format) {
196 return callDescriptorFunction(device, descriptorId,
197 &Descriptor::setFormat, format);
198 }
199
200 static int32_t setProducerUsageHook(gralloc1_device_t* device,
201 gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
202 auto usage = static_cast<gralloc1_producer_usage_t>(intUsage);
203 return callDescriptorFunction(device, descriptorId,
204 &Descriptor::setProducerUsage, usage);
205 }
206
207 // Buffer handle query functions
208
209 class Buffer {
210 public:
211 Buffer(buffer_handle_t handle, gralloc1_backing_store_t store,
212 const Descriptor& descriptor, uint32_t stride,
213 bool wasAllocated);
214
215 buffer_handle_t getHandle() const { return mHandle; }
216
217 void retain() { ++mReferenceCount; }
218
219 // Returns true if the reference count has dropped to 0, indicating that
220 // the buffer needs to be released
221 bool release() { return --mReferenceCount == 0; }
222
223 bool wasAllocated() const { return mWasAllocated; }
224
225 gralloc1_error_t getBackingStore(
226 gralloc1_backing_store_t* outStore) const {
227 *outStore = mStore;
228 return GRALLOC1_ERROR_NONE;
229 }
230
231 gralloc1_error_t getConsumerUsage(
232 gralloc1_consumer_usage_t* outUsage) const {
233 *outUsage = mDescriptor.consumerUsage;
234 return GRALLOC1_ERROR_NONE;
235 }
236
237 gralloc1_error_t getDimensions(uint32_t* outWidth,
238 uint32_t* outHeight) const {
239 *outWidth = mDescriptor.width;
240 *outHeight = mDescriptor.height;
241 return GRALLOC1_ERROR_NONE;
242 }
243
244 gralloc1_error_t getFormat(int32_t* outFormat) const {
245 *outFormat = mDescriptor.format;
246 return GRALLOC1_ERROR_NONE;
247 }
248
249 gralloc1_error_t getNumFlexPlanes(uint32_t* outNumPlanes) const {
250 // TODO: This is conservative, and we could do better by examining
251 // the format, but it won't hurt anything for now
252 *outNumPlanes = 4;
253 return GRALLOC1_ERROR_NONE;
254 }
255
256 gralloc1_error_t getProducerUsage(
257 gralloc1_producer_usage_t* outUsage) const {
258 *outUsage = mDescriptor.producerUsage;
259 return GRALLOC1_ERROR_NONE;
260 }
261
262 gralloc1_error_t getStride(uint32_t* outStride) const {
263 *outStride = mStride;
264 return GRALLOC1_ERROR_NONE;
265 }
266
267 private:
268
269 const buffer_handle_t mHandle;
270 size_t mReferenceCount;
271
272 // Since we're adapting to gralloc0, there will always be a 1:1
273 // correspondence between buffer handles and backing stores, and the
274 // backing store ID will be the same as the GraphicBuffer unique ID
275 const gralloc1_backing_store_t mStore;
276
277 const Descriptor mDescriptor;
278 const uint32_t mStride;
279
280 // Whether this buffer allocated in this process (as opposed to just
281 // being retained here), which determines whether to free or unregister
282 // the buffer when this Buffer is released
283 const bool mWasAllocated;
284 };
285
286 template <typename ...Args>
287 static int32_t callBufferFunction(gralloc1_device_t* device,
288 buffer_handle_t bufferHandle,
289 gralloc1_error_t (Buffer::*member)(Args...) const, Args... args) {
290 auto buffer = getAdapter(device)->getBuffer(bufferHandle);
291 if (!buffer) {
292 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
293 }
294 auto error = ((*buffer).*member)(std::forward<Args>(args)...);
295 return static_cast<int32_t>(error);
296 }
297
298 template <typename MF, MF memFunc, typename ...Args>
299 static int32_t bufferHook(gralloc1_device_t* device,
300 buffer_handle_t bufferHandle, Args... args) {
301 return Gralloc1On0Adapter::callBufferFunction(device, bufferHandle,
302 memFunc, std::forward<Args>(args)...);
303 }
304
305 static int32_t getConsumerUsageHook(gralloc1_device_t* device,
306 buffer_handle_t bufferHandle, uint64_t* outUsage) {
307 auto usage = GRALLOC1_CONSUMER_USAGE_NONE;
308 auto error = callBufferFunction(device, bufferHandle,
309 &Buffer::getConsumerUsage, &usage);
310 if (error != GRALLOC1_ERROR_NONE) {
311 *outUsage = static_cast<uint64_t>(usage);
312 }
313 return error;
314 }
315
316 static int32_t getProducerUsageHook(gralloc1_device_t* device,
317 buffer_handle_t bufferHandle, uint64_t* outUsage) {
318 auto usage = GRALLOC1_PRODUCER_USAGE_NONE;
319 auto error = callBufferFunction(device, bufferHandle,
320 &Buffer::getProducerUsage, &usage);
321 if (error != GRALLOC1_ERROR_NONE) {
322 *outUsage = static_cast<uint64_t>(usage);
323 }
324 return error;
325 }
326
327 // Buffer management functions
328
329 // We don't provide GRALLOC1_FUNCTION_ALLOCATE, since this should always be
330 // called through GRALLOC1_FUNCTION_ALLOCATE_WITH_ID
331 gralloc1_error_t allocate(
332 const std::shared_ptr<Descriptor>& descriptor,
333 gralloc1_backing_store_t id,
334 buffer_handle_t* outBufferHandle);
335 static gralloc1_error_t allocateWithIdHook(gralloc1_device_t* device,
336 gralloc1_buffer_descriptor_t descriptors,
337 gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
338
339 gralloc1_error_t retain(const std::shared_ptr<Buffer>& buffer);
340 gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer);
341
342 // Member function pointer 'member' will either be retain or release
343 template <gralloc1_error_t (Gralloc1On0Adapter::*member)(
344 const std::shared_ptr<Buffer>& buffer)>
345 static int32_t managementHook(gralloc1_device_t* device,
346 buffer_handle_t bufferHandle) {
347 auto adapter = getAdapter(device);
348
349 auto buffer = adapter->getBuffer(bufferHandle);
350 if (!buffer) {
351 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
352 }
353
354 auto error = ((*adapter).*member)(buffer);
355 return static_cast<int32_t>(error);
356 }
357
358 gralloc1_error_t retain(const GraphicBuffer* buffer);
359 static gralloc1_error_t retainGraphicBufferHook(gralloc1_device_t* device,
360 const GraphicBuffer* buffer) {
361 auto adapter = getAdapter(device);
362 return adapter->retain(buffer);
363 }
364
365 // Buffer access functions
366
367 gralloc1_error_t lock(const std::shared_ptr<Buffer>& buffer,
368 gralloc1_producer_usage_t producerUsage,
369 gralloc1_consumer_usage_t consumerUsage,
370 const gralloc1_rect_t& accessRegion, void** outData,
371 const sp<Fence>& acquireFence);
372 gralloc1_error_t lockFlex(const std::shared_ptr<Buffer>& buffer,
373 gralloc1_producer_usage_t producerUsage,
374 gralloc1_consumer_usage_t consumerUsage,
375 const gralloc1_rect_t& accessRegion,
376 struct android_flex_layout* outFlex,
377 const sp<Fence>& acquireFence);
378 gralloc1_error_t lockYCbCr(const std::shared_ptr<Buffer>& buffer,
379 gralloc1_producer_usage_t producerUsage,
380 gralloc1_consumer_usage_t consumerUsage,
381 const gralloc1_rect_t& accessRegion,
382 struct android_ycbcr* outFlex,
383 const sp<Fence>& acquireFence);
384
385 template <typename OUT, gralloc1_error_t (Gralloc1On0Adapter::*member)(
386 const std::shared_ptr<Buffer>&, gralloc1_producer_usage_t,
387 gralloc1_consumer_usage_t, const gralloc1_rect_t&, OUT*,
388 const sp<Fence>&)>
389 static int32_t lockHook(gralloc1_device_t* device,
390 buffer_handle_t bufferHandle,
391 uint64_t /*gralloc1_producer_usage_t*/ uintProducerUsage,
392 uint64_t /*gralloc1_consumer_usage_t*/ uintConsumerUsage,
393 const gralloc1_rect_t* accessRegion, OUT* outData,
394 int32_t acquireFenceFd) {
395 auto adapter = getAdapter(device);
396
397 // Exactly one of producer and consumer usage must be *_USAGE_NONE,
398 // but we can't check this until the upper levels of the framework
399 // correctly distinguish between producer and consumer usage
400 /*
401 bool hasProducerUsage =
402 uintProducerUsage != GRALLOC1_PRODUCER_USAGE_NONE;
403 bool hasConsumerUsage =
404 uintConsumerUsage != GRALLOC1_CONSUMER_USAGE_NONE;
405 if (hasProducerUsage && hasConsumerUsage ||
406 !hasProducerUsage && !hasConsumerUsage) {
407 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
408 }
409 */
410
411 auto producerUsage =
412 static_cast<gralloc1_producer_usage_t>(uintProducerUsage);
413 auto consumerUsage =
414 static_cast<gralloc1_consumer_usage_t>(uintConsumerUsage);
415
416 if (!outData) {
417 const auto producerCpuUsage = GRALLOC1_PRODUCER_USAGE_CPU_READ |
418 GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
419 if (producerUsage & producerCpuUsage != 0) {
420 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
421 }
422 if (consumerUsage & GRALLOC1_CONSUMER_USAGE_CPU_READ != 0) {
423 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
424 }
425 }
426
427 auto buffer = adapter->getBuffer(bufferHandle);
428 if (!buffer) {
429 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
430 }
431
432 if (!accessRegion) {
433 ALOGE("accessRegion is null");
434 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
435 }
436
437 sp<Fence> acquireFence{new Fence(acquireFenceFd)};
438 auto error = ((*adapter).*member)(buffer, producerUsage, consumerUsage,
439 *accessRegion, outData, acquireFence);
440 return static_cast<int32_t>(error);
441 }
442
443 gralloc1_error_t unlock(const std::shared_ptr<Buffer>& buffer,
444 sp<Fence>* outReleaseFence);
445 static int32_t unlockHook(gralloc1_device_t* device,
446 buffer_handle_t bufferHandle, int32_t* outReleaseFenceFd) {
447 auto adapter = getAdapter(device);
448
449 auto buffer = adapter->getBuffer(bufferHandle);
450 if (!buffer) {
451 return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
452 }
453
454 sp<Fence> releaseFence = Fence::NO_FENCE;
455 auto error = adapter->unlock(buffer, &releaseFence);
456 if (error == GRALLOC1_ERROR_NONE) {
457 *outReleaseFenceFd = releaseFence->dup();
458 }
459 return static_cast<int32_t>(error);
460 }
461
462 // Adapter internals
463 const gralloc_module_t* mModule;
464 uint8_t mMinorVersion;
465 alloc_device_t* mDevice;
466
467 std::shared_ptr<Descriptor> getDescriptor(
468 gralloc1_buffer_descriptor_t descriptorId);
469 std::shared_ptr<Buffer> getBuffer(buffer_handle_t bufferHandle);
470
471 static std::atomic<gralloc1_buffer_descriptor_t> sNextBufferDescriptorId;
472 std::mutex mDescriptorMutex;
473 std::unordered_map<gralloc1_buffer_descriptor_t,
474 std::shared_ptr<Descriptor>> mDescriptors;
475 std::mutex mBufferMutex;
476 std::unordered_map<buffer_handle_t, std::shared_ptr<Buffer>> mBuffers;
477};
478
479} // namespace android
480
481#endif