From 5df2a86063c6a83813fc1aa3d8938a82f7ff8f14 Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Thu, 24 Mar 2016 16:19:37 -0700 Subject: [PATCH] HWC2: Hook up setColorTransform/setLayerDataspace Plumbs the setColorTransform and setLayerDataspace calls through the HWC2 C++ shim and implements a trivial versions in the adapter, which drops non-HAL_DATASPACE_UNKNOWN layers to client composition, and which drops all layers to client composition if a color transform is applied. Bug: 22767098 Change-Id: Ifffd19b77cf3b33ec86fde3f72257f6b97b4dd79 --- services/surfaceflinger/DisplayHardware/HWC2.cpp | 22 ++++++++++++++ services/surfaceflinger/DisplayHardware/HWC2.h | 7 +++++ .../DisplayHardware/HWC2On1Adapter.cpp | 34 +++++++++++++++++++++- .../DisplayHardware/HWC2On1Adapter.h | 25 ++++++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index f7678e405c..f53e0a2771 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -107,6 +107,7 @@ Device::Device(hwc2_device_t* device) mPresentDisplay(nullptr), mSetActiveConfig(nullptr), mSetClientTarget(nullptr), + mSetColorTransform(nullptr), mSetOutputBuffer(nullptr), mSetPowerMode(nullptr), mSetVsyncEnabled(nullptr), @@ -117,6 +118,7 @@ Device::Device(hwc2_device_t* device) mSetLayerBlendMode(nullptr), mSetLayerColor(nullptr), mSetLayerCompositionType(nullptr), + mSetLayerDataspace(nullptr), mSetLayerDisplayFrame(nullptr), mSetLayerPlaneAlpha(nullptr), mSetLayerSidebandStream(nullptr), @@ -359,6 +361,8 @@ void Device::loadFunctionPointers() mSetActiveConfig)) return; if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget, mSetClientTarget)) return; + if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform, + mSetColorTransform)) return; if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer, mSetOutputBuffer)) return; if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode, @@ -381,6 +385,8 @@ void Device::loadFunctionPointers() mSetLayerColor)) return; if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType, mSetLayerCompositionType)) return; + if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace, + mSetLayerDataspace)) return; if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame, mSetLayerDisplayFrame)) return; if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha, @@ -752,6 +758,14 @@ Error Display::setClientTarget(buffer_handle_t target, return static_cast(intError); } +Error Display::setColorTransform(const android::mat4& matrix, + android_color_transform_t hint) +{ + int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId, + matrix.asArray(), static_cast(hint)); + return static_cast(intError); +} + Error Display::setOutputBuffer(const sp& buffer, const sp& releaseFence) { @@ -965,6 +979,14 @@ Error Layer::setCompositionType(Composition type) return static_cast(intError); } +Error Layer::setDataspace(android_dataspace_t dataspace) +{ + auto intDataspace = static_cast(dataspace); + int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice, + mDisplayId, mId, intDataspace); + return static_cast(intError); +} + Error Layer::setDisplayFrame(const Rect& frame) { hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom}; diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 967add01f2..76963056d8 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -24,6 +24,7 @@ #undef HWC2_USE_CPP11 #include +#include #include #include @@ -154,6 +155,7 @@ private: HWC2_PFN_PRESENT_DISPLAY mPresentDisplay; HWC2_PFN_SET_ACTIVE_CONFIG mSetActiveConfig; HWC2_PFN_SET_CLIENT_TARGET mSetClientTarget; + HWC2_PFN_SET_COLOR_TRANSFORM mSetColorTransform; HWC2_PFN_SET_OUTPUT_BUFFER mSetOutputBuffer; HWC2_PFN_SET_POWER_MODE mSetPowerMode; HWC2_PFN_SET_VSYNC_ENABLED mSetVsyncEnabled; @@ -166,6 +168,7 @@ private: HWC2_PFN_SET_LAYER_BLEND_MODE mSetLayerBlendMode; HWC2_PFN_SET_LAYER_COLOR mSetLayerColor; HWC2_PFN_SET_LAYER_COMPOSITION_TYPE mSetLayerCompositionType; + HWC2_PFN_SET_LAYER_DATASPACE mSetLayerDataspace; HWC2_PFN_SET_LAYER_DISPLAY_FRAME mSetLayerDisplayFrame; HWC2_PFN_SET_LAYER_PLANE_ALPHA mSetLayerPlaneAlpha; HWC2_PFN_SET_LAYER_SIDEBAND_STREAM mSetLayerSidebandStream; @@ -297,6 +300,8 @@ public: buffer_handle_t target, const android::sp& acquireFence, android_dataspace_t dataspace); + [[clang::warn_unused_result]] Error setColorTransform( + const android::mat4& matrix, android_color_transform_t hint); [[clang::warn_unused_result]] Error setOutputBuffer( const android::sp& buffer, const android::sp& releaseFence); @@ -360,6 +365,8 @@ public: [[clang::warn_unused_result]] Error setBlendMode(BlendMode mode); [[clang::warn_unused_result]] Error setColor(hwc_color_t color); [[clang::warn_unused_result]] Error setCompositionType(Composition type); + [[clang::warn_unused_result]] Error setDataspace( + android_dataspace_t dataspace); [[clang::warn_unused_result]] Error setDisplayFrame( const android::Rect& frame); [[clang::warn_unused_result]] Error setPlaneAlpha(float alpha); diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp index 6ebcdfeba6..7ed05706fb 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp @@ -261,6 +261,8 @@ hwc2_function_pointer_t HWC2On1Adapter::doGetFunction( displayHook); + case FunctionDescriptor::SetColorTransform: + return asFP(setColorTransformHook); case FunctionDescriptor::SetOutputBuffer: return asFP( displayHook( setLayerCompositionTypeHook); + case FunctionDescriptor::SetLayerDataspace: + return asFP(setLayerDataspaceHook); case FunctionDescriptor::SetLayerDisplayFrame: return asFP( layerHook lock(mStateMutex); + + ALOGV("%" PRIu64 "] setColorTransform(%d)", mId, + static_cast(hint)); + mHasColorTransform = (hint != HAL_COLOR_TRANSFORM_IDENTITY); + return Error::None; +} + Error HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer, int32_t releaseFence) { @@ -1286,6 +1301,12 @@ void HWC2On1Adapter::Display::addReleaseFences( } } +bool HWC2On1Adapter::Display::hasColorTransform() const +{ + std::unique_lock lock(mStateMutex); + return mHasColorTransform; +} + static std::string hwc1CompositionString(int32_t type) { switch (type) { @@ -1688,6 +1709,7 @@ HWC2On1Adapter::Layer::Layer(Display& display) mZ(0), mReleaseFence(), mHwc1Id(0), + mHasUnsupportedDataspace(false), mHasUnsupportedPlaneAlpha(false) {} bool HWC2On1Adapter::SortLayersByZ::operator()( @@ -1748,6 +1770,12 @@ Error HWC2On1Adapter::Layer::setCompositionType(Composition type) return Error::None; } +Error HWC2On1Adapter::Layer::setDataspace(android_dataspace_t dataspace) +{ + mHasUnsupportedDataspace = (dataspace != HAL_DATASPACE_UNKNOWN); + return Error::None; +} + Error HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame) { mDisplayFrame.setPending(frame); @@ -1976,7 +2004,11 @@ void HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer) void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer, bool applyAllState) { - if (mHasUnsupportedPlaneAlpha) { + // HWC1 never supports color transforms or dataspaces and only sometimes + // supports plane alpha (depending on the version). These require us to drop + // some or all layers to client composition. + if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha || + mDisplay.hasColorTransform()) { hwc1Layer.compositionType = HWC_FRAMEBUFFER; hwc1Layer.flags = HWC_SKIP_LAYER; return; diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h index 6fdb1840af..2e6206e9a3 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h +++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h @@ -208,6 +208,7 @@ private: HWC2::Error setActiveConfig(hwc2_config_t configId); HWC2::Error setClientTarget(buffer_handle_t target, int32_t acquireFence, int32_t dataspace); + HWC2::Error setColorTransform(android_color_transform_t hint); HWC2::Error setOutputBuffer(buffer_handle_t buffer, int32_t releaseFence); HWC2::Error setPowerMode(HWC2::PowerMode mode); @@ -231,6 +232,8 @@ private: void addRetireFence(int fenceFd); void addReleaseFences(const hwc_display_contents_1& hwcContents); + bool hasColorTransform() const; + std::string dump() const; private: @@ -359,6 +362,8 @@ private: FencedBuffer mClientTarget; FencedBuffer mOutputBuffer; + bool mHasColorTransform; + std::multiset, SortLayersByZ> mLayers; std::unordered_map> mHwc1LayerMap; }; @@ -390,6 +395,17 @@ private: config, attribute, outValue); } + static int32_t setColorTransformHook(hwc2_device_t* device, + hwc2_display_t display, const float* /*matrix*/, + int32_t /*android_color_transform_t*/ intHint) { + // We intentionally throw away the matrix, because if the hint is + // anything other than IDENTITY, we have to fall back to client + // composition anyway + auto hint = static_cast(intHint); + return callDisplayFunction(device, display, &Display::setColorTransform, + hint); + } + static int32_t setPowerModeHook(hwc2_device_t* device, hwc2_display_t display, int32_t intMode) { auto mode = static_cast(intMode); @@ -467,6 +483,7 @@ private: HWC2::Error setBlendMode(HWC2::BlendMode mode); HWC2::Error setColor(hwc_color_t color); HWC2::Error setCompositionType(HWC2::Composition type); + HWC2::Error setDataspace(android_dataspace_t dataspace); HWC2::Error setDisplayFrame(hwc_rect_t frame); HWC2::Error setPlaneAlpha(float alpha); HWC2::Error setSidebandStream(const native_handle_t* stream); @@ -523,6 +540,7 @@ private: DeferredFence mReleaseFence; size_t mHwc1Id; + bool mHasUnsupportedDataspace; bool mHasUnsupportedPlaneAlpha; }; @@ -562,6 +580,13 @@ private: &Layer::setCompositionType, type); } + static int32_t setLayerDataspaceHook(hwc2_device_t* device, + hwc2_display_t display, hwc2_layer_t layer, int32_t intDataspace) { + auto dataspace = static_cast(intDataspace); + return callLayerFunction(device, display, layer, &Layer::setDataspace, + dataspace); + } + static int32_t setLayerTransformHook(hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer, int32_t intTransform) { auto transform = static_cast(intTransform); -- 2.11.0