1 /*
2 * Copyright (C) 2007 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 #define LOG_TAG "GraphicBufferMapper"
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 //#define LOG_NDEBUG 0
20
21 #include <ui/GraphicBufferMapper.h>
22
23 #include <grallocusage/GrallocUsageConversion.h>
24
25 // We would eliminate the non-conforming zero-length array, but we can't since
26 // this is effectively included from the Linux kernel
27 #pragma clang diagnostic push
28 #pragma clang diagnostic ignored "-Wzero-length-array"
29 #include <sync/sync.h>
30 #pragma clang diagnostic pop
31
32 #include <utils/Log.h>
33 #include <utils/Trace.h>
34
35 #include <ui/Gralloc.h>
36 #include <ui/Gralloc2.h>
37 #include <ui/Gralloc3.h>
38 #include <ui/GraphicBuffer.h>
39
40 #include <system/graphics.h>
41
42 namespace android {
43 // ---------------------------------------------------------------------------
44
ANDROID_SINGLETON_STATIC_INSTANCE(GraphicBufferMapper)45 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
46
47 void GraphicBufferMapper::preloadHal() {
48 Gralloc2Mapper::preload();
49 Gralloc3Mapper::preload();
50 }
51
GraphicBufferMapper()52 GraphicBufferMapper::GraphicBufferMapper() {
53 mMapper = std::make_unique<const Gralloc3Mapper>();
54 if (!mMapper->isLoaded()) {
55 mMapper = std::make_unique<const Gralloc2Mapper>();
56 mMapperVersion = Version::GRALLOC_2;
57 } else {
58 mMapperVersion = Version::GRALLOC_3;
59 }
60
61 if (!mMapper->isLoaded()) {
62 LOG_ALWAYS_FATAL("gralloc-mapper is missing");
63 }
64 }
65
importBuffer(buffer_handle_t rawHandle,uint32_t width,uint32_t height,uint32_t layerCount,PixelFormat format,uint64_t usage,uint32_t stride,buffer_handle_t * outHandle)66 status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
67 uint32_t width, uint32_t height, uint32_t layerCount,
68 PixelFormat format, uint64_t usage, uint32_t stride,
69 buffer_handle_t* outHandle)
70 {
71 ATRACE_CALL();
72
73 buffer_handle_t bufferHandle;
74 status_t error = mMapper->importBuffer(hardware::hidl_handle(rawHandle), &bufferHandle);
75 if (error != NO_ERROR) {
76 ALOGW("importBuffer(%p) failed: %d", rawHandle, error);
77 return error;
78 }
79
80 error = mMapper->validateBufferSize(bufferHandle, width, height, format, layerCount, usage,
81 stride);
82 if (error != NO_ERROR) {
83 ALOGE("validateBufferSize(%p) failed: %d", rawHandle, error);
84 freeBuffer(bufferHandle);
85 return static_cast<status_t>(error);
86 }
87
88 *outHandle = bufferHandle;
89
90 return NO_ERROR;
91 }
92
getTransportSize(buffer_handle_t handle,uint32_t * outTransportNumFds,uint32_t * outTransportNumInts)93 void GraphicBufferMapper::getTransportSize(buffer_handle_t handle,
94 uint32_t* outTransportNumFds, uint32_t* outTransportNumInts)
95 {
96 mMapper->getTransportSize(handle, outTransportNumFds, outTransportNumInts);
97 }
98
freeBuffer(buffer_handle_t handle)99 status_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle)
100 {
101 ATRACE_CALL();
102
103 mMapper->freeBuffer(handle);
104
105 return NO_ERROR;
106 }
107
lock(buffer_handle_t handle,uint32_t usage,const Rect & bounds,void ** vaddr,int32_t * outBytesPerPixel,int32_t * outBytesPerStride)108 status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage, const Rect& bounds,
109 void** vaddr, int32_t* outBytesPerPixel,
110 int32_t* outBytesPerStride) {
111 return lockAsync(handle, usage, bounds, vaddr, -1, outBytesPerPixel, outBytesPerStride);
112 }
113
lockYCbCr(buffer_handle_t handle,uint32_t usage,const Rect & bounds,android_ycbcr * ycbcr)114 status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage,
115 const Rect& bounds, android_ycbcr *ycbcr)
116 {
117 return lockAsyncYCbCr(handle, usage, bounds, ycbcr, -1);
118 }
119
unlock(buffer_handle_t handle)120 status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
121 {
122 int32_t fenceFd = -1;
123 status_t error = unlockAsync(handle, &fenceFd);
124 if (error == NO_ERROR && fenceFd >= 0) {
125 sync_wait(fenceFd, -1);
126 close(fenceFd);
127 }
128 return error;
129 }
130
lockAsync(buffer_handle_t handle,uint32_t usage,const Rect & bounds,void ** vaddr,int fenceFd,int32_t * outBytesPerPixel,int32_t * outBytesPerStride)131 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint32_t usage, const Rect& bounds,
132 void** vaddr, int fenceFd, int32_t* outBytesPerPixel,
133 int32_t* outBytesPerStride) {
134 return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd, outBytesPerPixel,
135 outBytesPerStride);
136 }
137
lockAsync(buffer_handle_t handle,uint64_t producerUsage,uint64_t consumerUsage,const Rect & bounds,void ** vaddr,int fenceFd,int32_t * outBytesPerPixel,int32_t * outBytesPerStride)138 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle, uint64_t producerUsage,
139 uint64_t consumerUsage, const Rect& bounds, void** vaddr,
140 int fenceFd, int32_t* outBytesPerPixel,
141 int32_t* outBytesPerStride) {
142 ATRACE_CALL();
143
144 const uint64_t usage = static_cast<uint64_t>(
145 android_convertGralloc1To0Usage(producerUsage, consumerUsage));
146 return mMapper->lock(handle, usage, bounds, fenceFd, vaddr, outBytesPerPixel,
147 outBytesPerStride);
148 }
149
lockAsyncYCbCr(buffer_handle_t handle,uint32_t usage,const Rect & bounds,android_ycbcr * ycbcr,int fenceFd)150 status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
151 uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
152 {
153 ATRACE_CALL();
154
155 return mMapper->lock(handle, usage, bounds, fenceFd, ycbcr);
156 }
157
unlockAsync(buffer_handle_t handle,int * fenceFd)158 status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
159 {
160 ATRACE_CALL();
161
162 *fenceFd = mMapper->unlock(handle);
163
164 return NO_ERROR;
165 }
166
isSupported(uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,bool * outSupported)167 status_t GraphicBufferMapper::isSupported(uint32_t width, uint32_t height,
168 android::PixelFormat format, uint32_t layerCount,
169 uint64_t usage, bool* outSupported) {
170 return mMapper->isSupported(width, height, format, layerCount, usage, outSupported);
171 }
172 // ---------------------------------------------------------------------------
173 }; // namespace android
174