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
connect(sp<HProducerListener> const & hListener,HConnectionType hConnectionType,bool producerControlledByApp,connect_cb _hidl_cb)252 Return<void> B2HGraphicBufferProducer::connect(
253 sp<HProducerListener> const& hListener,
254 HConnectionType hConnectionType,
255 bool producerControlledByApp,
256 connect_cb _hidl_cb) {
257 sp<BProducerListener> bListener = new H2BProducerListener(hListener);
258 int bConnectionType{};
259 if (!bListener || !h2b(hConnectionType, &bConnectionType)) {
260 _hidl_cb(HStatus::UNKNOWN_ERROR, QueueBufferOutput{});
261 return {};
262 }
263 BQueueBufferOutput bOutput{};
264 HStatus hStatus{};
265 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);
274 return {};
275 }
276
disconnect(HConnectionType hConnectionType)277 Return<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
allocateBuffers(uint32_t width,uint32_t height,uint32_t format,uint64_t usage)288 Return<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
allowAllocation(bool allow)296 Return<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
setGenerationNumber(uint32_t generationNumber)302 Return<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
setDequeueTimeout(int64_t timeoutNs)311 Return<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
getUniqueId()320 Return<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
getConsumerName(getConsumerName_cb _hidl_cb)327 Return<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
340