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