1 /* 2 * Copyright 2013 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 #include "VirtualDisplaySurface.h" 19 20 #include <inttypes.h> 21 22 #include "HWComposer.h" 23 #include "SurfaceFlinger.h" 24 25 #include <gui/BufferItem.h> 26 #include <gui/BufferQueue.h> 27 #include <gui/IProducerListener.h> 28 #include <system/window.h> 29 30 // --------------------------------------------------------------------------- 31 namespace android { 32 // --------------------------------------------------------------------------- 33 34 #define VDS_LOGE(msg, ...) ALOGE("[%s] " msg, \ 35 mDisplayName.c_str(), ##__VA_ARGS__) 36 #define VDS_LOGW_IF(cond, msg, ...) ALOGW_IF(cond, "[%s] " msg, \ 37 mDisplayName.c_str(), ##__VA_ARGS__) 38 #define VDS_LOGV(msg, ...) ALOGV("[%s] " msg, \ 39 mDisplayName.c_str(), ##__VA_ARGS__) 40 41 static const char* dbgCompositionTypeStr(compositionengine::DisplaySurface::CompositionType type) { 42 switch (type) { 43 case compositionengine::DisplaySurface::COMPOSITION_UNKNOWN: 44 return "UNKNOWN"; 45 case compositionengine::DisplaySurface::COMPOSITION_GLES: 46 return "GLES"; 47 case compositionengine::DisplaySurface::COMPOSITION_HWC: 48 return "HWC"; 49 case compositionengine::DisplaySurface::COMPOSITION_MIXED: 50 return "MIXED"; 51 default: return "<INVALID>"; 52 } 53 } 54 55 VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, 56 const std::optional<DisplayId>& displayId, 57 const sp<IGraphicBufferProducer>& sink, 58 const sp<IGraphicBufferProducer>& bqProducer, 59 const sp<IGraphicBufferConsumer>& bqConsumer, 60 const std::string& name) 61 : ConsumerBase(bqConsumer), 62 mHwc(hwc), 63 mDisplayId(displayId), 64 mDisplayName(name), 65 mSource{}, 66 mDefaultOutputFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED), 67 mOutputFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED), 68 mOutputUsage(GRALLOC_USAGE_HW_COMPOSER), 69 mProducerSlotSource(0), 70 mProducerBuffers(), 71 mQueueBufferOutput(), 72 mSinkBufferWidth(0), 73 mSinkBufferHeight(0), 74 mCompositionType(COMPOSITION_UNKNOWN), 75 mFbFence(Fence::NO_FENCE), 76 mOutputFence(Fence::NO_FENCE), 77 mFbProducerSlot(BufferQueue::INVALID_BUFFER_SLOT), 78 mOutputProducerSlot(BufferQueue::INVALID_BUFFER_SLOT), 79 mDbgState(DBG_STATE_IDLE), 80 mDbgLastCompositionType(COMPOSITION_UNKNOWN), 81 mMustRecompose(false), 82 mForceHwcCopy(SurfaceFlinger::useHwcForRgbToYuv) { 83 mSource[SOURCE_SINK] = sink; 84 mSource[SOURCE_SCRATCH] = bqProducer; 85 86 resetPerFrameState(); 87 88 int sinkWidth, sinkHeight; 89 sink->query(NATIVE_WINDOW_WIDTH, &sinkWidth); 90 sink->query(NATIVE_WINDOW_HEIGHT, &sinkHeight); 91 mSinkBufferWidth = sinkWidth; 92 mSinkBufferHeight = sinkHeight; 93 94 // Pick the buffer format to request from the sink when not rendering to it 95 // with GLES. If the consumer needs CPU access, use the default format 96 // set by the consumer. Otherwise allow gralloc to decide the format based 97 // on usage bits. 98 int sinkUsage; 99 sink->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &sinkUsage); 100 if (sinkUsage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { 101 int sinkFormat; 102 sink->query(NATIVE_WINDOW_FORMAT, &sinkFormat); 103 mDefaultOutputFormat = sinkFormat; 104 } else { 105 mDefaultOutputFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; 106 } 107 mOutputFormat = mDefaultOutputFormat; 108 109 ConsumerBase::mName = String8::format("VDS: %s", mDisplayName.c_str()); 110 mConsumer->setConsumerName(ConsumerBase::mName); 111 mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER); 112 mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight); 113 sink->setAsyncMode(true); 114 IGraphicBufferProducer::QueueBufferOutput output; 115 mSource[SOURCE_SCRATCH]->connect(nullptr, NATIVE_WINDOW_API_EGL, false, &output); 116 } 117 118 VirtualDisplaySurface::~VirtualDisplaySurface() { 119 mSource[SOURCE_SCRATCH]->disconnect(NATIVE_WINDOW_API_EGL); 120 } 121 122 status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) { 123 if (!mDisplayId) { 124 return NO_ERROR; 125 } 126 127 mMustRecompose = mustRecompose; 128 129 VDS_LOGW_IF(mDbgState != DBG_STATE_IDLE, 130 "Unexpected beginFrame() in %s state", dbgStateStr()); 131 mDbgState = DBG_STATE_BEGUN; 132 133 return refreshOutputBuffer(); 134 } 135 136 status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { 137 if (!mDisplayId) { 138 return NO_ERROR; 139 } 140 141 VDS_LOGW_IF(mDbgState != DBG_STATE_BEGUN, 142 "Unexpected prepareFrame() in %s state", dbgStateStr()); 143 mDbgState = DBG_STATE_PREPARED; 144 145 mCompositionType = compositionType; 146 if (mForceHwcCopy && mCompositionType == COMPOSITION_GLES) { 147 // Some hardware can do RGB->YUV conversion more efficiently in hardware 148 // controlled by HWC than in hardware controlled by the video encoder. 149 // Forcing GLES-composed frames to go through an extra copy by the HWC 150 // allows the format conversion to happen there, rather than passing RGB 151 // directly to the consumer. 152 // 153 // On the other hand, when the consumer prefers RGB or can consume RGB 154 // inexpensively, this forces an unnecessary copy. 155 mCompositionType = COMPOSITION_MIXED; 156 } 157 158 if (mCompositionType != mDbgLastCompositionType) { 159 VDS_LOGV("prepareFrame: composition type changed to %s", 160 dbgCompositionTypeStr(mCompositionType)); 161 mDbgLastCompositionType = mCompositionType; 162 } 163 164 if (mCompositionType != COMPOSITION_GLES && 165 (mOutputFormat != mDefaultOutputFormat || 166 mOutputUsage != GRALLOC_USAGE_HW_COMPOSER)) { 167 // We must have just switched from GLES-only to MIXED or HWC 168 // composition. Stop using the format and usage requested by the GLES 169 // driver; they may be suboptimal when HWC is writing to the output 170 // buffer. For example, if the output is going to a video encoder, and 171 // HWC can write directly to YUV, some hardware can skip a 172 // memory-to-memory RGB-to-YUV conversion step. 173 // 174 // If we just switched *to* GLES-only mode, we'll change the 175 // format/usage and get a new buffer when the GLES driver calls 176 // dequeueBuffer(). 177 mOutputFormat = mDefaultOutputFormat; 178 mOutputUsage = GRALLOC_USAGE_HW_COMPOSER; 179 refreshOutputBuffer(); 180 } 181 182 return NO_ERROR; 183 } 184 185 status_t VirtualDisplaySurface::advanceFrame() { 186 if (!mDisplayId) { 187 return NO_ERROR; 188 } 189 190 if (mCompositionType == COMPOSITION_HWC) { 191 VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED, 192 "Unexpected advanceFrame() in %s state on HWC frame", 193 dbgStateStr()); 194 } else { 195 VDS_LOGW_IF(mDbgState != DBG_STATE_GLES_DONE, 196 "Unexpected advanceFrame() in %s state on GLES/MIXED frame", 197 dbgStateStr()); 198 } 199 mDbgState = DBG_STATE_HWC; 200 201 if (mOutputProducerSlot < 0 || 202 (mCompositionType != COMPOSITION_HWC && mFbProducerSlot < 0)) { 203 // Last chance bailout if something bad happened earlier. For example, 204 // in a GLES configuration, if the sink disappears then dequeueBuffer 205 // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger 206 // will soldier on. So we end up here without a buffer. There should 207 // be lots of scary messages in the log just before this. 208 VDS_LOGE("advanceFrame: no buffer, bailing out"); 209 return NO_MEMORY; 210 } 211 212 sp<GraphicBuffer> fbBuffer = mFbProducerSlot >= 0 ? 213 mProducerBuffers[mFbProducerSlot] : sp<GraphicBuffer>(nullptr); 214 sp<GraphicBuffer> outBuffer = mProducerBuffers[mOutputProducerSlot]; 215 VDS_LOGV("advanceFrame: fb=%d(%p) out=%d(%p)", 216 mFbProducerSlot, fbBuffer.get(), 217 mOutputProducerSlot, outBuffer.get()); 218 219 // At this point we know the output buffer acquire fence, 220 // so update HWC state with it. 221 mHwc.setOutputBuffer(*mDisplayId, mOutputFence, outBuffer); 222 223 status_t result = NO_ERROR; 224 if (fbBuffer != nullptr) { 225 uint32_t hwcSlot = 0; 226 sp<GraphicBuffer> hwcBuffer; 227 mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer, &hwcSlot, &hwcBuffer); 228 229 // TODO: Correctly propagate the dataspace from GL composition 230 result = mHwc.setClientTarget(*mDisplayId, hwcSlot, mFbFence, hwcBuffer, 231 ui::Dataspace::UNKNOWN); 232 } 233 234 return result; 235 } 236 237 void VirtualDisplaySurface::onFrameCommitted() { 238 if (!mDisplayId) { 239 return; 240 } 241 242 VDS_LOGW_IF(mDbgState != DBG_STATE_HWC, 243 "Unexpected onFrameCommitted() in %s state", dbgStateStr()); 244 mDbgState = DBG_STATE_IDLE; 245 246 sp<Fence> retireFence = mHwc.getPresentFence(*mDisplayId); 247 if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) { 248 // release the scratch buffer back to the pool 249 Mutex::Autolock lock(mMutex); 250 int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot); 251 VDS_LOGV("onFrameCommitted: release scratch sslot=%d", sslot); 252 addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], 253 retireFence); 254 releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot]); 255 } 256 257 if (mOutputProducerSlot >= 0) { 258 int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot); 259 QueueBufferOutput qbo; 260 VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot); 261 if (mMustRecompose) { 262 status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot, 263 QueueBufferInput( 264 systemTime(), false /* isAutoTimestamp */, 265 HAL_DATASPACE_UNKNOWN, 266 Rect(mSinkBufferWidth, mSinkBufferHeight), 267 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */, 268 retireFence), 269 &qbo); 270 if (result == NO_ERROR) { 271 updateQueueBufferOutput(std::move(qbo)); 272 } 273 } else { 274 // If the surface hadn't actually been updated, then we only went 275 // through the motions of updating the display to keep our state 276 // machine happy. We cancel the buffer to avoid triggering another 277 // re-composition and causing an infinite loop. 278 mSource[SOURCE_SINK]->cancelBuffer(sslot, retireFence); 279 } 280 } 281 282 resetPerFrameState(); 283 } 284 285 void VirtualDisplaySurface::dumpAsString(String8& /* result */) const { 286 } 287 288 void VirtualDisplaySurface::resizeBuffers(const uint32_t w, const uint32_t h) { 289 mQueueBufferOutput.width = w; 290 mQueueBufferOutput.height = h; 291 mSinkBufferWidth = w; 292 mSinkBufferHeight = h; 293 } 294 295 const sp<Fence>& VirtualDisplaySurface::getClientTargetAcquireFence() const { 296 return mFbFence; 297 } 298 299 status_t VirtualDisplaySurface::requestBuffer(int pslot, 300 sp<GraphicBuffer>* outBuf) { 301 if (!mDisplayId) { 302 return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf); 303 } 304 305 VDS_LOGW_IF(mDbgState != DBG_STATE_GLES, 306 "Unexpected requestBuffer pslot=%d in %s state", 307 pslot, dbgStateStr()); 308 309 *outBuf = mProducerBuffers[pslot]; 310 return NO_ERROR; 311 } 312 313 status_t VirtualDisplaySurface::setMaxDequeuedBufferCount( 314 int maxDequeuedBuffers) { 315 return mSource[SOURCE_SINK]->setMaxDequeuedBufferCount(maxDequeuedBuffers); 316 } 317 318 status_t VirtualDisplaySurface::setAsyncMode(bool async) { 319 return mSource[SOURCE_SINK]->setAsyncMode(async); 320 } 321 322 status_t VirtualDisplaySurface::dequeueBuffer(Source source, 323 PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) { 324 LOG_FATAL_IF(!mDisplayId); 325 326 status_t result = 327 mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight, 328 format, usage, nullptr, nullptr); 329 if (result < 0) 330 return result; 331 int pslot = mapSource2ProducerSlot(source, *sslot); 332 VDS_LOGV("dequeueBuffer(%s): sslot=%d pslot=%d result=%d", 333 dbgSourceStr(source), *sslot, pslot, result); 334 uint64_t sourceBit = static_cast<uint64_t>(source) << pslot; 335 336 if ((mProducerSlotSource & (1ULL << pslot)) != sourceBit) { 337 // This slot was previously dequeued from the other source; must 338 // re-request the buffer. 339 result |= BUFFER_NEEDS_REALLOCATION; 340 mProducerSlotSource &= ~(1ULL << pslot); 341 mProducerSlotSource |= sourceBit; 342 } 343 344 if (result & RELEASE_ALL_BUFFERS) { 345 for (uint32_t i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 346 if ((mProducerSlotSource & (1ULL << i)) == sourceBit) 347 mProducerBuffers[i].clear(); 348 } 349 } 350 if (result & BUFFER_NEEDS_REALLOCATION) { 351 result = mSource[source]->requestBuffer(*sslot, &mProducerBuffers[pslot]); 352 if (result < 0) { 353 mProducerBuffers[pslot].clear(); 354 mSource[source]->cancelBuffer(*sslot, *fence); 355 return result; 356 } 357 VDS_LOGV("dequeueBuffer(%s): buffers[%d]=%p fmt=%d usage=%#" PRIx64, 358 dbgSourceStr(source), pslot, mProducerBuffers[pslot].get(), 359 mProducerBuffers[pslot]->getPixelFormat(), 360 mProducerBuffers[pslot]->getUsage()); 361 } 362 363 return result; 364 } 365 366 status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, uint32_t w, uint32_t h, 367 PixelFormat format, uint64_t usage, 368 uint64_t* outBufferAge, 369 FrameEventHistoryDelta* outTimestamps) { 370 if (!mDisplayId) { 371 return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, w, h, format, usage, outBufferAge, 372 outTimestamps); 373 } 374 375 VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED, 376 "Unexpected dequeueBuffer() in %s state", dbgStateStr()); 377 mDbgState = DBG_STATE_GLES; 378 379 VDS_LOGV("dequeueBuffer %dx%d fmt=%d usage=%#" PRIx64, w, h, format, usage); 380 381 status_t result = NO_ERROR; 382 Source source = fbSourceForCompositionType(mCompositionType); 383 384 if (source == SOURCE_SINK) { 385 386 if (mOutputProducerSlot < 0) { 387 // Last chance bailout if something bad happened earlier. For example, 388 // in a GLES configuration, if the sink disappears then dequeueBuffer 389 // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger 390 // will soldier on. So we end up here without a buffer. There should 391 // be lots of scary messages in the log just before this. 392 VDS_LOGE("dequeueBuffer: no buffer, bailing out"); 393 return NO_MEMORY; 394 } 395 396 // We already dequeued the output buffer. If the GLES driver wants 397 // something incompatible, we have to cancel and get a new one. This 398 // will mean that HWC will see a different output buffer between 399 // prepare and set, but since we're in GLES-only mode already it 400 // shouldn't matter. 401 402 usage |= GRALLOC_USAGE_HW_COMPOSER; 403 const sp<GraphicBuffer>& buf = mProducerBuffers[mOutputProducerSlot]; 404 if ((usage & ~buf->getUsage()) != 0 || 405 (format != 0 && format != buf->getPixelFormat()) || 406 (w != 0 && w != mSinkBufferWidth) || 407 (h != 0 && h != mSinkBufferHeight)) { 408 VDS_LOGV("dequeueBuffer: dequeueing new output buffer: " 409 "want %dx%d fmt=%d use=%#" PRIx64 ", " 410 "have %dx%d fmt=%d use=%#" PRIx64, 411 w, h, format, usage, 412 mSinkBufferWidth, mSinkBufferHeight, 413 buf->getPixelFormat(), buf->getUsage()); 414 mOutputFormat = format; 415 mOutputUsage = usage; 416 result = refreshOutputBuffer(); 417 if (result < 0) 418 return result; 419 } 420 } 421 422 if (source == SOURCE_SINK) { 423 *pslot = mOutputProducerSlot; 424 *fence = mOutputFence; 425 } else { 426 int sslot; 427 result = dequeueBuffer(source, format, usage, &sslot, fence); 428 if (result >= 0) { 429 *pslot = mapSource2ProducerSlot(source, sslot); 430 } 431 } 432 if (outBufferAge) { 433 *outBufferAge = 0; 434 } 435 return result; 436 } 437 438 status_t VirtualDisplaySurface::detachBuffer(int /* slot */) { 439 VDS_LOGE("detachBuffer is not available for VirtualDisplaySurface"); 440 return INVALID_OPERATION; 441 } 442 443 status_t VirtualDisplaySurface::detachNextBuffer( 444 sp<GraphicBuffer>* /* outBuffer */, sp<Fence>* /* outFence */) { 445 VDS_LOGE("detachNextBuffer is not available for VirtualDisplaySurface"); 446 return INVALID_OPERATION; 447 } 448 449 status_t VirtualDisplaySurface::attachBuffer(int* /* outSlot */, 450 const sp<GraphicBuffer>& /* buffer */) { 451 VDS_LOGE("attachBuffer is not available for VirtualDisplaySurface"); 452 return INVALID_OPERATION; 453 } 454 455 status_t VirtualDisplaySurface::queueBuffer(int pslot, 456 const QueueBufferInput& input, QueueBufferOutput* output) { 457 if (!mDisplayId) { 458 return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output); 459 } 460 461 VDS_LOGW_IF(mDbgState != DBG_STATE_GLES, 462 "Unexpected queueBuffer(pslot=%d) in %s state", pslot, 463 dbgStateStr()); 464 mDbgState = DBG_STATE_GLES_DONE; 465 466 VDS_LOGV("queueBuffer pslot=%d", pslot); 467 468 status_t result; 469 if (mCompositionType == COMPOSITION_MIXED) { 470 // Queue the buffer back into the scratch pool 471 QueueBufferOutput scratchQBO; 472 int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, pslot); 473 result = mSource[SOURCE_SCRATCH]->queueBuffer(sslot, input, &scratchQBO); 474 if (result != NO_ERROR) 475 return result; 476 477 // Now acquire the buffer from the scratch pool -- should be the same 478 // slot and fence as we just queued. 479 Mutex::Autolock lock(mMutex); 480 BufferItem item; 481 result = acquireBufferLocked(&item, 0); 482 if (result != NO_ERROR) 483 return result; 484 VDS_LOGW_IF(item.mSlot != sslot, 485 "queueBuffer: acquired sslot %d from SCRATCH after queueing sslot %d", 486 item.mSlot, sslot); 487 mFbProducerSlot = mapSource2ProducerSlot(SOURCE_SCRATCH, item.mSlot); 488 mFbFence = mSlots[item.mSlot].mFence; 489 490 } else { 491 LOG_FATAL_IF(mCompositionType != COMPOSITION_GLES, 492 "Unexpected queueBuffer in state %s for compositionType %s", 493 dbgStateStr(), dbgCompositionTypeStr(mCompositionType)); 494 495 // Extract the GLES release fence for HWC to acquire 496 int64_t timestamp; 497 bool isAutoTimestamp; 498 android_dataspace dataSpace; 499 Rect crop; 500 int scalingMode; 501 uint32_t transform; 502 input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, 503 &scalingMode, &transform, &mFbFence); 504 505 mFbProducerSlot = pslot; 506 mOutputFence = mFbFence; 507 } 508 509 // This moves the frame timestamps and keeps a copy of all other fields. 510 *output = std::move(mQueueBufferOutput); 511 return NO_ERROR; 512 } 513 514 status_t VirtualDisplaySurface::cancelBuffer(int pslot, 515 const sp<Fence>& fence) { 516 if (!mDisplayId) { 517 return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence); 518 } 519 520 VDS_LOGW_IF(mDbgState != DBG_STATE_GLES, 521 "Unexpected cancelBuffer(pslot=%d) in %s state", pslot, 522 dbgStateStr()); 523 VDS_LOGV("cancelBuffer pslot=%d", pslot); 524 Source source = fbSourceForCompositionType(mCompositionType); 525 return mSource[source]->cancelBuffer( 526 mapProducer2SourceSlot(source, pslot), fence); 527 } 528 529 int VirtualDisplaySurface::query(int what, int* value) { 530 switch (what) { 531 case NATIVE_WINDOW_WIDTH: 532 *value = mSinkBufferWidth; 533 break; 534 case NATIVE_WINDOW_HEIGHT: 535 *value = mSinkBufferHeight; 536 break; 537 default: 538 return mSource[SOURCE_SINK]->query(what, value); 539 } 540 return NO_ERROR; 541 } 542 543 status_t VirtualDisplaySurface::connect(const sp<IProducerListener>& listener, 544 int api, bool producerControlledByApp, 545 QueueBufferOutput* output) { 546 QueueBufferOutput qbo; 547 status_t result = mSource[SOURCE_SINK]->connect(listener, api, 548 producerControlledByApp, &qbo); 549 if (result == NO_ERROR) { 550 updateQueueBufferOutput(std::move(qbo)); 551 // This moves the frame timestamps and keeps a copy of all other fields. 552 *output = std::move(mQueueBufferOutput); 553 } 554 return result; 555 } 556 557 status_t VirtualDisplaySurface::disconnect(int api, DisconnectMode mode) { 558 return mSource[SOURCE_SINK]->disconnect(api, mode); 559 } 560 561 status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stream*/) { 562 return INVALID_OPERATION; 563 } 564 565 void VirtualDisplaySurface::allocateBuffers(uint32_t /* width */, 566 uint32_t /* height */, PixelFormat /* format */, uint64_t /* usage */) { 567 // TODO: Should we actually allocate buffers for a virtual display? 568 } 569 570 status_t VirtualDisplaySurface::allowAllocation(bool /* allow */) { 571 return INVALID_OPERATION; 572 } 573 574 status_t VirtualDisplaySurface::setGenerationNumber(uint32_t /* generation */) { 575 ALOGE("setGenerationNumber not supported on VirtualDisplaySurface"); 576 return INVALID_OPERATION; 577 } 578 579 String8 VirtualDisplaySurface::getConsumerName() const { 580 return String8("VirtualDisplaySurface"); 581 } 582 583 status_t VirtualDisplaySurface::setSharedBufferMode(bool /*sharedBufferMode*/) { 584 ALOGE("setSharedBufferMode not supported on VirtualDisplaySurface"); 585 return INVALID_OPERATION; 586 } 587 588 status_t VirtualDisplaySurface::setAutoRefresh(bool /*autoRefresh*/) { 589 ALOGE("setAutoRefresh not supported on VirtualDisplaySurface"); 590 return INVALID_OPERATION; 591 } 592 593 status_t VirtualDisplaySurface::setDequeueTimeout(nsecs_t /* timeout */) { 594 ALOGE("setDequeueTimeout not supported on VirtualDisplaySurface"); 595 return INVALID_OPERATION; 596 } 597 598 status_t VirtualDisplaySurface::getLastQueuedBuffer( 599 sp<GraphicBuffer>* /*outBuffer*/, sp<Fence>* /*outFence*/, 600 float[16] /* outTransformMatrix*/) { 601 ALOGE("getLastQueuedBuffer not supported on VirtualDisplaySurface"); 602 return INVALID_OPERATION; 603 } 604 605 status_t VirtualDisplaySurface::getUniqueId(uint64_t* /*outId*/) const { 606 ALOGE("getUniqueId not supported on VirtualDisplaySurface"); 607 return INVALID_OPERATION; 608 } 609 610 status_t VirtualDisplaySurface::getConsumerUsage(uint64_t* outUsage) const { 611 return mSource[SOURCE_SINK]->getConsumerUsage(outUsage); 612 } 613 614 void VirtualDisplaySurface::updateQueueBufferOutput( 615 QueueBufferOutput&& qbo) { 616 mQueueBufferOutput = std::move(qbo); 617 mQueueBufferOutput.transformHint = 0; 618 } 619 620 void VirtualDisplaySurface::resetPerFrameState() { 621 mCompositionType = COMPOSITION_UNKNOWN; 622 mFbFence = Fence::NO_FENCE; 623 mOutputFence = Fence::NO_FENCE; 624 mOutputProducerSlot = -1; 625 mFbProducerSlot = -1; 626 } 627 628 status_t VirtualDisplaySurface::refreshOutputBuffer() { 629 LOG_FATAL_IF(!mDisplayId); 630 631 if (mOutputProducerSlot >= 0) { 632 mSource[SOURCE_SINK]->cancelBuffer( 633 mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot), 634 mOutputFence); 635 } 636 637 int sslot; 638 status_t result = dequeueBuffer(SOURCE_SINK, mOutputFormat, mOutputUsage, 639 &sslot, &mOutputFence); 640 if (result < 0) 641 return result; 642 mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot); 643 644 // On GLES-only frames, we don't have the right output buffer acquire fence 645 // until after GLES calls queueBuffer(). So here we just set the buffer 646 // (for use in HWC prepare) but not the fence; we'll call this again with 647 // the proper fence once we have it. 648 result = mHwc.setOutputBuffer(*mDisplayId, Fence::NO_FENCE, 649 mProducerBuffers[mOutputProducerSlot]); 650 651 return result; 652 } 653 654 // This slot mapping function is its own inverse, so two copies are unnecessary. 655 // Both are kept to make the intent clear where the function is called, and for 656 // the (unlikely) chance that we switch to a different mapping function. 657 int VirtualDisplaySurface::mapSource2ProducerSlot(Source source, int sslot) { 658 if (source == SOURCE_SCRATCH) { 659 return BufferQueue::NUM_BUFFER_SLOTS - sslot - 1; 660 } else { 661 return sslot; 662 } 663 } 664 int VirtualDisplaySurface::mapProducer2SourceSlot(Source source, int pslot) { 665 return mapSource2ProducerSlot(source, pslot); 666 } 667 668 VirtualDisplaySurface::Source 669 VirtualDisplaySurface::fbSourceForCompositionType(CompositionType type) { 670 return type == COMPOSITION_MIXED ? SOURCE_SCRATCH : SOURCE_SINK; 671 } 672 673 const char* VirtualDisplaySurface::dbgStateStr() const { 674 switch (mDbgState) { 675 case DBG_STATE_IDLE: return "IDLE"; 676 case DBG_STATE_PREPARED: return "PREPARED"; 677 case DBG_STATE_GLES: return "GLES"; 678 case DBG_STATE_GLES_DONE: return "GLES_DONE"; 679 case DBG_STATE_HWC: return "HWC"; 680 default: return "INVALID"; 681 } 682 } 683 684 const char* VirtualDisplaySurface::dbgSourceStr(Source s) { 685 switch (s) { 686 case SOURCE_SINK: return "SINK"; 687 case SOURCE_SCRATCH: return "SCRATCH"; 688 default: return "INVALID"; 689 } 690 } 691 692 // --------------------------------------------------------------------------- 693 } // namespace android 694 // --------------------------------------------------------------------------- 695