blob: e891ec581ef407840365d0dbe3936a5ff4d066a7 [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
252Return<void> B2HGraphicBufferProducer::connect(
253 sp<HProducerListener> const& hListener,
254 HConnectionType hConnectionType,
255 bool producerControlledByApp,
256 connect_cb _hidl_cb) {
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800257 sp<BProducerListener> bListener = new H2BProducerListener(hListener);
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700258 int bConnectionType{};
259 if (!bListener || !h2b(hConnectionType, &bConnectionType)) {
260 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800261 return {};
262 }
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700263 BQueueBufferOutput bOutput{};
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800264 HStatus hStatus{};
Pawin Vongmasa23399ac2019-04-25 03:44:52 -0700265 QueueBufferOutput hOutput{};
266 bool converted =
267 b2h(mBase->connect(bListener,
268 bConnectionType,
269 producerControlledByApp,
270 &bOutput),
271 &hStatus) &&
272 b2h(bOutput, &hOutput);
273 _hidl_cb(converted ? hStatus : HStatus::UNKNOWN_ERROR, hOutput);
Pawin Vongmasae672cd02019-02-14 16:01:29 -0800274 return {};
275}
276
277Return<HStatus> B2HGraphicBufferProducer::disconnect(
278 HConnectionType hConnectionType) {
279 int bConnectionType;
280 if (!h2b(hConnectionType, &bConnectionType)) {
281 return {HStatus::UNKNOWN_ERROR};
282 }
283 HStatus hStatus{};
284 bool converted = b2h(mBase->disconnect(bConnectionType), &hStatus);
285 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
286}
287
288Return<HStatus> B2HGraphicBufferProducer::allocateBuffers(
289 uint32_t width, uint32_t height,
290 uint32_t format, uint64_t usage) {
291 mBase->allocateBuffers(
292 width, height, static_cast<PixelFormat>(format), usage);
293 return {HStatus::OK};
294}
295
296Return<HStatus> B2HGraphicBufferProducer::allowAllocation(bool allow) {
297 HStatus hStatus{};
298 bool converted = b2h(mBase->allowAllocation(allow), &hStatus);
299 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
300}
301
302Return<HStatus> B2HGraphicBufferProducer::setGenerationNumber(
303 uint32_t generationNumber) {
304 HStatus hStatus{};
305 bool converted = b2h(
306 mBase->setGenerationNumber(generationNumber),
307 &hStatus);
308 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
309}
310
311Return<HStatus> B2HGraphicBufferProducer::setDequeueTimeout(
312 int64_t timeoutNs) {
313 HStatus hStatus{};
314 bool converted = b2h(
315 mBase->setDequeueTimeout(static_cast<nsecs_t>(timeoutNs)),
316 &hStatus);
317 return {converted ? hStatus : HStatus::UNKNOWN_ERROR};
318}
319
320Return<uint64_t> B2HGraphicBufferProducer::getUniqueId() {
321 uint64_t outId{};
322 HStatus hStatus{};
323 bool converted = b2h(mBase->getUniqueId(&outId), &hStatus);
324 return {converted ? outId : 0};
325}
326
327Return<void> B2HGraphicBufferProducer::getConsumerName(
328 getConsumerName_cb _hidl_cb) {
329 _hidl_cb(hidl_string{mBase->getConsumerName().c_str()});
330 return {};
331}
332
333} // namespace utils
334} // namespace V2_0
335} // namespace bufferqueue
336} // namespace graphics
337} // namespace hardware
338} // namespace android
339