Merge "hwc2: Derive dataspace on ClientTarget from ColorMode"
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index f6051bd..c7fab21 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -795,6 +795,9 @@
   // Append client target to the layer stack
   Layer *sdm_client_target = client_target_->GetSDMLayer();
   sdm_client_target->flags.updating = IsLayerUpdating(client_target_);
+  // Derive client target dataspace based on the color mode - bug/115482728
+  int32_t client_target_dataspace = GetDataspaceFromColorMode(GetCurrentColorMode());
+  SetClientTargetDataSpace(client_target_dataspace);
   layer_stack_.layers.push_back(sdm_client_target);
 
   // fall back frame composition to GPU when client target is 10bit
@@ -1147,12 +1150,11 @@
   Layer *sdm_layer = client_target_->GetSDMLayer();
   sdm_layer->frame_rate = current_refresh_rate_;
   client_target_->SetLayerSurfaceDamage(damage);
-  if (client_target_->GetLayerDataspace() != dataspace) {
-    client_target_->SetLayerDataspace(dataspace);
-    Layer *sdm_layer = client_target_->GetSDMLayer();
-    // Data space would be validated at GetClientTargetSupport, so just use here.
-    sdm::GetSDMColorSpace(client_target_->GetLayerDataspace(),
-                          &sdm_layer->input_buffer.color_metadata);
+  int translated_dataspace = TranslateFromLegacyDataspace(dataspace);
+  if (client_target_->GetLayerDataspace() != translated_dataspace) {
+    DLOGW("New Dataspace = %d not matching Dataspace from color mode = %d",
+           translated_dataspace, client_target_->GetLayerDataspace());
+    return HWC2::Error::BadParameter;
   }
   client_target_->SetLayerBuffer(target, acquire_fence);
 
@@ -2298,4 +2300,16 @@
   }
 }
 
+int32_t HWCDisplay::SetClientTargetDataSpace(int32_t dataspace) {
+  if (client_target_->GetLayerDataspace() != dataspace) {
+    client_target_->SetLayerDataspace(dataspace);
+    Layer *sdm_layer = client_target_->GetSDMLayer();
+    // Data space would be validated at GetClientTargetSupport, so just use here.
+    sdm::GetSDMColorSpace(client_target_->GetLayerDataspace(),
+                          &sdm_layer->input_buffer.color_metadata);
+  }
+
+  return 0;
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 70ac73a..3a3401a 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -334,6 +334,7 @@
   bool IsLayerUpdating(HWCLayer *layer);
   uint32_t SanitizeRefreshRate(uint32_t req_refresh_rate);
   virtual void GetUnderScanConfig() { }
+  int32_t SetClientTargetDataSpace(int32_t dataspace);
 
   enum {
     INPUT_LAYER_DUMP,
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 45cfb16..4caad2a 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -182,6 +182,10 @@
     }
   }
 
+  if (dataspace == HAL_DATASPACE_UNKNOWN) {
+    dataspace = HAL_DATASPACE_V0_SRGB;
+  }
+
   return dataspace;
 }
 
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 562903b..168fb79 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -76,7 +76,7 @@
 int HWCSession::null_display_mode_ = 0;
 
 // Map the known color modes to dataspace.
-static int32_t GetDataspace(ColorMode mode) {
+int32_t GetDataspaceFromColorMode(ColorMode mode) {
   switch (mode) {
     case ColorMode::SRGB:
     case ColorMode::NATIVE:
@@ -2834,7 +2834,7 @@
 
   if (hwc_display) {
     *format = HAL_PIXEL_FORMAT_RGB_888;
-    *dataspace = GetDataspace(hwc_display->GetCurrentColorMode());
+    *dataspace = GetDataspaceFromColorMode(hwc_display->GetCurrentColorMode());
     return HWC2_ERROR_NONE;
   }
 
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 5dd803d..a03a43d 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -78,6 +78,8 @@
 using ::android::hardware::Return;
 using ::android::hardware::hidl_string;
 
+int32_t GetDataspaceFromColorMode(ColorMode mode);
+
 // Create a singleton uevent listener thread valid for life of hardware composer process.
 // This thread blocks on uevents poll inside uevent library implementation. This poll exits
 // only when there is a valid uevent, it can not be interrupted otherwise. Tieing life cycle