From eb3db61f914a2469fe632c48b46a0ce60c84c9d9 Mon Sep 17 00:00:00 2001 From: Fabien Sanglard Date: Fri, 18 Nov 2016 16:12:31 -0800 Subject: [PATCH] Fix 5x and 6P crash when using HWC2to1adapter Angler and Bullhead crash when a SolidColor layer is used in combination with HWC2to1Adapter. This is due to assumptions in the HWC1 code (non-null handle field = valid pointer). This assumption is incorrect with a background layer because it will set the field backgroundcolor...which occupies the same location as handle field in hwc_layer_1_t. This patch detects whether the HWC supports BACKGROUND layer and sets backgroundcolor/handle accordingly to HWC assumption. Test: Manual on Angler and Bullhead. Change-Id: Ic5c3366a4a8989f3a82b6367258bad8af25d3990 --- .../DisplayHardware/HWC2On1Adapter.cpp | 28 ++++++++++++++++++++-- .../DisplayHardware/HWC2On1Adapter.h | 6 +++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp index 1107c994ec..40c67156ca 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp @@ -132,6 +132,7 @@ HWC2On1Adapter::HWC2On1Adapter(hwc_composer_device_1_t* hwc1Device) mHwc1Device(hwc1Device), mHwc1MinorVersion(getMinorVersion(hwc1Device)), mHwc1SupportsVirtualDisplays(false), + mHwc1SupportsBackgroundColor(false), mHwc1Callbacks(std::make_unique(*this)), mCapabilities(), mLayers(), @@ -2272,7 +2273,18 @@ void HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer, bool applyAllState) { if (applyAllState || mColor.isDirty()) { - hwc1Layer.backgroundColor = mColor.getPendingValue(); + // If the device does not support background color it is likely to make + // assumption regarding backgroundColor and handle (both fields occupy + // the same location in hwc_layer_1_t union). + // To not confuse these devices we don't set background color and we + // make sure handle is a null pointer. + if (mDisplay.getDevice().supportsBackgroundColor()) { + hwc1Layer.backgroundColor = mColor.getPendingValue(); + mHasUnsupportedBackgroundColor = false; + } else { + hwc1Layer.handle = nullptr; + mHasUnsupportedBackgroundColor = true; + } mColor.latch(); } } @@ -2299,7 +2311,7 @@ void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer, // supports plane alpha (depending on the version). These require us to drop // some or all layers to client composition. if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha || - mDisplay.hasColorTransform()) { + mDisplay.hasColorTransform() || mHasUnsupportedBackgroundColor) { hwc1Layer.compositionType = HWC_FRAMEBUFFER; hwc1Layer.flags = HWC_SKIP_LAYER; return; @@ -2369,6 +2381,18 @@ void HWC2On1Adapter::populateCapabilities() if (mHwc1MinorVersion >= 4U) { mCapabilities.insert(Capability::SidebandStream); } + + // Check for HWC background color layer support. + if (mHwc1MinorVersion >= 1U) { + int backgroundColorSupported = 0; + auto result = mHwc1Device->query(mHwc1Device, + HWC_BACKGROUND_LAYER_SUPPORTED, + &backgroundColorSupported); + if ((result == 0) && (backgroundColorSupported == 1)) { + ALOGV("Found support for HWC background color"); + mHwc1SupportsBackgroundColor = true; + } + } } HWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id) diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h index 047e3aa2f1..daa988c2a3 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h +++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h @@ -63,6 +63,10 @@ private: getAdapter(device)->doGetCapabilities(outCount, outCapabilities); } + bool supportsBackgroundColor() { + return mHwc1SupportsBackgroundColor; + } + // getFunction hwc2_function_pointer_t doGetFunction(HWC2::FunctionDescriptor descriptor); @@ -576,6 +580,7 @@ private: size_t mHwc1Id; bool mHasUnsupportedDataspace; bool mHasUnsupportedPlaneAlpha; + bool mHasUnsupportedBackgroundColor; }; template @@ -656,6 +661,7 @@ private: struct hwc_composer_device_1* const mHwc1Device; const uint8_t mHwc1MinorVersion; bool mHwc1SupportsVirtualDisplays; + bool mHwc1SupportsBackgroundColor; class Callbacks; const std::unique_ptr mHwc1Callbacks; -- 2.11.0