sf: Fix virtual display related issues.
1. SurfaceFlinger: Fix virtual display related issues. 1) Validate
output
buffer usage bit appropriately Validate output buffer usage bit only
against GRALLOC_USAGE_HW_COMPOSER to differentiate GLES only
conposition
and HWC/MIXED composition. 2) Exclude video encoder usage for
scratch
buffer Sink and Scratch buffers in VDS are using same usage
flags. This
causes video encoder flag to be set for scratch buffers
Also. Exclude
video encoder flag from scratch buffer usage flags as
scratch buffers
are used only as write back input and not video
encoder input.
2. sf: Allow VDS to use HWC -- Preserve VDS layer
pixel format based on
GRALLOC flags. -- skip color layer for vds
3. sf: Add secure content support for VDS
4. sf: Enable GPU comp. for non-primary displays
Ensure that "Return
status" of dequeueBuffer() complies with API
requirements. Client relies
on this status to call requestBuffer()
upon reallocation.
5. sf: Enable UBWC on virtual display scratch buffer Set
GRALLOC_USAGE_HW_FB usage flag on virtual display Scratch
buffer to
enable UBWC.
Change-Id: Ia49a175372ca187a295531e18f8e84dc22a19486
CRs-Fixed: 2656027
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fcead9f..f1e22b3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -163,6 +163,12 @@
#include "Utils/Dumper.h"
#include "WindowInfosListenerInvoker.h"
+#if __has_include("QtiGralloc.h")
+#include "QtiGralloc.h"
+#else
+#include "gralloc_priv.h"
+#endif
+
#include <aidl/android/hardware/graphics/common/DisplayDecorationSupport.h>
#include <aidl/android/hardware/graphics/composer3/DisplayCapability.h>
#include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
@@ -3796,6 +3802,7 @@
void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
const DisplayDeviceState& state) {
+ bool canAllocateHwcForVDS = false;
ui::Size resolution(0, 0);
ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);
if (state.physical) {
@@ -3810,6 +3817,20 @@
status = state.surface->query(NATIVE_WINDOW_FORMAT, &format);
ALOGE_IF(status != NO_ERROR, "Unable to query format (%d)", status);
pixelFormat = static_cast<ui::PixelFormat>(format);
+ if (mUseHwcVirtualDisplays || getHwComposer().isUsingVrComposer()) {
+ if (maxVirtualDisplaySize == 0 ||
+ ((uint64_t)width <= maxVirtualDisplaySize &&
+ (uint64_t)height <= maxVirtualDisplaySize)) {
+ uint64_t usage = 0;
+ // Replace with native_window_get_consumer_usage ?
+ status = state .surface->getConsumerUsage(&usage);
+ ALOGW_IF(status != NO_ERROR, "Unable to query usage (%d)", status);
+ if ((status == NO_ERROR) && canAllocateHwcDisplayIdForVDS(usage)) {
+ canAllocateHwcForVDS = true;
+ }
+ }
+ }
+
} else {
// Virtual displays without a surface are dormant:
// they have external state (layer stack, projection,
@@ -3842,7 +3863,8 @@
const auto displayId = VirtualDisplayId::tryCast(compositionDisplay->getId());
LOG_FATAL_IF(!displayId);
auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *displayId, state.surface,
- bqProducer, bqConsumer, state.displayName);
+ bqProducer, bqConsumer, state.displayName,
+ state.isSecure);
displaySurface = surface;
producer = std::move(surface);
} else {
@@ -8801,6 +8823,20 @@
} // namespace
+bool SurfaceFlinger::canAllocateHwcDisplayIdForVDS(uint64_t usage) {
+ uint64_t flag_mask_pvt_wfd = ~0;
+ uint64_t flag_mask_hw_video = ~0;
+ char value[PROPERTY_VALUE_MAX] = {};
+ property_get("vendor.display.vds_allow_hwc", value, "0");
+ int allowHwcForVDS = atoi(value);
+ // Reserve hardware acceleration for WFD use-case
+ // GRALLOC_USAGE_PRIVATE_WFD + GRALLOC_USAGE_HW_VIDEO_ENCODER = WFD using HW composer.
+ flag_mask_pvt_wfd = GRALLOC_USAGE_PRIVATE_WFD;
+ flag_mask_hw_video = GRALLOC_USAGE_HW_VIDEO_ENCODER;
+ return (allowHwcForVDS || ((usage & flag_mask_pvt_wfd) &&
+ (usage & flag_mask_hw_video)));
+}
+
status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
const gui::DisplayModeSpecs& specs) {
ATRACE_CALL();