Merge "hwc2: Use floating value refresh rate"
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index dfea4c8..3e0896f 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -34,6 +34,8 @@
#define __DISPLAY_INTERFACE_H__
#include <stdint.h>
+#include <string>
+#include <vector>
#include "layer_stack.h"
#include "sdm_types.h"
@@ -412,6 +414,41 @@
PPDisplayAPIPayload *out_payload,
PPPendingParams *pending_action) = 0;
+ /*! @brief Method to request the number of color modes supported.
+
+ @param[out] mode_count Number of modes
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetColorModeCount(uint32_t *mode_count) = 0;
+
+ /*! @brief Method to request the information of supported color modes.
+
+ @param[inout] mode_count Number of updated modes
+ @param[out] vector of mode strings
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError GetColorModes(uint32_t *mode_count,
+ std::vector<std::string> *color_modes) = 0;
+
+ /*! @brief Method to set the color mode
+
+ @param[in] mode_name Mode name which needs to be set
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetColorMode(const std::string &color_mode) = 0;
+
+ /*! @brief Method to set the color transform
+
+ @param[in] length Mode name which needs to be set
+ @param[in] color_transform 4x4 Matrix for color transform
+
+ @return \link DisplayError \endlink
+ */
+ virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform) = 0;
+
/*! @brief Method to request applying default display mode.
@return \link DisplayError \endlink
diff --git a/sdm/include/private/color_interface.h b/sdm/include/private/color_interface.h
index b84bcab..cc7eac3 100644
--- a/sdm/include/private/color_interface.h
+++ b/sdm/include/private/color_interface.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2015-2016, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -60,6 +60,20 @@
virtual DisplayError ApplyDefaultDisplayMode(PPFeaturesConfig *out_features) = 0;
+ virtual DisplayError ColorIntfSetColorTransform(PPFeaturesConfig *out_features,
+ uint32_t disp_id, uint32_t length,
+ const double *trans_data) = 0;
+
+ virtual DisplayError ColorIntfSetDisplayMode(PPFeaturesConfig *out_features,
+ uint32_t disp_id, int32_t mode_id) = 0;
+
+ virtual DisplayError ColorIntfGetNumDisplayModes(PPFeaturesConfig *out_features,
+ uint32_t disp_id, uint32_t *mode_cnt) = 0;
+
+ virtual DisplayError ColorIntfEnumerateDisplayModes(PPFeaturesConfig *out_features,
+ uint32_t disp_id, SDEDisplayMode *modes,
+ uint32_t *mode_cnt) = 0;
+
protected:
virtual ~ColorInterface() {}
};
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index 9eb5d79..8bca55f 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -315,6 +315,13 @@
uint32_t *c2_data = NULL;
};
+struct SDEDisplayMode {
+ static const int kMaxModeNameSize = 256;
+ int32_t id = -1;
+ uint32_t type = 0;
+ char name[kMaxModeNameSize] = {0};
+};
+
// Wrapper on HW block config data structure to encapsulate the details of allocating
// and destroying from the caller.
class SDEGamutCfgWrapper : private SDEGamutCfg {
diff --git a/sdm/libs/core/color_manager.cpp b/sdm/libs/core/color_manager.cpp
index 7b8a1ca..f24a920 100644
--- a/sdm/libs/core/color_manager.cpp
+++ b/sdm/libs/core/color_manager.cpp
@@ -219,4 +219,22 @@
}
}
+DisplayError ColorManagerProxy::ColorMgrGetNumOfModes(uint32_t *mode_cnt) {
+ return color_intf_->ColorIntfGetNumDisplayModes(&pp_features_, 0, mode_cnt);
+}
+
+DisplayError ColorManagerProxy::ColorMgrGetModes(uint32_t *mode_cnt,
+ SDEDisplayMode *modes) {
+ return color_intf_->ColorIntfEnumerateDisplayModes(&pp_features_, 0, modes, mode_cnt);
+}
+
+DisplayError ColorManagerProxy::ColorMgrSetMode(int32_t color_mode_id) {
+ return color_intf_->ColorIntfSetDisplayMode(&pp_features_, 0, color_mode_id);
+}
+
+DisplayError ColorManagerProxy::ColorMgrSetColorTransform(uint32_t length,
+ const double *trans_data) {
+ return color_intf_->ColorIntfSetColorTransform(&pp_features_, 0, length, trans_data);
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/color_manager.h b/sdm/libs/core/color_manager.h
index fb2bbf5..9f9eb40 100644
--- a/sdm/libs/core/color_manager.h
+++ b/sdm/libs/core/color_manager.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, The Linux Foundataion. All rights reserved.
+/* Copyright (c) 2015-2016, The Linux Foundataion. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -65,6 +65,10 @@
PPDisplayAPIPayload *out_payload,
PPPendingParams *pending_action);
DisplayError ApplyDefaultDisplayMode();
+ DisplayError ColorMgrGetNumOfModes(uint32_t *mode_cnt);
+ DisplayError ColorMgrGetModes(uint32_t *mode_cnt, SDEDisplayMode *modes);
+ DisplayError ColorMgrSetMode(int32_t color_mode_id);
+ DisplayError ColorMgrSetColorTransform(uint32_t length, const double *trans_data);
bool NeedsPartialUpdateDisable();
DisplayError Commit();
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 5523ff2..361ded8 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -28,6 +28,7 @@
#include <utils/formats.h>
#include <utils/rect.h>
+#include <string>
#include <vector>
#include "display_base.h"
@@ -111,6 +112,10 @@
rotator_intf_->UnregisterDisplay(display_rotator_ctx_);
}
+ if (color_modes_) {
+ delete[] color_modes_;
+ }
+
if (color_mgr_) {
delete color_mgr_;
color_mgr_ = NULL;
@@ -708,6 +713,105 @@
return kErrorParameters;
}
+DisplayError DisplayBase::GetColorModeCount(uint32_t *mode_count) {
+ if (!mode_count) {
+ return kErrorParameters;
+ }
+
+ if (!color_mgr_) {
+ return kErrorNotSupported;
+ }
+
+ DisplayError error = color_mgr_->ColorMgrGetNumOfModes(&num_color_modes_);
+ if (error != kErrorNone || !num_color_modes_) {
+ return kErrorNotSupported;
+ }
+
+ DLOGI("Number of color modes = %d", num_color_modes_);
+ *mode_count = num_color_modes_;
+
+ return kErrorNone;
+}
+
+DisplayError DisplayBase::GetColorModes(uint32_t *mode_count,
+ std::vector<std::string> *color_modes) {
+ if (!mode_count || !color_modes) {
+ return kErrorParameters;
+ }
+
+ if (!color_mgr_) {
+ return kErrorNotSupported;
+ }
+
+ if (color_modes_ == NULL) {
+ color_modes_ = new SDEDisplayMode[num_color_modes_];
+
+ DisplayError error = color_mgr_->ColorMgrGetModes(&num_color_modes_, color_modes_);
+ if (error != kErrorNone) {
+ DLOGE("Failed");
+ return error;
+ }
+ for (uint32_t i = 0; i < num_color_modes_; i++) {
+ DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
+ color_modes_[i].id);
+ color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
+ }
+ }
+
+ for (uint32_t i = 0; i < num_color_modes_; i++) {
+ DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
+ color_modes_[i].id);
+ color_modes->at(i) = color_modes_[i].name;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError DisplayBase::SetColorMode(const std::string &color_mode) {
+ if (!color_mgr_) {
+ return kErrorNotSupported;
+ }
+
+ DLOGV_IF(kTagQDCM, "Color Mode = %s", color_mode.c_str());
+
+ ColorModeMap::iterator it = color_mode_map_.find(color_mode);
+ if (it == color_mode_map_.end()) {
+ DLOGE("Failed: Unknown Mode : %s", color_mode.c_str());
+ return kErrorNotSupported;
+ }
+
+ SDEDisplayMode *sde_display_mode = it->second;
+ if (color_mode_ == sde_display_mode->id) {
+ DLOGV_IF(kTagQDCM, "Same mode requested");
+ return kErrorNone;
+ }
+
+ DLOGV_IF(kTagQDCM, "Color Mode Name = %s corresponding mode_id = %d", sde_display_mode->name,
+ sde_display_mode->id);
+ DisplayError error = kErrorNone;
+ error = color_mgr_->ColorMgrSetMode(sde_display_mode->id);
+ if (error != kErrorNone) {
+ DLOGE("Failed for mode id = %d", sde_display_mode->id);
+ return error;
+ }
+
+ color_mode_ = sde_display_mode->id;
+
+ return error;
+}
+
+DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) {
+ if (!color_mgr_) {
+ return kErrorNotSupported;
+ }
+
+ if (!color_transform) {
+ return kErrorParameters;
+ }
+
+ return color_mgr_->ColorMgrSetColorTransform(length, color_transform);
+}
+
DisplayError DisplayBase::ApplyDefaultDisplayMode() {
if (color_mgr_)
return color_mgr_->ApplyDefaultDisplayMode();
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 0f316fd..d771342 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -31,6 +31,10 @@
#include <private/color_interface.h>
#include <utils/locker.h>
+#include <map>
+#include <string>
+#include <vector>
+
#include "hw_interface.h"
#include "comp_manager.h"
#include "color_manager.h"
@@ -72,6 +76,10 @@
virtual DisplayError ColorSVCRequestRoute(const PPDisplayAPIPayload &in_payload,
PPDisplayAPIPayload *out_payload,
PPPendingParams *pending_action);
+ virtual DisplayError GetColorModeCount(uint32_t *mode_count);
+ virtual DisplayError GetColorModes(uint32_t *mode_count, std::vector<std::string> *color_modes);
+ virtual DisplayError SetColorMode(const std::string &color_mode);
+ virtual DisplayError SetColorTransform(const uint32_t length, const double *color_transform);
virtual DisplayError ApplyDefaultDisplayMode(void);
virtual DisplayError SetCursorPosition(int x, int y);
virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
@@ -122,6 +130,11 @@
bool partial_update_control_ = true;
HWEventsInterface *hw_events_intf_ = NULL;
bool disable_pu_one_frame_ = false;
+ uint32_t num_color_modes_ = 0;
+ SDEDisplayMode *color_modes_ = NULL;
+ int32_t color_mode_ = 0;
+ typedef std::map<std::string, SDEDisplayMode *> ColorModeMap;
+ ColorModeMap color_mode_map_ = {};
private:
// Unused
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index eb477d0..f687731 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -17,20 +17,23 @@
* limitations under the License.
*/
-#include <math.h>
+#include <cutils/properties.h>
#include <errno.h>
-#include <gralloc_priv.h>
#include <gr.h>
+#include <gralloc_priv.h>
+#include <math.h>
+#include <sync/sync.h>
#include <utils/constants.h>
+#include <utils/debug.h>
#include <utils/formats.h>
#include <utils/rect.h>
-#include <utils/debug.h>
-#include <sync/sync.h>
-#include <cutils/properties.h>
+
+#include <algorithm>
#include <map>
-#include <string>
#include <sstream>
+#include <string>
#include <utility>
+#include <vector>
#include "hwc_display.h"
#include "hwc_debugger.h"
@@ -53,6 +56,155 @@
}
}
+HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(display_intf) {}
+
+HWC2::Error HWCColorMode::Init() {
+ PopulateColorModes();
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCColorMode::DeInit() {
+ color_mode_transform_map_.clear();
+ return HWC2::Error::None;
+}
+
+uint32_t HWCColorMode::GetColorModeCount() {
+ uint32_t count = UINT32(color_mode_transform_map_.size());
+ DLOGI("Supported color mode count = %d", count);
+
+ return std::max(1U, count);
+}
+
+HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
+ int32_t /*android_color_mode_t*/ *out_modes) {
+ auto it = color_mode_transform_map_.begin();
+ for (auto i = 0; it != color_mode_transform_map_.end(); it++, i++) {
+ out_modes[i] = it->first;
+ DLOGI("Supports color mode[%d] = %d", i, it->first);
+ }
+ *out_num_modes = UINT32(color_mode_transform_map_.size());
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCColorMode::SetColorMode(int32_t /*android_color_mode_t*/ mode) {
+ // first mode in 2D matrix is the mode (identity)
+ auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
+ if (status != HWC2::Error::None) {
+ DLOGE("failed for mode = %d", mode);
+ }
+
+ return status;
+}
+
+HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
+ if (!matrix) {
+ return HWC2::Error::BadParameter;
+ }
+
+ double color_matrix[kColorTransformMatrixCount] = {0};
+ CopyColorTransformMatrix(matrix, color_matrix);
+
+ auto status = HandleColorModeTransform(current_color_mode_, hint, color_matrix);
+ if (status != HWC2::Error::None) {
+ DLOGE("failed for hint = %d", hint);
+ }
+
+ return status;
+}
+
+HWC2::Error HWCColorMode::HandleColorModeTransform(int32_t /*android_color_mode_t*/ mode,
+ android_color_transform_t hint,
+ const double *matrix) {
+ android_color_transform_t transform_hint = hint;
+ std::string color_mode_transform;
+ bool use_matrix = false;
+ if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) {
+ // if the mode + transfrom request from HWC matches one mode in SDM, set that
+ color_mode_transform = color_mode_transform_map_[mode][hint];
+ if (color_mode_transform.empty()) {
+ transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
+ use_matrix = true;
+ }
+ } else {
+ use_matrix = true;
+ transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
+ }
+
+ color_mode_transform = color_mode_transform_map_[mode][transform_hint];
+ DisplayError error = display_intf_->SetColorMode(color_mode_transform);
+ if (error != kErrorNone) {
+ DLOGE("Failed to set color_mode = %d transform_hint = %d", mode, hint);
+ // TODO(user): make use client composition
+ return HWC2::Error::Unsupported;
+ }
+
+ if (use_matrix) {
+ DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix);
+ if (error != kErrorNone) {
+ DLOGE("Failed to set Color Transform Matrix");
+ // TODO(user): make use client composition
+ return HWC2::Error::Unsupported;
+ }
+ }
+
+ current_color_mode_ = mode;
+ current_color_transform_ = hint;
+ CopyColorTransformMatrix(matrix, color_matrix_);
+ DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
+
+ return HWC2::Error::None;
+}
+
+void HWCColorMode::PopulateColorModes() {
+ uint32_t color_mode_count = 0;
+ // SDM returns modes which is string combination of mode + transform.
+ DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
+ if (error != kErrorNone || (color_mode_count == 0)) {
+ DLOGW("GetColorModeCount failed, use native color mode");
+ PopulateTransform(0, "native_identity");
+ return;
+ }
+
+ DLOGI("Color Modes supported count = %d", color_mode_count);
+
+ std::vector<std::string> color_modes(color_mode_count);
+ error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
+
+ for (uint32_t i = 0; i < color_mode_count; i++) {
+ std::string &mode_string = color_modes.at(i);
+ DLOGI("Color Mode[%d] = %s", i, mode_string.c_str());
+ if (mode_string.find("native") != std::string::npos) {
+ // TODO(user): replace numbers(0,1..) with android_color_mode_t
+ PopulateTransform(0, mode_string);
+ } else if (mode_string.find("srgb") != std::string::npos) {
+ PopulateTransform(1, mode_string);
+ } else if (mode_string.find("adobe") != std::string::npos) {
+ PopulateTransform(2, mode_string);
+ } else if (mode_string.find("dci3") != std::string::npos) {
+ PopulateTransform(3, mode_string);
+ }
+ }
+}
+
+void HWCColorMode::PopulateTransform(const int32_t &mode, const std::string &color_transform) {
+ // TODO(user): Check the substring from QDCM
+ if (color_transform.find("identity") != std::string::npos) {
+ color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_transform;
+ } else if (color_transform.find("artitrary") != std::string::npos) {
+ // no color mode for arbitrary
+ } else if (color_transform.find("inverse") != std::string::npos) {
+ color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_transform;
+ } else if (color_transform.find("grayscale") != std::string::npos) {
+ color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_GRAYSCALE] = color_transform;
+ } else if (color_transform.find("correct_protonopia") != std::string::npos) {
+ color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA] = color_transform;
+ } else if (color_transform.find("correct_deuteranopia") != std::string::npos) {
+ color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA] = color_transform;
+ } else if (color_transform.find("correct_tritanopia") != std::string::npos) {
+ color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA] = color_transform;
+ }
+}
+
HWCDisplay::HWCDisplay(CoreInterface *core_intf, HWCCallbacks *callbacks, DisplayType type,
hwc2_display_t id, bool needs_blit, qService::QService *qservice,
DisplayClass display_class)
@@ -124,6 +276,11 @@
blit_engine_ = NULL;
}
+ if (color_mode_) {
+ color_mode_->DeInit();
+ delete color_mode_;
+ }
+
return 0;
}
@@ -353,6 +510,15 @@
}
}
+HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, int32_t *out_modes) {
+ if (out_modes) {
+ out_modes[0] = 0; // TODO(user): Change to android_color_mode_t
+ }
+ *out_num_modes = 1;
+
+ return HWC2::Error::None;
+}
+
HWC2::Error HWCDisplay::GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs) {
// TODO(user): Actually handle multiple configs
if (out_configs == nullptr) {
@@ -361,6 +527,7 @@
*out_num_configs = 1;
out_configs[0] = 0;
}
+
return HWC2::Error::None;
}
@@ -1260,6 +1427,16 @@
}
}
+void HWCDisplay::MarkLayersForClientComposition() {
+ // ClientComposition - GPU comp, to acheive this, set skip flag so that
+ // SDM does not handle this layer and hwc_layer composition will be
+ // set correctly at the end of Prepare.
+ for (auto hwc_layer : layer_set_) {
+ Layer *layer = hwc_layer->GetSDMLayer();
+ layer->flags.skip = true;
+ }
+}
+
void HWCDisplay::ApplyScanAdjustment(hwc_rect_t *display_frame) {
}
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 51e7d13..c3ffcb4 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -20,16 +20,18 @@
#ifndef __HWC_DISPLAY_H__
#define __HWC_DISPLAY_H__
-#include <hardware/hwcomposer.h>
-#include <core/core_interface.h>
-#include <qdMetaData.h>
#include <QService.h>
+#include <core/core_interface.h>
+#include <hardware/hwcomposer.h>
#include <private/color_params.h>
+#include <qdMetaData.h>
#include <map>
+#include <queue>
#include <set>
#include <string>
-#include <queue>
#include <utility>
+#include <vector>
+
#include "hwc_callbacks.h"
#include "hwc_layers.h"
@@ -46,6 +48,40 @@
DISPLAY_CLASS_NULL
};
+class HWCColorMode {
+ public:
+ explicit HWCColorMode(DisplayInterface *display_intf);
+ ~HWCColorMode() {}
+ HWC2::Error Init();
+ HWC2::Error DeInit();
+ uint32_t GetColorModeCount();
+ HWC2::Error GetColorModes(uint32_t *out_num_modes, int32_t /*android_color_mode_t*/ *out_modes);
+ HWC2::Error SetColorMode(int32_t /*android_color_mode_t*/ mode);
+ HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
+
+ private:
+ static const uint32_t kColorTransformMatrixCount = 16;
+
+ HWC2::Error HandleColorModeTransform(int32_t /*android_color_mode_t*/ mode,
+ android_color_transform_t hint, const double *matrix);
+ void PopulateColorModes();
+ void PopulateTransform(const int32_t &mode, const std::string &color_mode);
+ template <class T>
+ void CopyColorTransformMatrix(const T *input_matrix, double *output_matrix) {
+ for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
+ output_matrix[i] = static_cast<double>(input_matrix[i]);
+ }
+ }
+
+ DisplayInterface *display_intf_ = NULL;
+ int32_t current_color_mode_ = 0; // android_color_mode_t
+ android_color_transform_t current_color_transform_ = HAL_COLOR_TRANSFORM_IDENTITY;
+ typedef std::map<android_color_transform_t, std::string> TransformMap;
+ // TODO(user): change int32_t to android_color_mode_t when defined
+ std::map<int32_t, TransformMap> color_mode_transform_map_ = {};
+ double color_matrix_[kColorTransformMatrixCount] = {0};
+};
+
class HWCDisplay : public DisplayEventHandler {
public:
virtual ~HWCDisplay() {}
@@ -101,11 +137,23 @@
virtual HWC2::Error SetActiveConfig(hwc2_config_t config);
virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
int32_t dataspace);
+ virtual HWC2::Error SetColorMode(int32_t /*android_color_mode_t*/ mode) {
+ return HWC2::Error::Unsupported;
+ }
+ virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint) {
+ return HWC2::Error::Unsupported;
+ }
+ virtual HWC2::Error HandleColorModeTransform(int32_t /*android_color_mode_t*/ mode,
+ android_color_transform_t hint,
+ const double *matrix) {
+ return HWC2::Error::Unsupported;
+ }
virtual HWC2::Error GetDisplayConfigs(uint32_t *out_num_configs, hwc2_config_t *out_configs);
virtual HWC2::Error GetDisplayAttribute(hwc2_config_t config, HWC2::Attribute attribute,
int32_t *out_value);
virtual HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
int32_t dataspace);
+ virtual HWC2::Error GetColorModes(uint32_t *outNumModes, int32_t *outModes);
virtual HWC2::Error GetChangedCompositionTypes(uint32_t *out_num_elements,
hwc2_layer_t *out_layers, int32_t *out_types);
virtual HWC2::Error GetDisplayRequests(int32_t *out_display_requests, uint32_t *out_num_elements,
@@ -150,6 +198,7 @@
const char *GetDisplayString();
void ScaleDisplayFrame(hwc_rect_t *display_frame);
void MarkLayersForGPUBypass(void);
+ void MarkLayersForClientComposition(void);
virtual void ApplyScanAdjustment(hwc_rect_t *display_frame);
bool NeedsFrameBufferRefresh(void);
bool SingleLayerUpdating(void);
@@ -197,6 +246,8 @@
uint32_t solid_fill_color_ = 0;
LayerRect display_rect_;
bool validated_ = false;
+ bool color_tranform_failed_ = false;
+ HWCColorMode *color_mode_ = NULL;
private:
bool IsFrameBufferScaled();
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index 40ac723..517959e 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -34,6 +34,10 @@
#include <stdarg.h>
#include <sys/mman.h>
+#include <map>
+#include <string>
+#include <vector>
+
#include "hwc_display_primary.h"
#include "hwc_debugger.h"
@@ -103,7 +107,13 @@
use_metadata_refresh_rate_ = false;
}
- return HWCDisplay::Init();
+ int status = HWCDisplay::Init();
+ if (status) {
+ return status;
+ }
+ color_mode_ = new HWCColorMode(display_intf_);
+
+ return INT(color_mode_->Init());
}
void HWCDisplayPrimary::ProcessBootAnimCompleted() {
@@ -153,6 +163,11 @@
return status;
}
+ if (color_tranform_failed_) {
+ // Must fall back to client composition
+ MarkLayersForClientComposition();
+ }
+
// Fill in the remaining blanks in the layers and add them to the SDM layerstack
BuildLayerStack();
@@ -213,6 +228,48 @@
return status;
}
+HWC2::Error HWCDisplayPrimary::GetColorModes(uint32_t *out_num_modes,
+ int32_t /*android_color_mode_t*/ *out_modes) {
+ if (out_modes == nullptr) {
+ *out_num_modes = color_mode_->GetColorModeCount();
+ } else {
+ color_mode_->GetColorModes(out_num_modes, out_modes);
+ }
+
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplayPrimary::SetColorMode(int32_t /*android_color_mode_t*/ mode) {
+ auto status = color_mode_->SetColorMode(mode);
+ if (status != HWC2::Error::None) {
+ DLOGE("failed for mode = %d", mode);
+ return status;
+ }
+
+ callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+
+ return status;
+}
+
+HWC2::Error HWCDisplayPrimary::SetColorTransform(const float *matrix,
+ android_color_transform_t hint) {
+ if (!matrix) {
+ return HWC2::Error::BadParameter;
+ }
+
+ auto status = color_mode_->SetColorTransform(matrix, hint);
+ if (status != HWC2::Error::None) {
+ DLOGE("failed for hint = %d", hint);
+ color_tranform_failed_ = true;
+ return status;
+ }
+
+ callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
+ color_tranform_failed_ = false;
+
+ return status;
+}
+
int HWCDisplayPrimary::Perform(uint32_t operation, ...) {
va_list args;
va_start(args, operation);
diff --git a/sdm/libs/hwc2/hwc_display_primary.h b/sdm/libs/hwc2/hwc_display_primary.h
index 2779f1b..62b311e 100644
--- a/sdm/libs/hwc2/hwc_display_primary.h
+++ b/sdm/libs/hwc2/hwc_display_primary.h
@@ -30,6 +30,8 @@
#ifndef __HWC_DISPLAY_PRIMARY_H__
#define __HWC_DISPLAY_PRIMARY_H__
+#include <string>
+
#include "cpuhint.h"
#include "hwc_display.h"
@@ -52,6 +54,9 @@
virtual int Init();
virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
virtual HWC2::Error Present(int32_t *out_retire_fence);
+ virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, int32_t *out_modes);
+ virtual HWC2::Error SetColorMode(int32_t /*android_color_mode_t*/ mode);
+ virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
virtual int Perform(uint32_t operation, ...);
virtual void SetSecureDisplay(bool secure_display_active);
virtual DisplayError Refresh();
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 66eeb1e..28e0206 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -307,7 +307,11 @@
width, height, format, dataspace);
}
-// TODO(user): GetColorModes
+static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
+ int32_t /*android_color_mode_t*/ *out_modes) {
+ return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetColorModes, out_num_modes,
+ out_modes);
+}
static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
hwc2_config_t config, int32_t int_attribute,
@@ -418,7 +422,20 @@
acquire_fence, dataspace);
}
-// TODO(user): SetColorMode, SetColorTransform
+int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
+ int32_t /*android_color_mode_t*/ mode) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
+}
+
+int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
+ const float *matrix,
+ int32_t /*android_color_transform_t*/ hint) {
+ SEQUENCE_WAIT_SCOPE_LOCK(locker_);
+ android_color_transform_t transform_hint = static_cast<android_color_transform_t>(hint);
+ return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorTransform, matrix,
+ transform_hint);
+}
static int32_t SetCursorPosition(hwc2_device_t *device, hwc2_display_t display, hwc2_layer_t layer,
int32_t x, int32_t y) {
@@ -583,8 +600,8 @@
return AsFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(GetChangedCompositionTypes);
case HWC2::FunctionDescriptor::GetClientTargetSupport:
return AsFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(GetClientTargetSupport);
- // case HWC2::FunctionDescriptor::GetColorModes:
- // TODO(user): Support later
+ case HWC2::FunctionDescriptor::GetColorModes:
+ return AsFP<HWC2_PFN_GET_COLOR_MODES>(GetColorModes);
case HWC2::FunctionDescriptor::GetDisplayAttribute:
return AsFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(GetDisplayAttribute);
case HWC2::FunctionDescriptor::GetDisplayConfigs:
@@ -611,10 +628,10 @@
return AsFP<HWC2_PFN_SET_ACTIVE_CONFIG>(SetActiveConfig);
case HWC2::FunctionDescriptor::SetClientTarget:
return AsFP<HWC2_PFN_SET_CLIENT_TARGET>(SetClientTarget);
- // TODO(user): Support later
- // case HWC2::FunctionDescriptor::SetColorMode:
- // case HWC2::FunctionDescriptor::SetColorTransform:
- // break;
+ case HWC2::FunctionDescriptor::SetColorMode:
+ return AsFP<HWC2_PFN_SET_COLOR_MODE>(SetColorMode);
+ case HWC2::FunctionDescriptor::SetColorTransform:
+ return AsFP<HWC2_PFN_SET_COLOR_TRANSFORM>(SetColorTransform);
case HWC2::FunctionDescriptor::SetCursorPosition:
return AsFP<HWC2_PFN_SET_CURSOR_POSITION>(SetCursorPosition);
case HWC2::FunctionDescriptor::SetLayerBlendMode:
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 679619c..a713ab0 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -101,6 +101,10 @@
static int32_t SetPowerMode(hwc2_device_t *device, hwc2_display_t display, int32_t int_mode);
static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_types, uint32_t *out_num_requests);
+ static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display,
+ int32_t /*android_color_mode_t*/ mode);
+ static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
+ const float *matrix, int32_t /*android_color_transform_t*/ hint);
private:
static const int kExternalConnectionTimeoutMs = 500;