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/Gralloc2.h>
36 #include <ui/GraphicBuffer.h>
37
38 #include <system/graphics.h>
39
40 namespace android {
41 // ---------------------------------------------------------------------------
42
ANDROID_SINGLETON_STATIC_INSTANCE(GraphicBufferMapper)43 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
44
45 GraphicBufferMapper::GraphicBufferMapper()
46 : mMapper(std::make_unique<const Gralloc2::Mapper>())
47 {
48 }
49
importBuffer(buffer_handle_t rawHandle,buffer_handle_t * outHandle)50 status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
51 buffer_handle_t* outHandle)
52 {
53 ATRACE_CALL();
54
55 Gralloc2::Error error = mMapper->importBuffer(
56 hardware::hidl_handle(rawHandle), outHandle);
57
58 ALOGW_IF(error != Gralloc2::Error::NONE, "importBuffer(%p) failed: %d",
59 rawHandle, error);
60
61 return static_cast<status_t>(error);
62 }
63
freeBuffer(buffer_handle_t handle)64 status_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle)
65 {
66 ATRACE_CALL();
67
68 mMapper->freeBuffer(handle);
69
70 return NO_ERROR;
71 }
72
asGralloc2Rect(const Rect & rect)73 static inline Gralloc2::IMapper::Rect asGralloc2Rect(const Rect& rect) {
74 Gralloc2::IMapper::Rect outRect{};
75 outRect.left = rect.left;
76 outRect.top = rect.top;
77 outRect.width = rect.width();
78 outRect.height = rect.height();
79 return outRect;
80 }
81
lock(buffer_handle_t handle,uint32_t usage,const Rect & bounds,void ** vaddr)82 status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
83 const Rect& bounds, void** vaddr)
84 {
85 return lockAsync(handle, usage, bounds, vaddr, -1);
86 }
87
lockYCbCr(buffer_handle_t handle,uint32_t usage,const Rect & bounds,android_ycbcr * ycbcr)88 status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage,
89 const Rect& bounds, android_ycbcr *ycbcr)
90 {
91 return lockAsyncYCbCr(handle, usage, bounds, ycbcr, -1);
92 }
93
unlock(buffer_handle_t handle)94 status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
95 {
96 int32_t fenceFd = -1;
97 status_t error = unlockAsync(handle, &fenceFd);
98 if (error == NO_ERROR) {
99 sync_wait(fenceFd, -1);
100 close(fenceFd);
101 }
102 return error;
103 }
104
lockAsync(buffer_handle_t handle,uint32_t usage,const Rect & bounds,void ** vaddr,int fenceFd)105 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
106 uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
107 {
108 return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd);
109 }
110
lockAsync(buffer_handle_t handle,uint64_t producerUsage,uint64_t consumerUsage,const Rect & bounds,void ** vaddr,int fenceFd)111 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
112 uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds,
113 void** vaddr, int fenceFd)
114 {
115 ATRACE_CALL();
116
117 const uint64_t usage = static_cast<uint64_t>(
118 android_convertGralloc1To0Usage(producerUsage, consumerUsage));
119 Gralloc2::Error error = mMapper->lock(handle, usage,
120 asGralloc2Rect(bounds), fenceFd, vaddr);
121
122 ALOGW_IF(error != Gralloc2::Error::NONE, "lock(%p, ...) failed: %d",
123 handle, error);
124
125 return static_cast<status_t>(error);
126 }
127
isValidYCbCrPlane(const android_flex_plane_t & plane)128 static inline bool isValidYCbCrPlane(const android_flex_plane_t& plane) {
129 if (plane.bits_per_component != 8) {
130 ALOGV("Invalid number of bits per component: %d",
131 plane.bits_per_component);
132 return false;
133 }
134 if (plane.bits_used != 8) {
135 ALOGV("Invalid number of bits used: %d", plane.bits_used);
136 return false;
137 }
138
139 bool hasValidIncrement = plane.h_increment == 1 ||
140 (plane.component != FLEX_COMPONENT_Y && plane.h_increment == 2);
141 hasValidIncrement = hasValidIncrement && plane.v_increment > 0;
142 if (!hasValidIncrement) {
143 ALOGV("Invalid increment: h %d v %d", plane.h_increment,
144 plane.v_increment);
145 return false;
146 }
147
148 return true;
149 }
150
lockAsyncYCbCr(buffer_handle_t handle,uint32_t usage,const Rect & bounds,android_ycbcr * ycbcr,int fenceFd)151 status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
152 uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
153 {
154 ATRACE_CALL();
155
156 Gralloc2::YCbCrLayout layout;
157 Gralloc2::Error error = mMapper->lock(handle, usage,
158 asGralloc2Rect(bounds), fenceFd, &layout);
159 if (error == Gralloc2::Error::NONE) {
160 ycbcr->y = layout.y;
161 ycbcr->cb = layout.cb;
162 ycbcr->cr = layout.cr;
163 ycbcr->ystride = static_cast<size_t>(layout.yStride);
164 ycbcr->cstride = static_cast<size_t>(layout.cStride);
165 ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
166 }
167
168 return static_cast<status_t>(error);
169 }
170
unlockAsync(buffer_handle_t handle,int * fenceFd)171 status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
172 {
173 ATRACE_CALL();
174
175 *fenceFd = mMapper->unlock(handle);
176
177 return NO_ERROR;
178 }
179
180 // ---------------------------------------------------------------------------
181 }; // namespace android
182