OSDN Git Service

HWC2: Hook up setColorTransform/setLayerDataspace
authorDan Stoza <stoza@google.com>
Thu, 24 Mar 2016 23:19:37 +0000 (16:19 -0700)
committerDan Stoza <stoza@google.com>
Wed, 4 May 2016 20:46:36 +0000 (13:46 -0700)
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
services/surfaceflinger/DisplayHardware/HWC2.h
services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
services/surfaceflinger/DisplayHardware/HWC2On1Adapter.h

index f7678e4..f53e0a2 100644 (file)
@@ -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<Error>(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<int32_t>(hint));
+    return static_cast<Error>(intError);
+}
+
 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
         const sp<Fence>& releaseFence)
 {
@@ -965,6 +979,14 @@ Error Layer::setCompositionType(Composition type)
     return static_cast<Error>(intError);
 }
 
+Error Layer::setDataspace(android_dataspace_t dataspace)
+{
+    auto intDataspace = static_cast<int32_t>(dataspace);
+    int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
+            mDisplayId, mId, intDataspace);
+    return static_cast<Error>(intError);
+}
+
 Error Layer::setDisplayFrame(const Rect& frame)
 {
     hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
index 967add0..7696305 100644 (file)
@@ -24,6 +24,7 @@
 #undef HWC2_USE_CPP11
 
 #include <ui/HdrCapabilities.h>
+#include <ui/mat4.h>
 
 #include <utils/Log.h>
 #include <utils/StrongPointer.h>
@@ -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<android::Fence>& 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<android::GraphicBuffer>& buffer,
             const android::sp<android::Fence>& 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);
index 6ebcdfe..7ed0570 100644 (file)
@@ -261,6 +261,8 @@ hwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
                     displayHook<decltype(&Display::setClientTarget),
                     &Display::setClientTarget, buffer_handle_t, int32_t,
                     int32_t>);
+        case FunctionDescriptor::SetColorTransform:
+            return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
         case FunctionDescriptor::SetOutputBuffer:
             return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
                     displayHook<decltype(&Display::setOutputBuffer),
@@ -299,6 +301,8 @@ hwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
         case FunctionDescriptor::SetLayerCompositionType:
             return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
                     setLayerCompositionTypeHook);
+        case FunctionDescriptor::SetLayerDataspace:
+            return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerDataspaceHook);
         case FunctionDescriptor::SetLayerDisplayFrame:
             return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
                     layerHook<decltype(&Layer::setDisplayFrame),
@@ -554,6 +558,7 @@ HWC2On1Adapter::Display::Display(HWC2On1Adapter& device, HWC2::DisplayType type)
     mVsyncEnabled(Vsync::Invalid),
     mClientTarget(),
     mOutputBuffer(),
+    mHasColorTransform(false),
     mLayers(),
     mHwc1LayerMap() {}
 
@@ -850,6 +855,16 @@ Error HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target,
     return Error::None;
 }
 
+Error HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint)
+{
+    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
+
+    ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
+            static_cast<int32_t>(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<std::recursive_mutex> 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;
index 6fdb184..2e6206e 100644 (file)
@@ -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<std::shared_ptr<Layer>, SortLayersByZ> mLayers;
             std::unordered_map<size_t, std::shared_ptr<Layer>> 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<android_color_transform_t>(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<HWC2::PowerMode>(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<android_dataspace_t>(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<HWC2::Transform>(intTransform);