blob: 0f3ae2e28ce96c78aa3d37298f55d3beefe926ac [file] [log] [blame]
Pawin Vongmasae672cd02019-02-14 16:01:29 -08001/*
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
Pawin Vongmasa23399ac2019-04-25 03:44:52 -070018#define LOG_TAG "B2HGraphicBufferProducer@2.0"
Pawin Vongmasae672cd02019-02-14 16:01:29 -080019
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
32namespace android {
Pawin Vongmasae672cd02019-02-14 16:01:29 -080033namespace hardware {
34namespace graphics {
35namespace bufferqueue {
36namespace V2_0 {
37namespace utils {
38
Pawin Vongmasa23399ac2019-04-25 03:44:52 -070039namespace /* unnamed */ {
40
41using BQueueBufferInput = ::android::
42 IGraphicBufferProducer::QueueBufferInput;
43using HQueueBufferInput = ::android::hardware::graphics::bufferqueue::V2_0::
44 IGraphicBufferProducer::QueueBufferInput;
45using BQueueBufferOutput = ::android::
46 IGraphicBufferProducer::QueueBufferOutput;
47using HQueueBufferOutput = ::android::hardware::graphics::bufferqueue::V2_0::
48 IGraphicBufferProducer::QueueBufferOutput;
49
50using ::android::hardware::graphics::bufferqueue::V2_0::utils::b2h;
51using ::android::hardware::graphics::bufferqueue::V2_0::utils::h2b;
52
53bool 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
Pawin Vongmasae672cd02019-02-14 16:01:29 -080065// B2HGraphicBufferProducer
66// ========================
67
68B2HGraphicBufferProducer::B2HGraphicBufferProducer(
69 sp<BGraphicBufferProducer> const& base)
70 : mBase{base} {
71}
72
73Return<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
83Return<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
100Return<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
106Return<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
135Return<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
142Return<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
159Return<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
185Return<void> B2HGraphicBufferProducer::queueBuffer(
186 int32_t slot,
187 QueueBufferInput const& hInput,
188 queueBuffer_cb _hidl_cb) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700189 BQueueBufferInput bInput{
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800190 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)) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700202 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800203 return {};
204 }
205
206 // Convert surfaceDamage.
207 if (!h2b(hInput.surfaceDamage, &bInput.surfaceDamage)) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700208 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800209 return {};
210 }
211
212 // Convert fence.
213 if (!h2b(hInput.fence, &bInput.fence)) {
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700214 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800215 return {};
216 }
217
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700218 BQueueBufferOutput bOutput{};
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800219 HStatus hStatus{};
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700220 QueueBufferOutput hOutput{};
221 bool converted =
222 b2h(
223 mBase->queueBuffer(static_cast<int>(slot), bInput, &bOutput),
224 &hStatus) &&
225 b2h(bOutput, &hOutput);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800226
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700227 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800228 return {};
229}
230
231Return<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
245Return<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
Chong Zhang62493092020-01-15 16:04:47 -0800252struct Obituary : public hardware::hidl_death_recipient {
253 wp<B2HGraphicBufferProducer> producer;
254 sp<HProducerListener> listener;
255 HConnectionType apiType;
256 Obituary(const wp<B2HGraphicBufferProducer>& p,
257 const sp<HProducerListener>& l,
258 HConnectionType t)
259 : producer(p), listener(l), apiType(t) {}
260
261 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
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800270Return<void> B2HGraphicBufferProducer::connect(
271 sp<HProducerListener> const& hListener,
272 HConnectionType hConnectionType,
273 bool producerControlledByApp,
274 connect_cb _hidl_cb) {
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800275 sp<BProducerListener> bListener = new H2BProducerListener(hListener);
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700276 int bConnectionType{};
277 if (!bListener || !h2b(hConnectionType, &bConnectionType)) {
278 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800279 return {};
280 }
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700281 BQueueBufferOutput bOutput{};
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800282 HStatus hStatus{};
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700283 QueueBufferOutput hOutput{};
284 bool converted =
285 b2h(mBase->connect(bListener,
286 bConnectionType,
287 producerControlledByApp,
288 &bOutput),
289 &hStatus) &&
290 b2h(bOutput, &hOutput);
Chong Zhang62493092020-01-15 16:04:47 -0800291 if (converted) {
292 mObituary = new Obituary(this, hListener, hConnectionType);
293 hListener->linkToDeath(mObituary, 0);
294 }
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700295 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800296 return {};
297}
298
299Return<HStatus> B2HGraphicBufferProducer::disconnect(
300 HConnectionType hConnectionType) {
301 int bConnectionType;
302 if (!h2b(hConnectionType, &bConnectionType)) {
303 return {HStatus::UNKNOWN_ERROR};
304 }
305 HStatus hStatus{};
306 bool converted = b2h(mBase->disconnect(bConnectionType), &hStatus);
Chong Zhang62493092020-01-15 16:04:47 -0800307 if (mObituary != nullptr) {
308 mObituary->listener->unlinkToDeath(mObituary);
309 mObituary.clear();
310 }
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800311 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
312}
313
314Return<HStatus> B2HGraphicBufferProducer::allocateBuffers(
315 uint32_t width, uint32_t height,
316 uint32_t format, uint64_t usage) {
317 mBase->allocateBuffers(
318 width, height, static_cast<PixelFormat>(format), usage);
319 return {HStatus::OK};
320}
321
322Return<HStatus> B2HGraphicBufferProducer::allowAllocation(bool allow) {
323 HStatus hStatus{};
324 bool converted = b2h(mBase->allowAllocation(allow), &hStatus);
325 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
326}
327
328Return<HStatus> B2HGraphicBufferProducer::setGenerationNumber(
329 uint32_t generationNumber) {
330 HStatus hStatus{};
331 bool converted = b2h(
332 mBase->setGenerationNumber(generationNumber),
333 &hStatus);
334 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
335}
336
337Return<HStatus> B2HGraphicBufferProducer::setDequeueTimeout(
338 int64_t timeoutNs) {
339 HStatus hStatus{};
340 bool converted = b2h(
341 mBase->setDequeueTimeout(static_cast<nsecs_t>(timeoutNs)),
342 &hStatus);
343 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
344}
345
346Return<uint64_t> B2HGraphicBufferProducer::getUniqueId() {
347 uint64_t outId{};
348 HStatus hStatus{};
349 bool converted = b2h(mBase->getUniqueId(&outId), &hStatus);
350 return {converted ? outId : 0};
351}
352
353Return<void> B2HGraphicBufferProducer::getConsumerName(
354 getConsumerName_cb _hidl_cb) {
355 _hidl_cb(hidl_string{mBase->getConsumerName().c_str()});
356 return {};
357}
358
359} // namespace utils
360} // namespace V2_0
361} // namespace bufferqueue
362} // namespace graphics
363} // namespace hardware
364} // namespace android
365