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