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