1 /*
2 * Copyright 2019 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_NDEBUG 0
18 #define LOG_TAG "B2HGraphicBufferProducer@2.0"
19
20 #include <android-base/logging.h>
21
22 #include <android/hardware/graphics/bufferqueue/2.0/types.h>
23 #include <android/hardware/graphics/common/1.2/types.h>
24 #include <gui/bufferqueue/2.0/H2BProducerListener.h>
25 #include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
26 #include <gui/bufferqueue/2.0/types.h>
27 #include <ui/GraphicBuffer.h>
28 #include <ui/Rect.h>
29 #include <ui/Region.h>
30 #include <vndk/hardware_buffer.h>
31
32 namespace android {
33 namespace hardware {
34 namespace graphics {
35 namespace bufferqueue {
36 namespace V2_0 {
37 namespace utils {
38
39 namespace /* unnamed */ {
40
41 using BQueueBufferInput = ::android::
42 IGraphicBufferProducer::QueueBufferInput;
43 using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
44 IGraphicBufferProducer::QueueBufferInput;
45 using BQueueBufferOutput = ::android::
46 IGraphicBufferProducer::QueueBufferOutput;
47 using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
48 IGraphicBufferProducer::QueueBufferOutput;
49
50 using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
51 using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
52
b2h(BQueueBufferOutput const & from,HQueueBufferOutput * to)53 bool b2h(BQueueBufferOutput const& from, HQueueBufferOutput* to) {
54 to->width = from.width;
55 to->height = from.height;
56 to->transformHint = static_cast<int32_t>(from.transformHint);
57 to->numPendingBuffers = from.numPendingBuffers;
58 to->nextFrameNumber = from.nextFrameNumber;
59 to->bufferReplaced = from.bufferReplaced;
60 return true;
61 }
62
63 } // unnamed namespace
64
65 // B2HGraphicBufferProducer
66 // ========================
67
B2HGraphicBufferProducer(sp<BGraphicBufferProducer> const & base)68 B2HGraphicBufferProducer::B2HGraphicBufferProducer(
69 sp<BGraphicBufferProducer> const& base)
70 : mBase{base} {
71 }
72
setMaxDequeuedBufferCount(int32_t maxDequeuedBuffers)73 Return<HStatus> B2HGraphicBufferProducer::setMaxDequeuedBufferCount(
74 int32_t maxDequeuedBuffers) {
75 HStatus hStatus{};
76 bool converted = b2h(
77 mBase->setMaxDequeuedBufferCount(
78 static_cast<int>(maxDequeuedBuffers)),
79 &hStatus);
80 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
81 }
82
requestBuffer(int32_t slot,requestBuffer_cb _hidl_cb)83 Return<void> B2HGraphicBufferProducer::requestBuffer(
84 int32_t slot,
85 requestBuffer_cb _hidl_cb) {
86 sp<GraphicBuffer> bBuffer;
87 HStatus hStatus{};
88 HardwareBuffer hBuffer{};
89 uint32_t hGenerationNumber{};
90 bool converted =
91 b2h(mBase->requestBuffer(
92 static_cast<int>(slot), &bBuffer),
93 &hStatus) &&
94 b2h(bBuffer, &hBuffer, &hGenerationNumber);
95 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
96 hBuffer, hGenerationNumber);
97 return {};
98 }
99
setAsyncMode(bool async)100 Return<HStatus> B2HGraphicBufferProducer::setAsyncMode(bool async) {
101 HStatus hStatus{};
102 bool converted = b2h(mBase->setAsyncMode(async), &hStatus);
103 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
104 }
105
dequeueBuffer(DequeueBufferInput const & input,dequeueBuffer_cb _hidl_cb)106 Return<void> B2HGraphicBufferProducer::dequeueBuffer(
107 DequeueBufferInput const& input,
108 dequeueBuffer_cb _hidl_cb) {
109 int bSlot{};
110 sp<BFence> bFence;
111 HStatus hStatus{};
112 DequeueBufferOutput hOutput{};
113 HFenceWrapper hFenceWrapper;
114 bool converted =
115 b2h(mBase->dequeueBuffer(
116 &bSlot,
117 &bFence,
118 input.width,
119 input.height,
120 static_cast<PixelFormat>(input.format),
121 input.usage,
122 &hOutput.bufferAge,
123 nullptr /* outTimestamps */),
124 &hStatus,
125 &hOutput.bufferNeedsReallocation,
126 &hOutput.releaseAllBuffers) &&
127 b2h(bFence, &hFenceWrapper);
128 hOutput.fence = hFenceWrapper.getHandle();
129 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
130 static_cast<int32_t>(bSlot),
131 hOutput);
132 return {};
133 }
134
detachBuffer(int32_t slot)135 Return<HStatus> B2HGraphicBufferProducer::detachBuffer(int32_t slot) {
136 HStatus hStatus{};
137 bool converted = b2h(
138 mBase->detachBuffer(static_cast<int>(slot)), &hStatus);
139 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
140 }
141
detachNextBuffer(detachNextBuffer_cb _hidl_cb)142 Return<void> B2HGraphicBufferProducer::detachNextBuffer(
143 detachNextBuffer_cb _hidl_cb) {
144 sp<GraphicBuffer> bBuffer;
145 sp<BFence> bFence;
146 HStatus hStatus{};
147 HardwareBuffer hBuffer{};
148 HFenceWrapper hFenceWrapper;
149 bool converted =
150 b2h(mBase->detachNextBuffer(&bBuffer, &bFence), &hStatus) &&
151 b2h(bBuffer, &hBuffer) &&
152 b2h(bFence, &hFenceWrapper);
153 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
154 hBuffer,
155 hFenceWrapper.getHandle());
156 return {};
157 }
158
attachBuffer(HardwareBuffer const & hBuffer,uint32_t generationNumber,attachBuffer_cb _hidl_cb)159 Return<void> B2HGraphicBufferProducer::attachBuffer(
160 HardwareBuffer const& hBuffer,
161 uint32_t generationNumber,
162 attachBuffer_cb _hidl_cb) {
163 sp<GraphicBuffer> bBuffer;
164 if (!h2b(hBuffer, &bBuffer) || !bBuffer) {
165 _hidl_cb(HStatus::UNKNOWN_ERROR,
166 static_cast<int32_t>(SlotIndex::INVALID),
167 false);
168 return {};
169 }
170 bBuffer->setGenerationNumber(generationNumber);
171
172 int bSlot{};
173 HStatus hStatus{};
174 bool releaseAllBuffers{};
175 bool converted = b2h(
176 mBase->attachBuffer(&bSlot, bBuffer), &hStatus,
177 nullptr /* bufferNeedsReallocation */,
178 &releaseAllBuffers);
179 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR,
180 static_cast<int32_t>(bSlot),
181 releaseAllBuffers);
182 return {};
183 }
184
queueBuffer(int32_t slot,QueueBufferInput const & hInput,queueBuffer_cb _hidl_cb)185 Return<void> B2HGraphicBufferProducer::queueBuffer(
186 int32_t slot,
187 QueueBufferInput const& hInput,
188 queueBuffer_cb _hidl_cb) {
189 BQueueBufferInput bInput{
190 hInput.timestamp,
191 hInput.isAutoTimestamp,
192 static_cast<android_dataspace>(hInput.dataSpace),
193 {}, /* crop */
194 0 /* scalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE */,
195 static_cast<uint32_t>(hInput.transform),
196 {}, /* fence */
197 static_cast<uint32_t>(hInput.stickyTransform),
198 false /* getFrameTimestamps */};
199
200 // Convert crop.
201 if (!h2b(hInput.crop, &bInput.crop)) {
202 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
203 return {};
204 }
205
206 // Convert surfaceDamage.
207 if (!h2b(hInput.surfaceDamage, &bInput.surfaceDamage)) {
208 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
209 return {};
210 }
211
212 // Convert fence.
213 if (!h2b(hInput.fence, &bInput.fence)) {
214 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
215 return {};
216 }
217
218 BQueueBufferOutput bOutput{};
219 HStatus hStatus{};
220 QueueBufferOutput hOutput{};
221 bool converted =
222 b2h(
223 mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput),
224 &hStatus) &&
225 b2h(bOutput, &hOutput);
226
227 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
228 return {};
229 }
230
cancelBuffer(int32_t slot,hidl_handle const & fence)231 Return<HStatus> B2HGraphicBufferProducer::cancelBuffer(
232 int32_t slot,
233 hidl_handle const& fence) {
234 sp<BFence> bFence;
235 if (!h2b(fence.getNativeHandle(), &bFence)) {
236 return {HStatus::UNKNOWN_ERROR};
237 }
238 HStatus hStatus{};
239 bool converted = b2h(
240 mBase->cancelBuffer(static_cast<int>(slot), bFence),
241 &hStatus);
242 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
243 }
244
query(int32_t what,query_cb _hidl_cb)245 Return<void> B2HGraphicBufferProducer::query(int32_t what, query_cb _hidl_cb) {
246 int value{};
247 int result = mBase->query(static_cast<int>(what), &value);
248 _hidl_cb(static_cast<int32_t>(result), static_cast<int32_t>(value));
249 return {};
250 }
251
252 struct Obituary : public hardware::hidl_death_recipient {
253 wp<B2HGraphicBufferProducer> producer;
254 sp<HProducerListener> listener;
255 HConnectionType apiType;
Obituaryandroid::hardware::graphics::bufferqueue::V2_0::utils::Obituary256 Obituary(const wp<B2HGraphicBufferProducer>& p,
257 const sp<HProducerListener>& l,
258 HConnectionType t)
259 : producer(p), listener(l), apiType(t) {}
260
serviceDiedandroid::hardware::graphics::bufferqueue::V2_0::utils::Obituary261 void serviceDied(uint64_t /* cookie */,
262 const wp<::android::hidl::base::V1_0::IBase>& /* who */) override {
263 sp<B2HGraphicBufferProducer> dr = producer.promote();
264 if (dr != nullptr) {
265 (void)dr->disconnect(apiType);
266 }
267 }
268 };
269
connect(sp<HProducerListener> const & hListener,HConnectionType hConnectionType,bool producerControlledByApp,connect_cb _hidl_cb)270 Return<void> B2HGraphicBufferProducer::connect(
271 sp<HProducerListener> const& hListener,
272 HConnectionType hConnectionType,
273 bool producerControlledByApp,
274 connect_cb _hidl_cb) {
275 sp<BProducerListener> bListener = new H2BProducerListener(hListener);
276 int bConnectionType{};
277 if (!bListener || !h2b(hConnectionType, &bConnectionType)) {
278 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
279 return {};
280 }
281 BQueueBufferOutput bOutput{};
282 HStatus hStatus{};
283 QueueBufferOutput hOutput{};
284 bool converted =
285 b2h(mBase->connect(bListener,
286 bConnectionType,
287 producerControlledByApp,
288 &bOutput),
289 &hStatus) &&
290 b2h(bOutput, &hOutput);
291 #ifdef NO_BINDER
292 if (converted && hListener != nullptr) {
293 mObituary = new Obituary(this, hListener, hConnectionType);
294 hListener->linkToDeath(mObituary, 0);
295 }
296 #endif // NO_BINDER
297 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
298 return {};
299 }
300
disconnect(HConnectionType hConnectionType)301 Return<HStatus> B2HGraphicBufferProducer::disconnect(
302 HConnectionType hConnectionType) {
303 int bConnectionType;
304 if (!h2b(hConnectionType, &bConnectionType)) {
305 return {HStatus::UNKNOWN_ERROR};
306 }
307 HStatus hStatus{};
308 bool converted = b2h(mBase->disconnect(bConnectionType), &hStatus);
309 #ifdef NO_BINDER
310 if (mObituary != nullptr) {
311 mObituary->listener->unlinkToDeath(mObituary);
312 mObituary.clear();
313 }
314 #endif // NO_BINDER
315 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
316 }
317
allocateBuffers(uint32_t width,uint32_t height,uint32_t format,uint64_t usage)318 Return<HStatus> B2HGraphicBufferProducer::allocateBuffers(
319 uint32_t width, uint32_t height,
320 uint32_t format, uint64_t usage) {
321 mBase->allocateBuffers(
322 width, height, static_cast<PixelFormat>(format), usage);
323 return {HStatus::OK};
324 }
325
allowAllocation(bool allow)326 Return<HStatus> B2HGraphicBufferProducer::allowAllocation(bool allow) {
327 HStatus hStatus{};
328 bool converted = b2h(mBase->allowAllocation(allow), &hStatus);
329 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
330 }
331
setGenerationNumber(uint32_t generationNumber)332 Return<HStatus> B2HGraphicBufferProducer::setGenerationNumber(
333 uint32_t generationNumber) {
334 HStatus hStatus{};
335 bool converted = b2h(
336 mBase->setGenerationNumber(generationNumber),
337 &hStatus);
338 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
339 }
340
setDequeueTimeout(int64_t timeoutNs)341 Return<HStatus> B2HGraphicBufferProducer::setDequeueTimeout(
342 int64_t timeoutNs) {
343 HStatus hStatus{};
344 bool converted = b2h(
345 mBase->setDequeueTimeout(static_cast<nsecs_t>(timeoutNs)),
346 &hStatus);
347 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
348 }
349
getUniqueId()350 Return<uint64_t> B2HGraphicBufferProducer::getUniqueId() {
351 uint64_t outId{};
352 HStatus hStatus{};
353 bool converted = b2h(mBase->getUniqueId(&outId), &hStatus);
354 return {converted ? outId : 0};
355 }
356
getConsumerName(getConsumerName_cb _hidl_cb)357 Return<void> B2HGraphicBufferProducer::getConsumerName(
358 getConsumerName_cb _hidl_cb) {
359 _hidl_cb(hidl_string{mBase->getConsumerName().c_str()});
360 return {};
361 }
362
363 } // namespace utils
364 } // namespace V2_0
365 } // namespace bufferqueue
366 } // namespace graphics
367 } // namespace hardware
368 } // namespace android
369
370