diff options
-rw-r--r-- | system/hwc3/GuestFrameComposer.cpp | 75 | ||||
-rw-r--r-- | system/hwc3/GuestFrameComposer.h | 8 |
2 files changed, 34 insertions, 49 deletions
diff --git a/system/hwc3/GuestFrameComposer.cpp b/system/hwc3/GuestFrameComposer.cpp index f4c92678..24002b89 100644 --- a/system/hwc3/GuestFrameComposer.cpp +++ b/system/hwc3/GuestFrameComposer.cpp @@ -480,44 +480,25 @@ HWC3::Error GuestFrameComposer::onDisplayCreate(Display* display) { DisplayInfo& displayInfo = mDisplayInfos[displayId]; - uint32_t bufferStride; - buffer_handle_t bufferHandle; - - auto status = ::android::GraphicBufferAllocator::get().allocate( - static_cast<uint32_t>(displayWidth), // - static_cast<uint32_t>(displayHeight), // - ::android::PIXEL_FORMAT_RGBA_8888, // - /*layerCount=*/1, // - ::android::GraphicBuffer::USAGE_HW_COMPOSER | - ::android::GraphicBuffer::USAGE_SW_READ_OFTEN | - ::android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, // - &bufferHandle, // - &bufferStride, // - "RanchuHwc"); - if (status != ::android::OK) { - ALOGE("%s: failed to allocate composition buffer for display:%" PRIu32, __FUNCTION__, - displayId); - return HWC3::Error::NoResources; - } - - displayInfo.compositionResultBuffer = bufferHandle; - - auto [drmBufferCreateError, drmBuffer] = mDrmClient.create(bufferHandle); - if (drmBufferCreateError != HWC3::Error::None) { - ALOGE("%s: failed to create drm buffer for display:%" PRIu32, __FUNCTION__, displayId); - return drmBufferCreateError; - } - displayInfo.compositionResultDrmBuffer = std::move(drmBuffer); + displayInfo.swapchain = DrmSwapchain::create(static_cast<uint32_t>(displayWidth), + static_cast<uint32_t>(displayHeight), + ::android::GraphicBuffer::USAGE_HW_COMPOSER | + ::android::GraphicBuffer::USAGE_SW_READ_OFTEN | + ::android::GraphicBuffer::USAGE_SW_WRITE_OFTEN, + &mDrmClient); if (displayId == 0) { + auto compositionResult = displayInfo.swapchain->getNextImage(); auto [flushError, flushSyncFd] = - mDrmClient.flushToDisplay(displayId, displayInfo.compositionResultDrmBuffer, -1); + mDrmClient.flushToDisplay(displayId, compositionResult->getDrmBuffer(), -1); if (flushError != HWC3::Error::None) { ALOGW( "%s: Initial display flush failed. HWComposer assuming that we are " "running in QEMU without a display and disabling presenting.", __FUNCTION__); mPresentDisabled = true; + } else { + compositionResult->markAsInUse(std::move(flushSyncFd)); } } @@ -534,14 +515,10 @@ HWC3::Error GuestFrameComposer::onDisplayDestroy(Display* display) { auto it = mDisplayInfos.find(displayId); if (it == mDisplayInfos.end()) { - ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, displayId); + ALOGE("%s: display:%" PRIu64 " missing display buffers?", __FUNCTION__, + displayId); return HWC3::Error::BadDisplay; } - - DisplayInfo& displayInfo = mDisplayInfos[displayId]; - - ::android::GraphicBufferAllocator::get().free(displayInfo.compositionResultBuffer); - mDisplayInfos.erase(it); return HWC3::Error::None; @@ -686,19 +663,23 @@ HWC3::Error GuestFrameComposer::presentDisplay( DisplayInfo& displayInfo = it->second; - if (displayInfo.compositionResultBuffer == nullptr) { - ALOGE("%s: display:%" PRIu32 " missing composition result buffer", __FUNCTION__, displayId); + auto compositionResult = displayInfo.swapchain->getNextImage(); + compositionResult->wait(); + + if (compositionResult->getBuffer() == nullptr) { + ALOGE("%s: display:%" PRIu32 " missing composition result buffer", + __FUNCTION__, displayId); return HWC3::Error::NoResources; } - if (displayInfo.compositionResultDrmBuffer == nullptr) { - ALOGE("%s: display:%" PRIu32 " missing composition result drm buffer", __FUNCTION__, - displayId); + if (compositionResult->getDrmBuffer() == nullptr) { + ALOGE("%s: display:%" PRIu32 " missing composition result drm buffer", + __FUNCTION__, displayId); return HWC3::Error::NoResources; } std::optional<GrallocBuffer> compositionResultBufferOpt = - mGralloc.Import(displayInfo.compositionResultBuffer); + mGralloc.Import(compositionResult->getBuffer()); if (!compositionResultBufferOpt) { ALOGE("%s: display:%" PRIu32 " failed to import buffer", __FUNCTION__, displayId); return HWC3::Error::NoResources; @@ -830,15 +811,19 @@ HWC3::Error GuestFrameComposer::presentDisplay( } } - DEBUG_LOG("%s display:%" PRIu32 " flushing drm buffer", __FUNCTION__, displayId); + DEBUG_LOG("%s display:%" PRIu32 " flushing drm buffer", __FUNCTION__, + displayId); - auto [error, fence] = - mDrmClient.flushToDisplay(displayId, displayInfo.compositionResultDrmBuffer, -1); + auto [error, fence] = mDrmClient.flushToDisplay(displayId, compositionResult->getDrmBuffer(), -1); if (error != HWC3::Error::None) { - ALOGE("%s: display:%" PRIu32 " failed to flush drm buffer" PRIu64, __FUNCTION__, displayId); + ALOGE("%s: display:%" PRIu32 " failed to flush drm buffer" PRIu64, + __FUNCTION__, displayId); } *outDisplayFence = std::move(fence); + compositionResult->markAsInUse(outDisplayFence->ok() + ? ::android::base::unique_fd(dup(*outDisplayFence)) + : ::android::base::unique_fd()); return error; } diff --git a/system/hwc3/GuestFrameComposer.h b/system/hwc3/GuestFrameComposer.h index 2d2ca202..9a054f10 100644 --- a/system/hwc3/GuestFrameComposer.h +++ b/system/hwc3/GuestFrameComposer.h @@ -21,6 +21,7 @@ #include "Common.h" #include "Display.h" #include "DrmClient.h" +#include "DrmSwapchain.h" #include "FrameComposer.h" #include "Gralloc.h" #include "Layer.h" @@ -84,15 +85,14 @@ class GuestFrameComposer : public FrameComposer { std::uint32_t dstBufferBytesPerPixel); struct DisplayInfo { - // Additional per display buffer for the composition result. - buffer_handle_t compositionResultBuffer = nullptr; - - std::shared_ptr<DrmBuffer> compositionResultDrmBuffer; + // Additional per display buffers for the composition result. + std::unique_ptr<DrmSwapchain> swapchain = {}; // Scratch storage space for intermediate images during composition. AlternatingImageStorage compositionIntermediateStorage; }; + std::unordered_map<int64_t, DisplayInfo> mDisplayInfos; Gralloc mGralloc; |