Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Color diff #58

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .ci/android_headers/hardware/hwcomposer2.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ typedef enum {
HWC2_FUNCTION_SET_CLIENT_TARGET,
HWC2_FUNCTION_SET_COLOR_MODE,
HWC2_FUNCTION_SET_COLOR_TRANSFORM,
HWC2_FUNCTION_SET_COLOR_TRANSFORM_CORRECTION,
HWC2_FUNCTION_SET_CURSOR_POSITION,
HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
HWC2_FUNCTION_SET_LAYER_BUFFER,
Expand Down Expand Up @@ -625,6 +626,8 @@ static inline const char* getFunctionDescriptorName(
case HWC2_FUNCTION_SET_CLIENT_TARGET: return "SetClientTarget";
case HWC2_FUNCTION_SET_COLOR_MODE: return "SetColorMode";
case HWC2_FUNCTION_SET_COLOR_TRANSFORM: return "SetColorTransform";
case HWC2_FUNCTION_SET_COLOR_TRANSFORM_CORRECTION:
return "SetColorTransformCorrection";
case HWC2_FUNCTION_SET_CURSOR_POSITION: return "SetCursorPosition";
case HWC2_FUNCTION_SET_LAYER_BLEND_MODE: return "SetLayerBlendMode";
case HWC2_FUNCTION_SET_LAYER_BUFFER: return "SetLayerBuffer";
Expand Down Expand Up @@ -910,6 +913,7 @@ enum class FunctionDescriptor : int32_t {
SetClientTarget = HWC2_FUNCTION_SET_CLIENT_TARGET,
SetColorMode = HWC2_FUNCTION_SET_COLOR_MODE,
SetColorTransform = HWC2_FUNCTION_SET_COLOR_TRANSFORM,
SetColorTransformCorrection = HWC2_FUNCTION_SET_COLOR_TRANSFORM_CORRECTION,
SetCursorPosition = HWC2_FUNCTION_SET_CURSOR_POSITION,
SetLayerBlendMode = HWC2_FUNCTION_SET_LAYER_BLEND_MODE,
SetLayerBuffer = HWC2_FUNCTION_SET_LAYER_BUFFER,
Expand Down Expand Up @@ -2011,6 +2015,32 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_COLOR_TRANSFORM)(
hwc2_device_t* device, hwc2_display_t display, const float* matrix,
int32_t /*android_color_transform_t*/ hint);

/* setColorTransformCorrection(..., contrast, luminance)
* Descriptor: HWC2_FUNCTION_SET_COLOR_TRANSFORM
* Must be provided by all HWC2 devices
*
* Sets a color transform which will be applied after composition.
*
* If the device is not capable of using the value to apply
* the desired color transform, it should force all layers to client composition
* during validateDisplay.
*
* If HWC2_CAPABILITY_SKIP_CLIENT_COLOR_TRANSFORM is present, then the client
* will never apply the color transform during client composition, even if all
* layers are being composed by the client.
*
* Parameters:
* contrast - an integer representing the transform contrast
* luminance - an integer representing the transform luminance
*
* Returns HWC2_ERROR_NONE or one of the following errors:
* HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in
* HWC2_ERROR_BAD_PARAMETER - hint is not a valid color transform hint
*/
typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_COLOR_TRANSFORM_CORRECTION)(
hwc2_device_t* device, hwc2_display_t display, int32_t contrast,
int32_t luminance);

/* getPerFrameMetadataKeys(..., outKeys)
* Descriptor: HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS
* Optional for HWC2 devices
Expand Down
4 changes: 4 additions & 0 deletions drm/DrmAtomicStateManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int {

bool nonblock = true;

if (args.commit_block == true) {
nonblock = false;
}

if (args.active) {
nonblock = false;
new_frame_state.crtc_active_state = *args.active;
Expand Down
4 changes: 3 additions & 1 deletion drm/DrmAtomicStateManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <sstream>
#include <tuple>

#include <system/graphics.h>
#include "compositor/DrmKmsPlan.h"
#include "compositor/LayerData.h"
#include "drm/DrmPlane.h"
Expand All @@ -40,7 +41,8 @@ struct AtomicCommitArgs {
std::optional<DrmMode> display_mode;
std::optional<bool> active;
std::shared_ptr<DrmKmsPlan> composition;
bool color_adjustment = false;
int32_t color_adjustment = 0;
bool commit_block = false;

/* out */
UniqueFd out_fence;
Expand Down
34 changes: 16 additions & 18 deletions drm/DrmCrtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,22 @@ auto DrmCrtc::CreateInstance(DrmDevice &dev, uint32_t crtc_id, uint32_t index)
return {};
}

if (dev.GetColorAdjustmentEnabling()) {
ret = GetCrtcProperty(dev, *c, "CTM", &c->ctm_property_);
if (ret != 0) {
ALOGE("Failed to get CTM property");
return {};
}

ret = GetCrtcProperty(dev, *c, "GAMMA_LUT", &c->gamma_lut_property_);
if (ret != 0) {
ALOGE("Failed to get GAMMA_LUT property");
return {};
}

ret = GetCrtcProperty(dev, *c, "GAMMA_LUT_SIZE", &c->gamma_lut_size_property_);
if (ret != 0) {
ALOGE("Failed to get GAMMA_LUT_SIZE property");
return {};
}
ret = GetCrtcProperty(dev, *c, "CTM", &c->ctm_property_);
if (ret != 0) {
ALOGE("Failed to get CTM property");
return {};
}

ret = GetCrtcProperty(dev, *c, "GAMMA_LUT", &c->gamma_lut_property_);
if (ret != 0) {
ALOGE("Failed to get GAMMA_LUT property");
return {};
}

ret = GetCrtcProperty(dev, *c, "GAMMA_LUT_SIZE", &c->gamma_lut_size_property_);
if (ret != 0) {
ALOGE("Failed to get GAMMA_LUT_SIZE property");
return {};
}

return c;
Expand Down
9 changes: 7 additions & 2 deletions drm/DrmDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,16 @@ auto DrmDevice::Init(const char *path) -> int {
res->min_height);
max_resolution_ = std::pair<uint32_t, uint32_t>(res->max_width,
res->max_height);
commit_block_enabling_ = false;
memset(property, 0 , PROPERTY_VALUE_MAX);
property_get("vendor.hwcomposer.commit.mode.block", property, "0");
commit_block_enabling_ = atoi(property) != 0 ? true : false;
ALOGD("The property 'vendor.hwcomposer.commit.mode.block' value is %d", commit_block_enabling_);

color_adjustment_enabling_ = false;
color_adjustment_enabling_ = 0;
memset(property, 0 , PROPERTY_VALUE_MAX);
property_get("vendor.hwcomposer.color.adjustment.enabling", property, "0");
color_adjustment_enabling_ = atoi(property) != 0 ? true : false;
color_adjustment_enabling_ = atoi(property) < 0 ? 0 : atoi(property);
ALOGD("COLOR_ The property 'vendor.hwcomposer.color.adjustment.enabling' value is %d", color_adjustment_enabling_);

for (int i = 0; i < res->count_crtcs; ++i) {
Expand Down
6 changes: 5 additions & 1 deletion drm/DrmDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class DrmDevice {
return max_resolution_;
}

auto GetCommitModeBlockEnabling() const {
return commit_block_enabling_;
}
auto GetColorAdjustmentEnabling() const {
return color_adjustment_enabling_;
}
Expand Down Expand Up @@ -135,7 +138,8 @@ class DrmDevice {
bool preferred_mode_limit_;
bool planes_enabling_;
uint32_t planes_num_;
bool color_adjustment_enabling_;
int32_t color_adjustment_enabling_;
bool commit_block_enabling_;
};
} // namespace android

Expand Down
59 changes: 59 additions & 0 deletions hwc2_device/HwcDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ void HwcDisplay::Deinit() {
a_args.active = false;
a_args.composition = std::make_shared<DrmKmsPlan>();
a_args.color_adjustment = GetPipe().device->GetColorAdjustmentEnabling();
a_args.commit_block = GetPipe().device->GetCommitModeBlockEnabling();

GetPipe().atomic_state_manager->ExecuteAtomicCommit(a_args);

Expand All @@ -132,6 +133,14 @@ void HwcDisplay::Deinit() {
SetClientTarget(nullptr, -1, 0, {});
}

int64_t HwcDisplay::FloatToFixedPoint(float value) const {
uint32_t *pointer = (uint32_t *)&value;
uint32_t negative = (*pointer & (1u << 31)) >> 31;
*pointer &= 0x7fffffff; /* abs of value*/
return (negative ? (1ll << 63) : 0) |
(__s64)((*(float *)pointer) * (double)(1ll << 32));
}

HWC2::Error HwcDisplay::Init() {
ChosePreferredConfig();

Expand Down Expand Up @@ -531,6 +540,7 @@ HWC2::Error HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) {
}

a_args.color_adjustment = GetPipe().device->GetColorAdjustmentEnabling();
a_args.commit_block = GetPipe().device->GetCommitModeBlockEnabling();

// order the layers by z-order
bool use_client_layer = false;
Expand Down Expand Up @@ -726,6 +736,54 @@ HWC2::Error HwcDisplay::SetColorTransform(const float *matrix, int32_t hint) {
if (color_transform_hint_ == HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX)
std::copy(matrix, matrix + MATRIX_SIZE, color_transform_matrix_.begin());

struct drm_color_ctm *ctm =
(struct drm_color_ctm *)malloc(sizeof(struct drm_color_ctm));
if (!ctm) {
ALOGE("Cannot allocate CTM memory");
return HWC2::Error::BadParameter;
}

memset(ctm->matrix, 0, sizeof(ctm->matrix));

for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
ctm->matrix[i * 3 + j] =
FloatToFixedPoint(matrix[j * 4 + i]);
}
}

GetPipe().atomic_state_manager->ApplyPendingCTM(ctm);

free(ctm);
return HWC2::Error::None;
}

HWC2::Error HwcDisplay::SetColorTransformCorrection(int32_t contrast, int32_t luminance) {
uint32_t new_contrast = 0x808080;
if (contrast < 0 || contrast > 255) {
new_contrast = 0x80;
} else {
new_contrast = contrast & 0xFF;
}

new_contrast = ((new_contrast << 16) |
(new_contrast << 8) |
(new_contrast));

uint32_t new_luminance = 0x808080;
if (luminance < 0 || luminance > 256) {
new_luminance = 0x80;
} else {
new_luminance = luminance & 0xFF;
}

new_luminance = ((new_luminance << 16) |
(new_luminance << 8) |
(new_luminance));

struct gamma_colors gamma = {1.0, 1.0, 1.0};

GetPipe().atomic_state_manager->SetColorCorrection(gamma, new_contrast, new_luminance);
return HWC2::Error::None;
}

Expand All @@ -747,6 +805,7 @@ HWC2::Error HwcDisplay::SetPowerMode(int32_t mode_in) {
case HWC2::PowerMode::On:
a_args.active = true;
a_args.color_adjustment = GetPipe().device->GetColorAdjustmentEnabling();
a_args.commit_block = GetPipe().device->GetCommitModeBlockEnabling();
break;
case HWC2::PowerMode::Doze:
case HWC2::PowerMode::DozeSuspend:
Expand Down
3 changes: 3 additions & 0 deletions hwc2_device/HwcDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class HwcDisplay {

void ClearDisplay();

int64_t FloatToFixedPoint(float value) const;

std::string Dump();

// HWC Hooks
Expand Down Expand Up @@ -114,6 +116,7 @@ class HwcDisplay {
int32_t dataspace, hwc_region_t damage);
HWC2::Error SetColorMode(int32_t mode);
HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
HWC2::Error SetColorTransformCorrection(int32_t contrast, int32_t luminance);
HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence);
HWC2::Error SetPowerMode(int32_t mode);
HWC2::Error SetVsyncEnabled(int32_t enabled);
Expand Down
4 changes: 4 additions & 0 deletions hwc2_device/hwc2_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>(
DisplayHook<decltype(&HwcDisplay::SetColorTransform),
&HwcDisplay::SetColorTransform, const float *, int32_t>);
case HWC2::FunctionDescriptor::SetColorTransformCorrection:
return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM_CORRECTION>(
DisplayHook<decltype(&HwcDisplay::SetColorTransformCorrection),
&HwcDisplay::SetColorTransformCorrection, int32_t, int32_t>);
case HWC2::FunctionDescriptor::SetOutputBuffer:
return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>(
DisplayHook<decltype(&HwcDisplay::SetOutputBuffer),
Expand Down
Loading