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 (at) 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 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 68 B2HGraphicBufferProducer::B2HGraphicBufferProducer( 69 sp<BGraphicBufferProducer> const& base) 70 : mBase{base} { 71 } 72 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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