xref: /aosp_15_r20/frameworks/native/libs/ui/Gralloc2.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2016 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "Gralloc2"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <hidl/ServiceManagement.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <hwbinder/IPCThreadState.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <ui/Gralloc2.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
25*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic push
26*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Wzero-length-array"
27*38e8c45fSAndroid Build Coastguard Worker #include <sync/sync.h>
28*38e8c45fSAndroid Build Coastguard Worker #pragma clang diagnostic pop
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::allocator::V2_0::IAllocator;
31*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::common::V1_1::BufferUsage;
32*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::common::V1_1::PixelFormat;
33*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
34*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::mapper::V2_0::Error;
35*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
36*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::mapper::V2_1::IMapper;
37*38e8c45fSAndroid Build Coastguard Worker 
38*38e8c45fSAndroid Build Coastguard Worker namespace android {
39*38e8c45fSAndroid Build Coastguard Worker 
40*38e8c45fSAndroid Build Coastguard Worker namespace {
41*38e8c45fSAndroid Build Coastguard Worker 
42*38e8c45fSAndroid Build Coastguard Worker static constexpr Error kTransactionError = Error::NO_RESOURCES;
43*38e8c45fSAndroid Build Coastguard Worker 
getValid10UsageBits()44*38e8c45fSAndroid Build Coastguard Worker uint64_t getValid10UsageBits() {
45*38e8c45fSAndroid Build Coastguard Worker     static const uint64_t valid10UsageBits = []() -> uint64_t {
46*38e8c45fSAndroid Build Coastguard Worker         using hardware::graphics::common::V1_0::BufferUsage;
47*38e8c45fSAndroid Build Coastguard Worker         uint64_t bits = 0;
48*38e8c45fSAndroid Build Coastguard Worker         for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
49*38e8c45fSAndroid Build Coastguard Worker             bits = bits | bit;
50*38e8c45fSAndroid Build Coastguard Worker         }
51*38e8c45fSAndroid Build Coastguard Worker         return bits;
52*38e8c45fSAndroid Build Coastguard Worker     }();
53*38e8c45fSAndroid Build Coastguard Worker     return valid10UsageBits;
54*38e8c45fSAndroid Build Coastguard Worker }
55*38e8c45fSAndroid Build Coastguard Worker 
getValid11UsageBits()56*38e8c45fSAndroid Build Coastguard Worker uint64_t getValid11UsageBits() {
57*38e8c45fSAndroid Build Coastguard Worker     static const uint64_t valid11UsageBits = []() -> uint64_t {
58*38e8c45fSAndroid Build Coastguard Worker         using hardware::graphics::common::V1_1::BufferUsage;
59*38e8c45fSAndroid Build Coastguard Worker         uint64_t bits = 0;
60*38e8c45fSAndroid Build Coastguard Worker         for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
61*38e8c45fSAndroid Build Coastguard Worker             bits = bits | bit;
62*38e8c45fSAndroid Build Coastguard Worker         }
63*38e8c45fSAndroid Build Coastguard Worker         return bits;
64*38e8c45fSAndroid Build Coastguard Worker     }();
65*38e8c45fSAndroid Build Coastguard Worker     return valid11UsageBits;
66*38e8c45fSAndroid Build Coastguard Worker }
67*38e8c45fSAndroid Build Coastguard Worker 
sGralloc2Rect(const Rect & rect)68*38e8c45fSAndroid Build Coastguard Worker static inline IMapper::Rect sGralloc2Rect(const Rect& rect) {
69*38e8c45fSAndroid Build Coastguard Worker     IMapper::Rect outRect{};
70*38e8c45fSAndroid Build Coastguard Worker     outRect.left = rect.left;
71*38e8c45fSAndroid Build Coastguard Worker     outRect.top = rect.top;
72*38e8c45fSAndroid Build Coastguard Worker     outRect.width = rect.width();
73*38e8c45fSAndroid Build Coastguard Worker     outRect.height = rect.height();
74*38e8c45fSAndroid Build Coastguard Worker     return outRect;
75*38e8c45fSAndroid Build Coastguard Worker }
76*38e8c45fSAndroid Build Coastguard Worker 
77*38e8c45fSAndroid Build Coastguard Worker }  // anonymous namespace
78*38e8c45fSAndroid Build Coastguard Worker 
preload()79*38e8c45fSAndroid Build Coastguard Worker void Gralloc2Mapper::preload() {
80*38e8c45fSAndroid Build Coastguard Worker     android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
81*38e8c45fSAndroid Build Coastguard Worker }
82*38e8c45fSAndroid Build Coastguard Worker 
Gralloc2Mapper()83*38e8c45fSAndroid Build Coastguard Worker Gralloc2Mapper::Gralloc2Mapper() {
84*38e8c45fSAndroid Build Coastguard Worker     mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
85*38e8c45fSAndroid Build Coastguard Worker     if (mMapper == nullptr) {
86*38e8c45fSAndroid Build Coastguard Worker         ALOGW("mapper 2.x is not supported");
87*38e8c45fSAndroid Build Coastguard Worker         return;
88*38e8c45fSAndroid Build Coastguard Worker     }
89*38e8c45fSAndroid Build Coastguard Worker     if (mMapper->isRemote()) {
90*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
91*38e8c45fSAndroid Build Coastguard Worker     }
92*38e8c45fSAndroid Build Coastguard Worker 
93*38e8c45fSAndroid Build Coastguard Worker     // IMapper 2.1 is optional
94*38e8c45fSAndroid Build Coastguard Worker     mMapperV2_1 = IMapper::castFrom(mMapper);
95*38e8c45fSAndroid Build Coastguard Worker }
96*38e8c45fSAndroid Build Coastguard Worker 
isLoaded() const97*38e8c45fSAndroid Build Coastguard Worker bool Gralloc2Mapper::isLoaded() const {
98*38e8c45fSAndroid Build Coastguard Worker     return mMapper != nullptr;
99*38e8c45fSAndroid Build Coastguard Worker }
100*38e8c45fSAndroid Build Coastguard Worker 
validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo * descriptorInfo) const101*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc2Mapper::validateBufferDescriptorInfo(
102*38e8c45fSAndroid Build Coastguard Worker         IMapper::BufferDescriptorInfo* descriptorInfo) const {
103*38e8c45fSAndroid Build Coastguard Worker     uint64_t validUsageBits = getValid10UsageBits();
104*38e8c45fSAndroid Build Coastguard Worker     if (mMapperV2_1 != nullptr) {
105*38e8c45fSAndroid Build Coastguard Worker         validUsageBits = validUsageBits | getValid11UsageBits();
106*38e8c45fSAndroid Build Coastguard Worker     }
107*38e8c45fSAndroid Build Coastguard Worker 
108*38e8c45fSAndroid Build Coastguard Worker     if (descriptorInfo->usage & ~validUsageBits) {
109*38e8c45fSAndroid Build Coastguard Worker         ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
110*38e8c45fSAndroid Build Coastguard Worker               descriptorInfo->usage & ~validUsageBits);
111*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
112*38e8c45fSAndroid Build Coastguard Worker     }
113*38e8c45fSAndroid Build Coastguard Worker 
114*38e8c45fSAndroid Build Coastguard Worker     // Gralloc2 implementations never understand non-BLOB with GPU_DATA_BUFFER
115*38e8c45fSAndroid Build Coastguard Worker     // and do not reliably reject it.
116*38e8c45fSAndroid Build Coastguard Worker     if (descriptorInfo->usage & BufferUsage::GPU_DATA_BUFFER &&
117*38e8c45fSAndroid Build Coastguard Worker         descriptorInfo->format != hardware::graphics::common::V1_1::PixelFormat::BLOB) {
118*38e8c45fSAndroid Build Coastguard Worker         ALOGE("gralloc2 does not support non-BLOB pixel formats with GPU_DATA_BUFFER usage");
119*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
120*38e8c45fSAndroid Build Coastguard Worker     }
121*38e8c45fSAndroid Build Coastguard Worker 
122*38e8c45fSAndroid Build Coastguard Worker     return NO_ERROR;
123*38e8c45fSAndroid Build Coastguard Worker }
124*38e8c45fSAndroid Build Coastguard Worker 
createDescriptor(void * bufferDescriptorInfo,void * outBufferDescriptor) const125*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc2Mapper::createDescriptor(void* bufferDescriptorInfo,
126*38e8c45fSAndroid Build Coastguard Worker                                           void* outBufferDescriptor) const {
127*38e8c45fSAndroid Build Coastguard Worker     IMapper::BufferDescriptorInfo* descriptorInfo =
128*38e8c45fSAndroid Build Coastguard Worker             static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
129*38e8c45fSAndroid Build Coastguard Worker     BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
130*38e8c45fSAndroid Build Coastguard Worker 
131*38e8c45fSAndroid Build Coastguard Worker     status_t status = validateBufferDescriptorInfo(descriptorInfo);
132*38e8c45fSAndroid Build Coastguard Worker     if (status != NO_ERROR) {
133*38e8c45fSAndroid Build Coastguard Worker         return status;
134*38e8c45fSAndroid Build Coastguard Worker     }
135*38e8c45fSAndroid Build Coastguard Worker 
136*38e8c45fSAndroid Build Coastguard Worker     Error error;
137*38e8c45fSAndroid Build Coastguard Worker     auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor)
138*38e8c45fSAndroid Build Coastguard Worker                    {
139*38e8c45fSAndroid Build Coastguard Worker                        error = tmpError;
140*38e8c45fSAndroid Build Coastguard Worker                        if (error != Error::NONE) {
141*38e8c45fSAndroid Build Coastguard Worker                            return;
142*38e8c45fSAndroid Build Coastguard Worker                        }
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker                        *outDescriptor = tmpDescriptor;
145*38e8c45fSAndroid Build Coastguard Worker                    };
146*38e8c45fSAndroid Build Coastguard Worker 
147*38e8c45fSAndroid Build Coastguard Worker     hardware::Return<void> ret;
148*38e8c45fSAndroid Build Coastguard Worker     if (mMapperV2_1 != nullptr) {
149*38e8c45fSAndroid Build Coastguard Worker         ret = mMapperV2_1->createDescriptor_2_1(*descriptorInfo, hidl_cb);
150*38e8c45fSAndroid Build Coastguard Worker     } else {
151*38e8c45fSAndroid Build Coastguard Worker         const hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo info = {
152*38e8c45fSAndroid Build Coastguard Worker                 descriptorInfo->width,
153*38e8c45fSAndroid Build Coastguard Worker                 descriptorInfo->height,
154*38e8c45fSAndroid Build Coastguard Worker                 descriptorInfo->layerCount,
155*38e8c45fSAndroid Build Coastguard Worker                 static_cast<hardware::graphics::common::V1_0::PixelFormat>(descriptorInfo->format),
156*38e8c45fSAndroid Build Coastguard Worker                 descriptorInfo->usage,
157*38e8c45fSAndroid Build Coastguard Worker         };
158*38e8c45fSAndroid Build Coastguard Worker         ret = mMapper->createDescriptor(info, hidl_cb);
159*38e8c45fSAndroid Build Coastguard Worker     }
160*38e8c45fSAndroid Build Coastguard Worker 
161*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
162*38e8c45fSAndroid Build Coastguard Worker }
163*38e8c45fSAndroid Build Coastguard Worker 
importBuffer(const native_handle_t * rawHandle,buffer_handle_t * outBufferHandle) const164*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc2Mapper::importBuffer(const native_handle_t* rawHandle,
165*38e8c45fSAndroid Build Coastguard Worker                                       buffer_handle_t* outBufferHandle) const {
166*38e8c45fSAndroid Build Coastguard Worker     Error error;
167*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->importBuffer(rawHandle,
168*38e8c45fSAndroid Build Coastguard Worker             [&](const auto& tmpError, const auto& tmpBuffer)
169*38e8c45fSAndroid Build Coastguard Worker             {
170*38e8c45fSAndroid Build Coastguard Worker                 error = tmpError;
171*38e8c45fSAndroid Build Coastguard Worker                 if (error != Error::NONE) {
172*38e8c45fSAndroid Build Coastguard Worker                     return;
173*38e8c45fSAndroid Build Coastguard Worker                 }
174*38e8c45fSAndroid Build Coastguard Worker 
175*38e8c45fSAndroid Build Coastguard Worker                 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
176*38e8c45fSAndroid Build Coastguard Worker             });
177*38e8c45fSAndroid Build Coastguard Worker 
178*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
179*38e8c45fSAndroid Build Coastguard Worker }
180*38e8c45fSAndroid Build Coastguard Worker 
freeBuffer(buffer_handle_t bufferHandle) const181*38e8c45fSAndroid Build Coastguard Worker void Gralloc2Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
182*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
183*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->freeBuffer(buffer);
184*38e8c45fSAndroid Build Coastguard Worker 
185*38e8c45fSAndroid Build Coastguard Worker     auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
186*38e8c45fSAndroid Build Coastguard Worker     ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
187*38e8c45fSAndroid Build Coastguard Worker             buffer, error);
188*38e8c45fSAndroid Build Coastguard Worker }
189*38e8c45fSAndroid Build Coastguard Worker 
validateBufferSize(buffer_handle_t bufferHandle,uint32_t width,uint32_t height,android::PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t stride) const190*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc2Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
191*38e8c45fSAndroid Build Coastguard Worker                                             uint32_t height, android::PixelFormat format,
192*38e8c45fSAndroid Build Coastguard Worker                                             uint32_t layerCount, uint64_t usage,
193*38e8c45fSAndroid Build Coastguard Worker                                             uint32_t stride) const {
194*38e8c45fSAndroid Build Coastguard Worker     if (mMapperV2_1 == nullptr) {
195*38e8c45fSAndroid Build Coastguard Worker         return NO_ERROR;
196*38e8c45fSAndroid Build Coastguard Worker     }
197*38e8c45fSAndroid Build Coastguard Worker 
198*38e8c45fSAndroid Build Coastguard Worker     IMapper::BufferDescriptorInfo descriptorInfo = {};
199*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.width = width;
200*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.height = height;
201*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.layerCount = layerCount;
202*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
203*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.usage = usage;
204*38e8c45fSAndroid Build Coastguard Worker 
205*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
206*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
207*38e8c45fSAndroid Build Coastguard Worker 
208*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
209*38e8c45fSAndroid Build Coastguard Worker }
210*38e8c45fSAndroid Build Coastguard Worker 
getTransportSize(buffer_handle_t bufferHandle,uint32_t * outNumFds,uint32_t * outNumInts) const211*38e8c45fSAndroid Build Coastguard Worker void Gralloc2Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
212*38e8c45fSAndroid Build Coastguard Worker                                       uint32_t* outNumInts) const {
213*38e8c45fSAndroid Build Coastguard Worker     *outNumFds = uint32_t(bufferHandle->numFds);
214*38e8c45fSAndroid Build Coastguard Worker     *outNumInts = uint32_t(bufferHandle->numInts);
215*38e8c45fSAndroid Build Coastguard Worker 
216*38e8c45fSAndroid Build Coastguard Worker     if (mMapperV2_1 == nullptr) {
217*38e8c45fSAndroid Build Coastguard Worker         return;
218*38e8c45fSAndroid Build Coastguard Worker     }
219*38e8c45fSAndroid Build Coastguard Worker 
220*38e8c45fSAndroid Build Coastguard Worker     Error error;
221*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
222*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapperV2_1->getTransportSize(buffer,
223*38e8c45fSAndroid Build Coastguard Worker             [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
224*38e8c45fSAndroid Build Coastguard Worker                 error = tmpError;
225*38e8c45fSAndroid Build Coastguard Worker                 if (error != Error::NONE) {
226*38e8c45fSAndroid Build Coastguard Worker                     return;
227*38e8c45fSAndroid Build Coastguard Worker                 }
228*38e8c45fSAndroid Build Coastguard Worker 
229*38e8c45fSAndroid Build Coastguard Worker                 *outNumFds = tmpNumFds;
230*38e8c45fSAndroid Build Coastguard Worker                 *outNumInts = tmpNumInts;
231*38e8c45fSAndroid Build Coastguard Worker             });
232*38e8c45fSAndroid Build Coastguard Worker 
233*38e8c45fSAndroid Build Coastguard Worker     error = (ret.isOk()) ? error : kTransactionError;
234*38e8c45fSAndroid Build Coastguard Worker 
235*38e8c45fSAndroid Build Coastguard Worker     ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
236*38e8c45fSAndroid Build Coastguard Worker }
237*38e8c45fSAndroid Build Coastguard Worker 
lock(buffer_handle_t bufferHandle,uint64_t usage,const Rect & bounds,int acquireFence,void ** outData,int32_t * outBytesPerPixel,int32_t * outBytesPerStride) const238*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
239*38e8c45fSAndroid Build Coastguard Worker                               int acquireFence, void** outData, int32_t* outBytesPerPixel,
240*38e8c45fSAndroid Build Coastguard Worker                               int32_t* outBytesPerStride) const {
241*38e8c45fSAndroid Build Coastguard Worker     if (outBytesPerPixel) {
242*38e8c45fSAndroid Build Coastguard Worker         *outBytesPerPixel = -1;
243*38e8c45fSAndroid Build Coastguard Worker     }
244*38e8c45fSAndroid Build Coastguard Worker     if (outBytesPerStride) {
245*38e8c45fSAndroid Build Coastguard Worker         *outBytesPerStride = -1;
246*38e8c45fSAndroid Build Coastguard Worker     }
247*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
248*38e8c45fSAndroid Build Coastguard Worker 
249*38e8c45fSAndroid Build Coastguard Worker     IMapper::Rect accessRegion = sGralloc2Rect(bounds);
250*38e8c45fSAndroid Build Coastguard Worker 
251*38e8c45fSAndroid Build Coastguard Worker     // put acquireFence in a hidl_handle
252*38e8c45fSAndroid Build Coastguard Worker     hardware::hidl_handle acquireFenceHandle;
253*38e8c45fSAndroid Build Coastguard Worker     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
254*38e8c45fSAndroid Build Coastguard Worker     if (acquireFence >= 0) {
255*38e8c45fSAndroid Build Coastguard Worker         auto h = native_handle_init(acquireFenceStorage, 1, 0);
256*38e8c45fSAndroid Build Coastguard Worker         h->data[0] = acquireFence;
257*38e8c45fSAndroid Build Coastguard Worker         acquireFenceHandle = h;
258*38e8c45fSAndroid Build Coastguard Worker     }
259*38e8c45fSAndroid Build Coastguard Worker 
260*38e8c45fSAndroid Build Coastguard Worker     Error error;
261*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
262*38e8c45fSAndroid Build Coastguard Worker             [&](const auto& tmpError, const auto& tmpData)
263*38e8c45fSAndroid Build Coastguard Worker             {
264*38e8c45fSAndroid Build Coastguard Worker                 error = tmpError;
265*38e8c45fSAndroid Build Coastguard Worker                 if (error != Error::NONE) {
266*38e8c45fSAndroid Build Coastguard Worker                     return;
267*38e8c45fSAndroid Build Coastguard Worker                 }
268*38e8c45fSAndroid Build Coastguard Worker 
269*38e8c45fSAndroid Build Coastguard Worker                 *outData = tmpData;
270*38e8c45fSAndroid Build Coastguard Worker             });
271*38e8c45fSAndroid Build Coastguard Worker 
272*38e8c45fSAndroid Build Coastguard Worker     // we own acquireFence even on errors
273*38e8c45fSAndroid Build Coastguard Worker     if (acquireFence >= 0) {
274*38e8c45fSAndroid Build Coastguard Worker         close(acquireFence);
275*38e8c45fSAndroid Build Coastguard Worker     }
276*38e8c45fSAndroid Build Coastguard Worker 
277*38e8c45fSAndroid Build Coastguard Worker     error = (ret.isOk()) ? error : kTransactionError;
278*38e8c45fSAndroid Build Coastguard Worker 
279*38e8c45fSAndroid Build Coastguard Worker     ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
280*38e8c45fSAndroid Build Coastguard Worker 
281*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>(error);
282*38e8c45fSAndroid Build Coastguard Worker }
283*38e8c45fSAndroid Build Coastguard Worker 
lock(buffer_handle_t bufferHandle,uint64_t usage,const Rect & bounds,int acquireFence,android_ycbcr * ycbcr) const284*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
285*38e8c45fSAndroid Build Coastguard Worker                               int acquireFence, android_ycbcr* ycbcr) const {
286*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
287*38e8c45fSAndroid Build Coastguard Worker 
288*38e8c45fSAndroid Build Coastguard Worker     IMapper::Rect accessRegion = sGralloc2Rect(bounds);
289*38e8c45fSAndroid Build Coastguard Worker 
290*38e8c45fSAndroid Build Coastguard Worker     // put acquireFence in a hidl_handle
291*38e8c45fSAndroid Build Coastguard Worker     hardware::hidl_handle acquireFenceHandle;
292*38e8c45fSAndroid Build Coastguard Worker     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
293*38e8c45fSAndroid Build Coastguard Worker     if (acquireFence >= 0) {
294*38e8c45fSAndroid Build Coastguard Worker         auto h = native_handle_init(acquireFenceStorage, 1, 0);
295*38e8c45fSAndroid Build Coastguard Worker         h->data[0] = acquireFence;
296*38e8c45fSAndroid Build Coastguard Worker         acquireFenceHandle = h;
297*38e8c45fSAndroid Build Coastguard Worker     }
298*38e8c45fSAndroid Build Coastguard Worker 
299*38e8c45fSAndroid Build Coastguard Worker     YCbCrLayout layout;
300*38e8c45fSAndroid Build Coastguard Worker     Error error;
301*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
302*38e8c45fSAndroid Build Coastguard Worker             acquireFenceHandle,
303*38e8c45fSAndroid Build Coastguard Worker             [&](const auto& tmpError, const auto& tmpLayout)
304*38e8c45fSAndroid Build Coastguard Worker             {
305*38e8c45fSAndroid Build Coastguard Worker                 error = tmpError;
306*38e8c45fSAndroid Build Coastguard Worker                 if (error != Error::NONE) {
307*38e8c45fSAndroid Build Coastguard Worker                     return;
308*38e8c45fSAndroid Build Coastguard Worker                 }
309*38e8c45fSAndroid Build Coastguard Worker 
310*38e8c45fSAndroid Build Coastguard Worker                 layout = tmpLayout;
311*38e8c45fSAndroid Build Coastguard Worker             });
312*38e8c45fSAndroid Build Coastguard Worker 
313*38e8c45fSAndroid Build Coastguard Worker     if (error == Error::NONE) {
314*38e8c45fSAndroid Build Coastguard Worker         ycbcr->y = layout.y;
315*38e8c45fSAndroid Build Coastguard Worker         ycbcr->cb = layout.cb;
316*38e8c45fSAndroid Build Coastguard Worker         ycbcr->cr = layout.cr;
317*38e8c45fSAndroid Build Coastguard Worker         ycbcr->ystride = static_cast<size_t>(layout.yStride);
318*38e8c45fSAndroid Build Coastguard Worker         ycbcr->cstride = static_cast<size_t>(layout.cStride);
319*38e8c45fSAndroid Build Coastguard Worker         ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
320*38e8c45fSAndroid Build Coastguard Worker     }
321*38e8c45fSAndroid Build Coastguard Worker 
322*38e8c45fSAndroid Build Coastguard Worker     // we own acquireFence even on errors
323*38e8c45fSAndroid Build Coastguard Worker     if (acquireFence >= 0) {
324*38e8c45fSAndroid Build Coastguard Worker         close(acquireFence);
325*38e8c45fSAndroid Build Coastguard Worker     }
326*38e8c45fSAndroid Build Coastguard Worker 
327*38e8c45fSAndroid Build Coastguard Worker     return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
328*38e8c45fSAndroid Build Coastguard Worker }
329*38e8c45fSAndroid Build Coastguard Worker 
unlock(buffer_handle_t bufferHandle) const330*38e8c45fSAndroid Build Coastguard Worker int Gralloc2Mapper::unlock(buffer_handle_t bufferHandle) const {
331*38e8c45fSAndroid Build Coastguard Worker     auto buffer = const_cast<native_handle_t*>(bufferHandle);
332*38e8c45fSAndroid Build Coastguard Worker 
333*38e8c45fSAndroid Build Coastguard Worker     int releaseFence = -1;
334*38e8c45fSAndroid Build Coastguard Worker     Error error;
335*38e8c45fSAndroid Build Coastguard Worker     auto ret = mMapper->unlock(buffer,
336*38e8c45fSAndroid Build Coastguard Worker             [&](const auto& tmpError, const auto& tmpReleaseFence)
337*38e8c45fSAndroid Build Coastguard Worker             {
338*38e8c45fSAndroid Build Coastguard Worker                 error = tmpError;
339*38e8c45fSAndroid Build Coastguard Worker                 if (error != Error::NONE) {
340*38e8c45fSAndroid Build Coastguard Worker                     return;
341*38e8c45fSAndroid Build Coastguard Worker                 }
342*38e8c45fSAndroid Build Coastguard Worker 
343*38e8c45fSAndroid Build Coastguard Worker                 auto fenceHandle = tmpReleaseFence.getNativeHandle();
344*38e8c45fSAndroid Build Coastguard Worker                 if (fenceHandle && fenceHandle->numFds == 1) {
345*38e8c45fSAndroid Build Coastguard Worker                     int fd = dup(fenceHandle->data[0]);
346*38e8c45fSAndroid Build Coastguard Worker                     if (fd >= 0) {
347*38e8c45fSAndroid Build Coastguard Worker                         releaseFence = fd;
348*38e8c45fSAndroid Build Coastguard Worker                     } else {
349*38e8c45fSAndroid Build Coastguard Worker                         ALOGD("failed to dup unlock release fence");
350*38e8c45fSAndroid Build Coastguard Worker                         sync_wait(fenceHandle->data[0], -1);
351*38e8c45fSAndroid Build Coastguard Worker                     }
352*38e8c45fSAndroid Build Coastguard Worker                 }
353*38e8c45fSAndroid Build Coastguard Worker             });
354*38e8c45fSAndroid Build Coastguard Worker 
355*38e8c45fSAndroid Build Coastguard Worker     error = (ret.isOk()) ? error : kTransactionError;
356*38e8c45fSAndroid Build Coastguard Worker     if (error != Error::NONE) {
357*38e8c45fSAndroid Build Coastguard Worker         ALOGE("unlock(%p) failed with %d", buffer, error);
358*38e8c45fSAndroid Build Coastguard Worker     }
359*38e8c45fSAndroid Build Coastguard Worker 
360*38e8c45fSAndroid Build Coastguard Worker     return releaseFence;
361*38e8c45fSAndroid Build Coastguard Worker }
362*38e8c45fSAndroid Build Coastguard Worker 
Gralloc2Allocator(const Gralloc2Mapper & mapper)363*38e8c45fSAndroid Build Coastguard Worker Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) {
364*38e8c45fSAndroid Build Coastguard Worker     mAllocator = IAllocator::getService();
365*38e8c45fSAndroid Build Coastguard Worker     if (mAllocator == nullptr) {
366*38e8c45fSAndroid Build Coastguard Worker         ALOGW("allocator 2.x is not supported");
367*38e8c45fSAndroid Build Coastguard Worker         return;
368*38e8c45fSAndroid Build Coastguard Worker     }
369*38e8c45fSAndroid Build Coastguard Worker }
370*38e8c45fSAndroid Build Coastguard Worker 
isLoaded() const371*38e8c45fSAndroid Build Coastguard Worker bool Gralloc2Allocator::isLoaded() const {
372*38e8c45fSAndroid Build Coastguard Worker     return mAllocator != nullptr;
373*38e8c45fSAndroid Build Coastguard Worker }
374*38e8c45fSAndroid Build Coastguard Worker 
dumpDebugInfo(bool) const375*38e8c45fSAndroid Build Coastguard Worker std::string Gralloc2Allocator::dumpDebugInfo(bool /*less*/) const {
376*38e8c45fSAndroid Build Coastguard Worker     std::string debugInfo;
377*38e8c45fSAndroid Build Coastguard Worker 
378*38e8c45fSAndroid Build Coastguard Worker     mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
379*38e8c45fSAndroid Build Coastguard Worker         debugInfo = tmpDebugInfo.c_str();
380*38e8c45fSAndroid Build Coastguard Worker     });
381*38e8c45fSAndroid Build Coastguard Worker 
382*38e8c45fSAndroid Build Coastguard Worker     return debugInfo;
383*38e8c45fSAndroid Build Coastguard Worker }
384*38e8c45fSAndroid Build Coastguard Worker 
allocate(std::string,uint32_t width,uint32_t height,PixelFormat format,uint32_t layerCount,uint64_t usage,uint32_t * outStride,buffer_handle_t * outBufferHandles,bool importBuffers) const385*38e8c45fSAndroid Build Coastguard Worker status_t Gralloc2Allocator::allocate(std::string /*requestorName*/, uint32_t width, uint32_t height,
386*38e8c45fSAndroid Build Coastguard Worker                                      PixelFormat format, uint32_t layerCount, uint64_t usage,
387*38e8c45fSAndroid Build Coastguard Worker                                      uint32_t* outStride, buffer_handle_t* outBufferHandles,
388*38e8c45fSAndroid Build Coastguard Worker                                      bool importBuffers) const {
389*38e8c45fSAndroid Build Coastguard Worker     IMapper::BufferDescriptorInfo descriptorInfo = {};
390*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.width = width;
391*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.height = height;
392*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.layerCount = layerCount;
393*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
394*38e8c45fSAndroid Build Coastguard Worker     descriptorInfo.usage = usage;
395*38e8c45fSAndroid Build Coastguard Worker 
396*38e8c45fSAndroid Build Coastguard Worker     BufferDescriptor descriptor;
397*38e8c45fSAndroid Build Coastguard Worker     status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
398*38e8c45fSAndroid Build Coastguard Worker                                               static_cast<void*>(&descriptor));
399*38e8c45fSAndroid Build Coastguard Worker     if (error != NO_ERROR) {
400*38e8c45fSAndroid Build Coastguard Worker         return error;
401*38e8c45fSAndroid Build Coastguard Worker     }
402*38e8c45fSAndroid Build Coastguard Worker 
403*38e8c45fSAndroid Build Coastguard Worker     constexpr auto bufferCount = 1;
404*38e8c45fSAndroid Build Coastguard Worker 
405*38e8c45fSAndroid Build Coastguard Worker     auto ret = mAllocator->allocate(descriptor, bufferCount,
406*38e8c45fSAndroid Build Coastguard Worker                                     [&](const auto& tmpError, const auto& tmpStride,
407*38e8c45fSAndroid Build Coastguard Worker                                         const auto& tmpBuffers) {
408*38e8c45fSAndroid Build Coastguard Worker                                         error = static_cast<status_t>(tmpError);
409*38e8c45fSAndroid Build Coastguard Worker                                         if (tmpError != Error::NONE) {
410*38e8c45fSAndroid Build Coastguard Worker                                             return;
411*38e8c45fSAndroid Build Coastguard Worker                                         }
412*38e8c45fSAndroid Build Coastguard Worker 
413*38e8c45fSAndroid Build Coastguard Worker                                         if (importBuffers) {
414*38e8c45fSAndroid Build Coastguard Worker                                             for (uint32_t i = 0; i < bufferCount; i++) {
415*38e8c45fSAndroid Build Coastguard Worker                                                 error = mMapper.importBuffer(tmpBuffers[i],
416*38e8c45fSAndroid Build Coastguard Worker                                                                              &outBufferHandles[i]);
417*38e8c45fSAndroid Build Coastguard Worker                                                 if (error != NO_ERROR) {
418*38e8c45fSAndroid Build Coastguard Worker                                                     for (uint32_t j = 0; j < i; j++) {
419*38e8c45fSAndroid Build Coastguard Worker                                                         mMapper.freeBuffer(outBufferHandles[j]);
420*38e8c45fSAndroid Build Coastguard Worker                                                         outBufferHandles[j] = nullptr;
421*38e8c45fSAndroid Build Coastguard Worker                                                     }
422*38e8c45fSAndroid Build Coastguard Worker                                                     return;
423*38e8c45fSAndroid Build Coastguard Worker                                                 }
424*38e8c45fSAndroid Build Coastguard Worker                                             }
425*38e8c45fSAndroid Build Coastguard Worker                                         } else {
426*38e8c45fSAndroid Build Coastguard Worker                                             for (uint32_t i = 0; i < bufferCount; i++) {
427*38e8c45fSAndroid Build Coastguard Worker                                                 outBufferHandles[i] = native_handle_clone(
428*38e8c45fSAndroid Build Coastguard Worker                                                         tmpBuffers[i].getNativeHandle());
429*38e8c45fSAndroid Build Coastguard Worker                                                 if (!outBufferHandles[i]) {
430*38e8c45fSAndroid Build Coastguard Worker                                                     for (uint32_t j = 0; j < i; j++) {
431*38e8c45fSAndroid Build Coastguard Worker                                                         auto buffer = const_cast<native_handle_t*>(
432*38e8c45fSAndroid Build Coastguard Worker                                                                 outBufferHandles[j]);
433*38e8c45fSAndroid Build Coastguard Worker                                                         native_handle_close(buffer);
434*38e8c45fSAndroid Build Coastguard Worker                                                         native_handle_delete(buffer);
435*38e8c45fSAndroid Build Coastguard Worker                                                         outBufferHandles[j] = nullptr;
436*38e8c45fSAndroid Build Coastguard Worker                                                     }
437*38e8c45fSAndroid Build Coastguard Worker                                                 }
438*38e8c45fSAndroid Build Coastguard Worker                                             }
439*38e8c45fSAndroid Build Coastguard Worker                                         }
440*38e8c45fSAndroid Build Coastguard Worker                                         *outStride = tmpStride;
441*38e8c45fSAndroid Build Coastguard Worker                                     });
442*38e8c45fSAndroid Build Coastguard Worker 
443*38e8c45fSAndroid Build Coastguard Worker     // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
444*38e8c45fSAndroid Build Coastguard Worker     hardware::IPCThreadState::self()->flushCommands();
445*38e8c45fSAndroid Build Coastguard Worker 
446*38e8c45fSAndroid Build Coastguard Worker     return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
447*38e8c45fSAndroid Build Coastguard Worker }
448*38e8c45fSAndroid Build Coastguard Worker 
449*38e8c45fSAndroid Build Coastguard Worker } // namespace android
450