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
diff --git a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
index 6ebcdfe..7ed0570 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.cpp
@@ -261,6 +261,8 @@
                     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 @@
         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 @@
     mVsyncEnabled(Vsync::Invalid),
     mClientTarget(),
     mOutputBuffer(),
+    mHasColorTransform(false),
     mLayers(),
     mHwc1LayerMap() {}
 
@@ -850,6 +855,16 @@
     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 @@
     }
 }
 
+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 @@
     mZ(0),
     mReleaseFence(),
     mHwc1Id(0),
+    mHasUnsupportedDataspace(false),
     mHasUnsupportedPlaneAlpha(false) {}
 
 bool HWC2On1Adapter::SortLayersByZ::operator()(
@@ -1748,6 +1770,12 @@
     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::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;