Merge tag 'android-15.0.0_r10' of https://android.googlesource.com/platform/frameworks/native into HEAD
Android 15.0.0 release 10
Change-Id: Ia1b575dea8e8276e7e84602a77fa29ca3b3e1c91
# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZ32Y6wAKCRDorT+BmrEO
# eF+uAJ4ih5KzthOgb0Kd4LK/qvlPoIuQyACgiUklzqenLL/7h+KfWlr4somovr4=
# =rWiQ
# -----END PGP SIGNATURE-----
# gpg: Signature faite le mar 07 jan 2025 16:13:15 EST
# gpg: avec la clef DSA 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Impossible de vérifier la signature : Pas de clef publique
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 1243b21..b76892f 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -309,9 +309,9 @@
],
}
-cc_library_shared {
- name: "libgui",
- vendor_available: true,
+cc_defaults {
+ name: "libgui_defaults",
+
double_loadable: true,
defaults: [
@@ -505,4 +505,16 @@
],
}
+cc_library_shared {
+ name: "libgui",
+ vendor_available: true,
+ defaults: ["libgui_defaults"]
+}
+
+cc_library_shared {
+ name: "libgui_vendor",
+ vendor: true,
+ defaults: ["libgui_defaults"]
+}
+
subdirs = ["tests"]
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index da74e9c..f1e5eb7 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -167,13 +167,14 @@
return BAD_VALUE;
}
- int bufferCount = mCore->getMinUndequeuedBufferCountLocked();
- bufferCount += maxDequeuedBuffers;
+ int minUndequedBufferCount = mCore->getMinUndequeuedBufferCountLocked();
+ int bufferCount = minUndequedBufferCount + maxDequeuedBuffers;
if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) {
BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large "
"(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
+ bufferCount = BufferQueueDefs::NUM_BUFFER_SLOTS;
+ maxDequeuedBuffers = bufferCount - minUndequedBufferCount;
}
const int minBufferSlots = mCore->getMinMaxBufferCountLocked();
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 12230f9..4664d04 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -153,6 +153,7 @@
"android.hardware.graphics.allocator-ndk_shared",
"android.hardware.graphics.common-ndk_shared",
"libui-defaults",
+ "gralloc_10_usage_bits_defaults",
// Uncomment the following line to enable VALIDATE_REGIONS traces
//defaults: ["libui-validate-regions-defaults"],
],
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
index a5aca99..ed6984d 100644
--- a/libs/ui/Gralloc2.cpp
+++ b/libs/ui/Gralloc2.cpp
@@ -48,6 +48,13 @@
for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
bits = bits | bit;
}
+
+#ifdef ADDNL_GRALLOC_10_USAGE_BITS
+ uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
+ ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
+ bits = bits | addnl_bits;
+#endif
+
return bits;
}();
return valid10UsageBits;
diff --git a/libs/ui/Gralloc3.cpp b/libs/ui/Gralloc3.cpp
index 152b35a..27d0c60 100644
--- a/libs/ui/Gralloc3.cpp
+++ b/libs/ui/Gralloc3.cpp
@@ -47,6 +47,13 @@
hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
bits = bits | bit;
}
+
+#ifdef ADDNL_GRALLOC_10_USAGE_BITS
+ uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
+ ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
+ bits = bits | addnl_bits;
+#endif
+
return bits;
}();
return validUsageBits;
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index 2a60730..7289ab5 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -75,6 +75,13 @@
hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
bits = bits | bit;
}
+
+#ifdef ADDNL_GRALLOC_10_USAGE_BITS
+ uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
+ ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
+ bits = bits | addnl_bits;
+#endif
+
return bits;
}();
return validUsageBits | kRemovedUsageBits;
diff --git a/libs/ui/Gralloc5.cpp b/libs/ui/Gralloc5.cpp
index c9ec036..07aed29 100644
--- a/libs/ui/Gralloc5.cpp
+++ b/libs/ui/Gralloc5.cpp
@@ -190,6 +190,13 @@
for (const auto bit : ndk::enum_range<BufferUsage>{}) {
bits |= static_cast<int64_t>(bit);
}
+
+ #ifdef ADDNL_GRALLOC_10_USAGE_BITS
+ uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
+ ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
+ bits = bits | addnl_bits;
+ #endif
+
return bits;
}();
return validUsageBits | kRemovedUsageBits;
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index c2a9880..da57b68 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -47,6 +47,7 @@
"libtimestats_deps",
"libsurfaceflinger_common_deps",
"surfaceflinger_defaults",
+ "surfaceflinger_qcom_ext_defaults",
"libsurfaceflinger_proto_deps",
],
cflags: [
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index b4ac9ba..5b1aacd 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -86,6 +86,7 @@
"src/OutputLayer.cpp",
"src/OutputLayerCompositionState.cpp",
"src/RenderSurface.cpp",
+ "src/UdfpsExtension.cpp",
],
}
@@ -94,6 +95,7 @@
defaults: [
"libcompositionengine_defaults",
"libsurfaceflinger_common_deps",
+ "surfaceflinger_udfps_lib_defaults",
],
srcs: [
":libcompositionengine_sources",
@@ -175,3 +177,11 @@
hwaddress: true,
},
}
+
+cc_library_static {
+ name: "surfaceflinger_udfps_lib",
+ srcs: [
+ "src/UdfpsExtension.cpp",
+ ],
+ export_include_dirs: ["include"],
+}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/UdfpsExtension.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/UdfpsExtension.h
new file mode 100644
index 0000000..4306cb4
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/UdfpsExtension.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2021-2022 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+
+#ifndef __UDFPS_EXTENSION__H__
+#define __UDFPS_EXTENSION__H__
+
+#define UDFPS_BIOMETRIC_PROMPT_LAYER_NAME "BiometricPrompt"
+#define UDFPS_LAYER_NAME "UdfpsControllerOverlay"
+#define UDFPS_TOUCHED_LAYER_NAME "SurfaceView[UdfpsControllerOverlay](BLAST)"
+
+extern uint32_t getUdfpsZOrder(uint32_t z, bool touched);
+extern uint64_t getUdfpsUsageBits(uint64_t usageBits, bool touched);
+
+#endif /* __UDFPS_EXTENSION__H__ */
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 2d8f98f..9c145b6 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -24,6 +24,7 @@
#include <compositionengine/LayerFE.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/RenderSurface.h>
+#include <compositionengine/UdfpsExtension.h>
#include <compositionengine/impl/HwcAsyncWorker.h>
#include <compositionengine/impl/Output.h>
#include <compositionengine/impl/OutputCompositionState.h>
@@ -911,7 +912,10 @@
compositionengine::OutputLayer* Output::findLayerRequestingBackgroundComposition() const {
compositionengine::OutputLayer* layerRequestingBgComposition = nullptr;
- for (auto* layer : getOutputLayersOrderedByZ()) {
+ for (size_t i = 0; i < getOutputLayerCount(); i++) {
+ compositionengine::OutputLayer* layer = getOutputLayerOrderedByZByIndex(i);
+ compositionengine::OutputLayer* nextLayer = getOutputLayerOrderedByZByIndex(i + 1);
+
const auto* compState = layer->getLayerFE().getCompositionState();
// If any layer has a sideband stream, we will disable blurs. In that case, we don't
@@ -931,6 +935,16 @@
if (compState->backgroundBlurRadius > 0 || compState->blurRegions.size() > 0) {
layerRequestingBgComposition = layer;
}
+
+ // If the next layer is the Udfps touched layer, enable client composition for it
+ // because that somehow leads to the Udfps touched layer getting device composition
+ // consistently.
+ if ((nextLayer != nullptr && layerRequestingBgComposition == nullptr) &&
+ (strncmp(nextLayer->getLayerFE().getDebugName(), UDFPS_TOUCHED_LAYER_NAME,
+ strlen(UDFPS_TOUCHED_LAYER_NAME)) == 0)) {
+ layerRequestingBgComposition = layer;
+ break;
+ }
}
return layerRequestingBgComposition;
}
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 091c207..408c58c 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -18,6 +18,7 @@
#include <compositionengine/DisplayColorProfile.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/Output.h>
+#include <compositionengine/UdfpsExtension.h>
#include <compositionengine/impl/HwcBufferCache.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/OutputLayer.h>
@@ -457,7 +458,17 @@
sourceCrop.bottom, to_string(error).c_str(), static_cast<int32_t>(error));
}
- if (auto error = hwcLayer->setZOrder(z); error != hal::Error::NONE) {
+ uint32_t z_udfps = z;
+ if ((strncmp(getLayerFE().getDebugName(), UDFPS_LAYER_NAME, strlen(UDFPS_LAYER_NAME)) == 0) ||
+ (strncmp(getLayerFE().getDebugName(), UDFPS_BIOMETRIC_PROMPT_LAYER_NAME,
+ strlen(UDFPS_BIOMETRIC_PROMPT_LAYER_NAME)) == 0)) {
+ z_udfps = getUdfpsZOrder(z, false);
+ } else if (strncmp(getLayerFE().getDebugName(), UDFPS_TOUCHED_LAYER_NAME,
+ strlen(UDFPS_TOUCHED_LAYER_NAME)) == 0) {
+ z_udfps = getUdfpsZOrder(z, true);
+ }
+
+ if (auto error = hwcLayer->setZOrder(z_udfps); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set Z %u: %s (%d)", getLayerFE().getDebugName(), z,
to_string(error).c_str(), static_cast<int32_t>(error));
}
diff --git a/services/surfaceflinger/CompositionEngine/src/UdfpsExtension.cpp b/services/surfaceflinger/CompositionEngine/src/UdfpsExtension.cpp
new file mode 100644
index 0000000..2d9d086
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/UdfpsExtension.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 The LineageOS Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TARGET_PROVIDES_UDFPS_LIB
+#include <compositionengine/UdfpsExtension.h>
+
+uint32_t getUdfpsZOrder(uint32_t z, __unused bool touched) {
+ return z;
+}
+
+uint64_t getUdfpsUsageBits(uint64_t usageBits, __unused bool touched) {
+ return usageBits;
+}
+#endif
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 384f7b2..7e29bff 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -51,7 +51,7 @@
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer,
- const std::string& name)
+ const std::string& name, bool secure)
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
: ConsumerBase(bqProducer, bqConsumer),
#else
@@ -74,7 +74,9 @@
mOutputFence(Fence::NO_FENCE),
mFbProducerSlot(BufferQueue::INVALID_BUFFER_SLOT),
mOutputProducerSlot(BufferQueue::INVALID_BUFFER_SLOT),
- mForceHwcCopy(SurfaceFlinger::useHwcForRgbToYuv) {
+ mForceHwcCopy(SurfaceFlinger::useHwcForRgbToYuv),
+ mSecure(secure),
+ mSinkUsage(0) {
mSource[SOURCE_SINK] = sink;
mSource[SOURCE_SCRATCH] = bqProducer;
@@ -92,6 +94,8 @@
// on usage bits.
int sinkUsage;
sink->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &sinkUsage);
+ mSinkUsage |= (GRALLOC_USAGE_HW_COMPOSER | sinkUsage);
+ setOutputUsage(mSinkUsage);
if (sinkUsage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
int sinkFormat;
sink->query(NATIVE_WINDOW_FORMAT, &sinkFormat);
@@ -124,7 +128,11 @@
}
mMustRecompose = mustRecompose;
-
+ //For WFD use cases we must always set the recompose flag in order
+ //to support pause/resume functionality
+ if (mOutputUsage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+ mMustRecompose = true;
+ }
VDS_LOGW_IF(mDebugState != DebugState::Idle, "Unexpected %s in %s state", __func__,
ftl::enum_string(mDebugState).c_str());
mDebugState = DebugState::Begun;
@@ -161,7 +169,7 @@
}
if (mCompositionType != CompositionType::Gpu &&
- (mOutputFormat != mDefaultOutputFormat || mOutputUsage != GRALLOC_USAGE_HW_COMPOSER)) {
+ (mOutputFormat != mDefaultOutputFormat || !(mOutputUsage & GRALLOC_USAGE_HW_COMPOSER))) {
// We must have just switched from GPU-only to MIXED or HWC
// composition. Stop using the format and usage requested by the GPU
// driver; they may be suboptimal when HWC is writing to the output
@@ -173,7 +181,7 @@
// format/usage and get a new buffer when the GPU driver calls
// dequeueBuffer().
mOutputFormat = mDefaultOutputFormat;
- mOutputUsage = GRALLOC_USAGE_HW_COMPOSER;
+ setOutputUsage(GRALLOC_USAGE_HW_COMPOSER);
refreshOutputBuffer();
}
@@ -259,7 +267,7 @@
int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot);
QueueBufferOutput qbo;
VDS_LOGV("%s: queue sink sslot=%d", __func__, sslot);
- if (mMustRecompose) {
+ if (retireFence->isValid() && mMustRecompose) {
status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
QueueBufferInput(
systemTime(), false /* isAutoTimestamp */,
@@ -323,6 +331,14 @@
PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) {
LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value());
+ // Exclude video encoder usage flag from scratch buffer usage flags.
+ if (source == SOURCE_SCRATCH) {
+ usage |= GRALLOC_USAGE_HW_FB;
+ usage &= ~(GRALLOC_USAGE_HW_VIDEO_ENCODER);
+ VDS_LOGV("%s(%s): updated scratch buffer usage flags=%#" PRIx64,
+ __func__, ftl::enum_string(source).c_str(), usage);
+ }
+
status_t result =
mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight,
format, usage, nullptr, nullptr);
@@ -352,11 +368,11 @@
}
}
if (result & BUFFER_NEEDS_REALLOCATION) {
- result = mSource[source]->requestBuffer(*sslot, &mProducerBuffers[pslot]);
- if (result < 0) {
+ auto status = mSource[source]->requestBuffer(*sslot, &mProducerBuffers[pslot]);
+ if (status < 0) {
mProducerBuffers[pslot].clear();
mSource[source]->cancelBuffer(*sslot, *fence);
- return result;
+ return status;
}
VDS_LOGV("%s(%s): buffers[%d]=%p fmt=%d usage=%#" PRIx64, __func__,
ftl::enum_string(source).c_str(), pslot, mProducerBuffers[pslot].get(),
@@ -417,7 +433,7 @@
__func__, w, h, format, usage, mSinkBufferWidth, mSinkBufferHeight,
buf->getPixelFormat(), buf->getUsage());
mOutputFormat = format;
- mOutputUsage = usage;
+ setOutputUsage(usage);
result = refreshOutputBuffer();
if (result < 0)
return result;
@@ -671,6 +687,21 @@
return type == CompositionType::Unknown ? "Unknown"s : ftl::Flags(type).string();
}
+/* Helper to update the output usage when the display is secure */
+
+void VirtualDisplaySurface::setOutputUsage(uint64_t /*flag*/) {
+
+ mOutputUsage = mSinkUsage;
+ if (mSecure && (mOutputUsage & GRALLOC_USAGE_HW_VIDEO_ENCODER)) {
+ /*TODO: Currently, the framework can only say whether the display
+ * and its subsequent session are secure or not. However, there is
+ * no mechanism to distinguish the different levels of security.
+ * The current solution assumes WV L3 protection.
+ */
+ mOutputUsage |= GRALLOC_USAGE_PROTECTED;
+ }
+}
+
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 90426f7..805fce9 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -77,7 +77,8 @@
public:
VirtualDisplaySurface(HWComposer&, VirtualDisplayId, const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
- const sp<IGraphicBufferConsumer>& bqConsumer, const std::string& name);
+ const sp<IGraphicBufferConsumer>& bqConsumer,
+ const std::string& name, bool secure);
//
// DisplaySurface interface
@@ -134,6 +135,7 @@
sp<Fence>* outFence, float outTransformMatrix[16]) override;
virtual status_t getUniqueId(uint64_t* outId) const override;
virtual status_t getConsumerUsage(uint64_t* outUsage) const override;
+ virtual void setOutputUsage(uint64_t flag);
//
// Utility methods
@@ -265,6 +267,8 @@
bool mMustRecompose = false;
bool mForceHwcCopy;
+ bool mSecure;
+ int mSinkUsage;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 65a0ed3..23a2f9f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -165,6 +165,14 @@
#include "Utils/Dumper.h"
#include "WindowInfosListenerInvoker.h"
+#ifdef QCOM_UM_FAMILY
+#if __has_include("QtiGralloc.h")
+#include "QtiGralloc.h"
+#else
+#include "gralloc_priv.h"
+#endif
+#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>
@@ -640,8 +648,10 @@
}
VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution,
- ui::PixelFormat format) {
- if (auto& generator = mVirtualDisplayIdGenerators.hal) {
+ ui::PixelFormat format,
+ bool canAllocateHwcForVDS) {
+ auto& generator = mVirtualDisplayIdGenerators.hal;
+ if (canAllocateHwcForVDS && generator) {
if (const auto id = generator->generateId()) {
if (getHwComposer().allocateVirtualDisplay(*id, resolution, &format)) {
return *id;
@@ -899,9 +909,9 @@
enableLatchUnsignaledConfig = getLatchUnsignaledConfig();
- if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
- enableHalVirtualDisplays(true);
- }
+ mAllowHwcForWFD = base::GetBoolProperty("vendor.display.vds_allow_hwc"s, false);
+ mAllowHwcForVDS = mAllowHwcForWFD && base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false);
+ mFirstApiLevel = android::base::GetIntProperty("ro.product.first_api_level", 0);
// Process hotplug for displays connected at boot.
LOG_ALWAYS_FATAL_IF(!configureLocked(),
@@ -3657,6 +3667,11 @@
void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
const DisplayDeviceState& state) {
+#ifdef QCOM_UM_FAMILY
+ bool canAllocateHwcForVDS = false;
+#else
+ bool canAllocateHwcForVDS = true;
+#endif
ui::Size resolution(0, 0);
ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);
if (state.physical) {
@@ -3671,6 +3686,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);
+#ifdef QCOM_UM_FAMILY
+ // Check if VDS is allowed to use HWC
+ size_t maxVirtualDisplaySize = getHwComposer().getMaxVirtualDisplayDimension();
+ if (maxVirtualDisplaySize == 0 || ((uint64_t)resolution.width <= maxVirtualDisplaySize &&
+ (uint64_t)resolution.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;
+ }
+ }
+#endif
} else {
// Virtual displays without a surface are dormant:
// they have external state (layer stack, projection,
@@ -3682,7 +3711,7 @@
if (const auto& physical = state.physical) {
builder.setId(physical->id);
} else {
- builder.setId(acquireVirtualDisplay(resolution, pixelFormat));
+ builder.setId(acquireVirtualDisplay(resolution, pixelFormat, canAllocateHwcForVDS));
}
builder.setPixels(resolution);
@@ -3703,7 +3732,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 {
@@ -7787,6 +7817,35 @@
} // namespace
+#ifdef QCOM_UM_FAMILY
+bool SurfaceFlinger::canAllocateHwcDisplayIdForVDS(uint64_t usage) {
+ uint64_t flag_mask_pvt_wfd = ~0;
+ uint64_t flag_mask_hw_video = ~0;
+ // 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;
+ bool isWfd = (usage & flag_mask_pvt_wfd) && (usage & flag_mask_hw_video);
+ // Enabling only the vendor property would allow WFD to use HWC
+ // Enabling both the aosp and vendor properties would allow all other VDS to use HWC
+ // Disabling both would set all virtual displays to fall back to GPU
+ // In vendor frozen targets, allow WFD to use HWC without any property settings.
+ bool canAllocate = mAllowHwcForVDS || (isWfd && mAllowHwcForWFD) || (isWfd &&
+ mFirstApiLevel < __ANDROID_API_T__);
+
+ if (canAllocate) {
+ enableHalVirtualDisplays(true);
+ }
+
+ return canAllocate;
+
+}
+#else
+bool SurfaceFlinger::canAllocateHwcDisplayIdForVDS(uint64_t) {
+ return true;
+}
+#endif
+
status_t SurfaceFlinger::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
const gui::DisplayModeSpecs& specs) {
SFTRACE_CALL();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3eb72cc..1ccfdc9 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -893,6 +893,8 @@
std::vector<std::pair<Layer*, sp<LayerFE>>>& layers,
std::vector<sp<LayerFE>>& layerFEs);
+ bool canAllocateHwcDisplayIdForVDS(uint64_t usage);
+
void readPersistentProperties();
uint32_t getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const;
@@ -1078,7 +1080,8 @@
void enableHalVirtualDisplays(bool);
// Virtual display lifecycle for ID generation and HAL allocation.
- VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat) REQUIRES(mStateLock);
+ VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat, bool canAllocateHwcForVDS)
+ REQUIRES(mStateLock);
void releaseVirtualDisplay(VirtualDisplayId);
// Returns a display other than `mActiveDisplayId` that can be activated, if any.
@@ -1406,6 +1409,10 @@
const sp<WindowInfosListenerInvoker> mWindowInfosListenerInvoker;
+ bool mAllowHwcForVDS = false;
+ bool mAllowHwcForWFD = false;
+ int mFirstApiLevel = 0;
+
// returns the framerate of the layer with the given sequence ID
float getLayerFramerate(nsecs_t now, int32_t id) const {
return mScheduler->getLayerFramerate(now, id);