• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 The Android Open Source Project
3  * * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #define LOG_TAG "Gralloc1Mapper"
17 
18 #include "Gralloc1Mapper.h"
19 
20 #include <vector>
21 
22 #include <log/log.h>
23 
24 namespace android {
25 namespace hardware {
26 namespace graphics {
27 namespace mapper {
28 namespace V2_0 {
29 namespace implementation {
30 
31 using android::hardware::graphics::common::V1_0::BufferUsage;
32 
Gralloc1Mapper(const hw_module_t * module)33 Gralloc1Mapper::Gralloc1Mapper(const hw_module_t* module)
34     : mDevice(nullptr), mDispatch() {
35     int result = gralloc1_open(module, &mDevice);
36     if (result) {
37         LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
38                          strerror(-result));
39     }
40 
41     initCapabilities();
42     initDispatch();
43 }
44 
~Gralloc1Mapper()45 Gralloc1Mapper::~Gralloc1Mapper() {
46     gralloc1_close(mDevice);
47 }
48 
initCapabilities()49 void Gralloc1Mapper::initCapabilities() {
50     mCapabilities.highUsageBits = true;
51     mCapabilities.layeredBuffers = false;
52     mCapabilities.unregisterImplyDelete = false;
53 
54     uint32_t count = 0;
55     mDevice->getCapabilities(mDevice, &count, nullptr);
56 
57     std::vector<int32_t> capabilities(count);
58     mDevice->getCapabilities(mDevice, &count, capabilities.data());
59     capabilities.resize(count);
60 
61     for (auto capability : capabilities) {
62         switch (capability) {
63             case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
64                 mCapabilities.layeredBuffers = true;
65                 break;
66             case GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE:
67                 mCapabilities.unregisterImplyDelete = true;
68                 break;
69         }
70     }
71 }
72 
73 template <typename T>
initDispatch(gralloc1_function_descriptor_t desc,T * outPfn)74 void Gralloc1Mapper::initDispatch(gralloc1_function_descriptor_t desc,
75                                   T* outPfn) {
76     auto pfn = mDevice->getFunction(mDevice, desc);
77     if (!pfn) {
78         LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
79     }
80 
81     *outPfn = reinterpret_cast<T>(pfn);
82 }
83 
initDispatch()84 void Gralloc1Mapper::initDispatch() {
85     initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain);
86     initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
87     initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES,
88                  &mDispatch.getNumFlexPlanes);
89     initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock);
90     initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex);
91     initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock);
92 }
93 
toError(int32_t error)94 Error Gralloc1Mapper::toError(int32_t error) {
95     switch (error) {
96         case GRALLOC1_ERROR_NONE:
97             return Error::NONE;
98         case GRALLOC1_ERROR_BAD_DESCRIPTOR:
99             return Error::BAD_DESCRIPTOR;
100         case GRALLOC1_ERROR_BAD_HANDLE:
101             return Error::BAD_BUFFER;
102         case GRALLOC1_ERROR_BAD_VALUE:
103             return Error::BAD_VALUE;
104         case GRALLOC1_ERROR_NOT_SHARED:
105             return Error::NONE;  // this is fine
106         case GRALLOC1_ERROR_NO_RESOURCES:
107             return Error::NO_RESOURCES;
108         case GRALLOC1_ERROR_UNDEFINED:
109         case GRALLOC1_ERROR_UNSUPPORTED:
110         default:
111             return Error::UNSUPPORTED;
112     }
113 }
114 
toYCbCrLayout(const android_flex_layout & flex,YCbCrLayout * outLayout)115 bool Gralloc1Mapper::toYCbCrLayout(const android_flex_layout& flex,
116                                    YCbCrLayout* outLayout) {
117     // must be YCbCr
118     if (flex.format != FLEX_FORMAT_YCbCr || flex.num_planes < 3) {
119         return false;
120     }
121 
122     for (int i = 0; i < 3; i++) {
123         const auto& plane = flex.planes[i];
124         // must have 8-bit depth
125         if (plane.bits_per_component != 8 || plane.bits_used != 8) {
126             return false;
127         }
128 
129         if (plane.component == FLEX_COMPONENT_Y) {
130             // Y must not be interleaved
131             if (plane.h_increment != 1) {
132                 return false;
133             }
134         } else {
135             // Cb and Cr can be interleaved
136             if (plane.h_increment != 1 && plane.h_increment != 2) {
137                 return false;
138             }
139         }
140 
141         if (!plane.v_increment) {
142             return false;
143         }
144     }
145 
146     if (flex.planes[0].component != FLEX_COMPONENT_Y ||
147         flex.planes[1].component != FLEX_COMPONENT_Cb ||
148         flex.planes[2].component != FLEX_COMPONENT_Cr) {
149         return false;
150     }
151 
152     const auto& y = flex.planes[0];
153     const auto& cb = flex.planes[1];
154     const auto& cr = flex.planes[2];
155 
156     if (cb.h_increment != cr.h_increment || cb.v_increment != cr.v_increment) {
157         return false;
158     }
159 
160     outLayout->y = y.top_left;
161     outLayout->cb = cb.top_left;
162     outLayout->cr = cr.top_left;
163     outLayout->yStride = y.v_increment;
164     outLayout->cStride = cb.v_increment;
165     outLayout->chromaStep = cb.h_increment;
166 
167     return true;
168 }
169 
asGralloc1Rect(const IMapper::Rect & rect)170 gralloc1_rect_t Gralloc1Mapper::asGralloc1Rect(const IMapper::Rect& rect) {
171     return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
172 }
173 
registerBuffer(buffer_handle_t bufferHandle)174 Error Gralloc1Mapper::registerBuffer(buffer_handle_t bufferHandle) {
175     return toError(mDispatch.retain(mDevice, bufferHandle));
176 }
177 
unregisterBuffer(buffer_handle_t bufferHandle)178 void Gralloc1Mapper::unregisterBuffer(buffer_handle_t bufferHandle) {
179     mDispatch.release(mDevice, bufferHandle);
180 }
181 
lockBuffer(buffer_handle_t bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,int fenceFd,void ** outData)182 Error Gralloc1Mapper::lockBuffer(buffer_handle_t bufferHandle,
183                                  uint64_t cpuUsage,
184                                  const IMapper::Rect& accessRegion, int fenceFd,
185                                  void** outData) {
186     // Dup fenceFd as it is going to be owned by gralloc.  Note that it is
187     // gralloc's responsibility to close it, even on locking errors.
188     if (fenceFd >= 0) {
189         fenceFd = dup(fenceFd);
190         if (fenceFd < 0) {
191             return Error::NO_RESOURCES;
192         }
193     }
194 
195     const uint64_t consumerUsage =
196         cpuUsage & ~static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK);
197     const auto accessRect = asGralloc1Rect(accessRegion);
198     void* data = nullptr;
199     int32_t error = mDispatch.lock(mDevice, bufferHandle, cpuUsage,
200                                    consumerUsage, &accessRect, &data, fenceFd);
201 
202     if (error == GRALLOC1_ERROR_NONE) {
203         *outData = data;
204     }
205 
206     return toError(error);
207 }
208 
lockBuffer(buffer_handle_t bufferHandle,uint64_t cpuUsage,const IMapper::Rect & accessRegion,int fenceFd,YCbCrLayout * outLayout)209 Error Gralloc1Mapper::lockBuffer(buffer_handle_t bufferHandle,
210                                  uint64_t cpuUsage,
211                                  const IMapper::Rect& accessRegion, int fenceFd,
212                                  YCbCrLayout* outLayout) {
213     // prepare flex layout
214     android_flex_layout flex = {};
215     int32_t error =
216         mDispatch.getNumFlexPlanes(mDevice, bufferHandle, &flex.num_planes);
217     if (error != GRALLOC1_ERROR_NONE) {
218         return toError(error);
219     }
220     std::vector<android_flex_plane_t> flexPlanes(flex.num_planes);
221     flex.planes = flexPlanes.data();
222 
223     // Dup fenceFd as it is going to be owned by gralloc.  Note that it is
224     // gralloc's responsibility to close it, even on locking errors.
225     if (fenceFd >= 0) {
226         fenceFd = dup(fenceFd);
227         if (fenceFd < 0) {
228             return Error::NO_RESOURCES;
229         }
230     }
231 
232     const uint64_t consumerUsage =
233         cpuUsage & ~static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK);
234     const auto accessRect = asGralloc1Rect(accessRegion);
235     error = mDispatch.lockFlex(mDevice, bufferHandle, cpuUsage, consumerUsage,
236                                &accessRect, &flex, fenceFd);
237     if (error == GRALLOC1_ERROR_NONE && !toYCbCrLayout(flex, outLayout)) {
238         ALOGD("unable to convert android_flex_layout to YCbCrLayout");
239 
240         // undo the lock
241         fenceFd = -1;
242         mDispatch.unlock(mDevice, bufferHandle, &fenceFd);
243         if (fenceFd >= 0) {
244             close(fenceFd);
245         }
246 
247         error = GRALLOC1_ERROR_BAD_HANDLE;
248     }
249 
250     return toError(error);
251 }
252 
unlockBuffer(buffer_handle_t bufferHandle,int * outFenceFd)253 Error Gralloc1Mapper::unlockBuffer(buffer_handle_t bufferHandle,
254                                    int* outFenceFd) {
255     int fenceFd = -1;
256     int32_t error = mDispatch.unlock(mDevice, bufferHandle, &fenceFd);
257 
258     if (error == GRALLOC1_ERROR_NONE) {
259         *outFenceFd = fenceFd;
260     } else if (fenceFd >= 0) {
261         // we always own the fenceFd even when unlock failed
262         close(fenceFd);
263     }
264 
265     return toError(error);
266 }
267 
268 }  // namespace implementation
269 }  // namespace V2_0
270 }  // namespace mapper
271 }  // namespace graphics
272 }  // namespace hardware
273 }  // namespace android
274