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