Commit fe99bbd3 authored by Daniele Castagna's avatar Daniele Castagna Committed by Commit Bot

ozone: drm: Emulate per-CRTC color transform matrix

On some devices we don't have a per-CRTC color transform matrix,
but we do have a per-plane CTM that is currently not used.

This CL emulates a per-crtc CTM on those devices.

Bug: 749250
Test: Night light on RK3399
Change-Id: Id5135e00e72085b7890426dca7688d34cf6759f7
Reviewed-on: https://chromium-review.googlesource.com/1037403
Commit-Queue: Daniele Castagna <dcastagna@chromium.org>
Reviewed-by: default avatarAhmed Fakhry <afakhry@chromium.org>
Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Reviewed-by: default avatarDaniel Nicoara <dnicoara@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555571}
parent d6e03f2b
...@@ -193,16 +193,18 @@ int ConnectorIndex(int device_index, int display_index) { ...@@ -193,16 +193,18 @@ int ConnectorIndex(int device_index, int display_index) {
return ((device_index << 4) + display_index) & 0xFF; return ((device_index << 4) + display_index) & 0xFF;
} }
bool HasColorCorrectionMatrix(int fd, drmModeCrtc* crtc) { bool HasPerPlaneColorCorrectionMatrix(const int fd, drmModeCrtc* crtc) {
ScopedDrmObjectPropertyPtr crtc_props( ScopedDrmPlaneResPtr plane_resources(drmModeGetPlaneResources(fd));
drmModeObjectGetProperties(fd, crtc->crtc_id, DRM_MODE_OBJECT_CRTC)); DCHECK(plane_resources);
for (uint32_t i = 0; i < plane_resources->count_planes; ++i) {
for (uint32_t i = 0; i < crtc_props->count_props; ++i) { ScopedDrmObjectPropertyPtr plane_props(drmModeObjectGetProperties(
ScopedDrmPropertyPtr property(drmModeGetProperty(fd, crtc_props->props[i])); fd, plane_resources->planes[i], DRM_MODE_OBJECT_PLANE));
if (property && !strcmp(property->name, "CTM")) DCHECK(plane_props);
return true;
if (!FindDrmProperty(fd, plane_props.get(), "PLANE_CTM"))
return false;
} }
return false; return true;
} }
bool AreDisplayModesEqual(const DisplayMode_Params& lhs, bool AreDisplayModesEqual(const DisplayMode_Params& lhs,
...@@ -213,6 +215,23 @@ bool AreDisplayModesEqual(const DisplayMode_Params& lhs, ...@@ -213,6 +215,23 @@ bool AreDisplayModesEqual(const DisplayMode_Params& lhs,
} // namespace } // namespace
ScopedDrmPropertyPtr FindDrmProperty(int fd,
drmModeObjectProperties* properties,
const char* name) {
for (uint32_t i = 0; i < properties->count_props; ++i) {
ScopedDrmPropertyPtr property(drmModeGetProperty(fd, properties->props[i]));
if (property && !strcmp(property->name, name))
return property;
}
return nullptr;
}
bool HasColorCorrectionMatrix(int fd, drmModeCrtc* crtc) {
ScopedDrmObjectPropertyPtr crtc_props(
drmModeObjectGetProperties(fd, crtc->crtc_id, DRM_MODE_OBJECT_CRTC));
return !!FindDrmProperty(fd, crtc_props.get(), "CTM");
}
DisplayMode_Params GetDisplayModeParams(const display::DisplayMode& mode) { DisplayMode_Params GetDisplayModeParams(const display::DisplayMode& mode) {
DisplayMode_Params params; DisplayMode_Params params;
params.size = mode.size(); params.size = mode.size();
...@@ -396,7 +415,8 @@ std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshot( ...@@ -396,7 +415,8 @@ std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshot(
const bool is_aspect_preserving_scaling = const bool is_aspect_preserving_scaling =
IsAspectPreserving(fd, info->connector()); IsAspectPreserving(fd, info->connector());
const bool has_color_correction_matrix = const bool has_color_correction_matrix =
HasColorCorrectionMatrix(fd, info->crtc()); HasColorCorrectionMatrix(fd, info->crtc()) ||
HasPerPlaneColorCorrectionMatrix(fd, info->crtc());
const gfx::Size maximum_cursor_size = GetMaximumCursorSize(fd); const gfx::Size maximum_cursor_size = GetMaximumCursorSize(fd);
std::string display_name; std::string display_name;
......
...@@ -106,6 +106,12 @@ int GetFourCCFormatForOpaqueFramebuffer(gfx::BufferFormat format); ...@@ -106,6 +106,12 @@ int GetFourCCFormatForOpaqueFramebuffer(gfx::BufferFormat format);
gfx::Size GetMaximumCursorSize(int fd); gfx::Size GetMaximumCursorSize(int fd);
ScopedDrmPropertyPtr FindDrmProperty(int fd,
drmModeObjectProperties* properties,
const char* name);
bool HasColorCorrectionMatrix(int fd, drmModeCrtc* crtc);
DisplayMode_Params GetDisplayModeParams(const display::DisplayMode& mode); DisplayMode_Params GetDisplayModeParams(const display::DisplayMode& mode);
std::unique_ptr<display::DisplayMode> CreateDisplayModeFromParams( std::unique_ptr<display::DisplayMode> CreateDisplayModeFromParams(
......
...@@ -55,4 +55,11 @@ void DrmFramebufferDeleter::operator()(drmModeFB* framebuffer) const { ...@@ -55,4 +55,11 @@ void DrmFramebufferDeleter::operator()(drmModeFB* framebuffer) const {
drmModeFreeFB(framebuffer); drmModeFreeFB(framebuffer);
} }
ScopedDrmPropertyBlob::ScopedDrmPropertyBlob(int fd, uint32_t blob_id)
: fd(fd), blob_id(blob_id) {}
ScopedDrmPropertyBlob::~ScopedDrmPropertyBlob() {
drmModeDestroyPropertyBlob(fd, blob_id);
}
} // namespace ui } // namespace ui
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <memory> #include <memory>
#include "base/memory/free_deleter.h"
typedef struct _drmModeConnector drmModeConnector; typedef struct _drmModeConnector drmModeConnector;
typedef struct _drmModeCrtc drmModeCrtc; typedef struct _drmModeCrtc drmModeCrtc;
typedef struct _drmModeEncoder drmModeEncoder; typedef struct _drmModeEncoder drmModeEncoder;
...@@ -18,6 +20,8 @@ typedef struct _drmModeProperty drmModePropertyRes; ...@@ -18,6 +20,8 @@ typedef struct _drmModeProperty drmModePropertyRes;
typedef struct _drmModeAtomicReq drmModeAtomicReq; typedef struct _drmModeAtomicReq drmModeAtomicReq;
typedef struct _drmModePropertyBlob drmModePropertyBlobRes; typedef struct _drmModePropertyBlob drmModePropertyBlobRes;
typedef struct _drmModeRes drmModeRes; typedef struct _drmModeRes drmModeRes;
typedef struct drm_color_lut drm_color_lut;
typedef struct drm_color_ctm drm_color_ctm;
namespace ui { namespace ui {
...@@ -74,6 +78,16 @@ typedef std::unique_ptr<drmModePropertyBlobRes, DrmPropertyBlobDeleter> ...@@ -74,6 +78,16 @@ typedef std::unique_ptr<drmModePropertyBlobRes, DrmPropertyBlobDeleter>
typedef std::unique_ptr<drmModeFB, DrmFramebufferDeleter> typedef std::unique_ptr<drmModeFB, DrmFramebufferDeleter>
ScopedDrmFramebufferPtr; ScopedDrmFramebufferPtr;
struct ScopedDrmPropertyBlob {
ScopedDrmPropertyBlob(int fd, uint32_t blob_id);
~ScopedDrmPropertyBlob();
int fd;
uint32_t blob_id;
};
typedef std::unique_ptr<drm_color_lut, base::FreeDeleter> ScopedDrmColorLutPtr;
typedef std::unique_ptr<drm_color_ctm, base::FreeDeleter> ScopedDrmColorCtmPtr;
} // namespace ui } // namespace ui
#endif // UI_OZONE_PLATFORM_DRM_COMMON_SCOPED_DRM_TYPES_H_ #endif // UI_OZONE_PLATFORM_DRM_COMMON_SCOPED_DRM_TYPES_H_
...@@ -132,8 +132,6 @@ bool CanQueryForResources(int fd) { ...@@ -132,8 +132,6 @@ bool CanQueryForResources(int fd) {
return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources); return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources);
} }
using ScopedDrmColorLutPtr = std::unique_ptr<drm_color_lut, base::FreeDeleter>;
using ScopedDrmColorCtmPtr = std::unique_ptr<drm_color_ctm, base::FreeDeleter>;
ScopedDrmColorLutPtr CreateLutBlob( ScopedDrmColorLutPtr CreateLutBlob(
const std::vector<display::GammaRampRGBEntry>& source) { const std::vector<display::GammaRampRGBEntry>& source) {
...@@ -694,13 +692,25 @@ bool DrmDevice::SetColorCorrection( ...@@ -694,13 +692,25 @@ bool DrmDevice::SetColorCorrection(
const std::vector<display::GammaRampRGBEntry>& degamma_lut, const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut, const std::vector<display::GammaRampRGBEntry>& gamma_lut,
const std::vector<float>& correction_matrix) { const std::vector<float>& correction_matrix) {
const bool should_set_gamma_properties =
!degamma_lut.empty() || !gamma_lut.empty();
ScopedDrmCrtcPtr crtc(drmModeGetCrtc(file_.GetPlatformFile(), crtc_id));
// TODO(dcastagna): Precompute and cache the return value of
// HasColorCorrectionMatrix when we initialize DrmDevice.
// We currently assume that if a per-CRTC CTM is not available, per-plane
// CTMs will be. We can make this more explicit once we address this TODO.
if (!HasColorCorrectionMatrix(file_.GetPlatformFile(), crtc.get()) &&
!should_set_gamma_properties) {
return plane_manager_->SetColorCorrectionOnAllCrtcPlanes(
crtc_id, CreateCTMBlob(correction_matrix));
}
ScopedDrmObjectPropertyPtr crtc_props(drmModeObjectGetProperties( ScopedDrmObjectPropertyPtr crtc_props(drmModeObjectGetProperties(
file_.GetPlatformFile(), crtc_id, DRM_MODE_OBJECT_CRTC)); file_.GetPlatformFile(), crtc_id, DRM_MODE_OBJECT_CRTC));
// Extract only the needed properties. // Extract only the needed properties.
int max_num_properties_expected = 1; int max_num_properties_expected = 1;
const bool should_set_gamma_properties =
!degamma_lut.empty() || !gamma_lut.empty();
if (should_set_gamma_properties) if (should_set_gamma_properties)
max_num_properties_expected += 4; max_num_properties_expected += 4;
......
...@@ -93,6 +93,12 @@ class HardwareDisplayPlaneManager { ...@@ -93,6 +93,12 @@ class HardwareDisplayPlaneManager {
// plane_list->old_plane_list. // plane_list->old_plane_list.
virtual bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) = 0; virtual bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) = 0;
// Set the drm_color_ctm contained in |ctm_blob_data| to all planes' KMS
// states
virtual bool SetColorCorrectionOnAllCrtcPlanes(
uint32_t crtc_id,
ScopedDrmColorCtmPtr ctm_blob_data) = 0;
// Check that the primary plane is valid for this // Check that the primary plane is valid for this
// PlaneManager. Specifically, legacy can't support primary planes // PlaneManager. Specifically, legacy can't support primary planes
// that don't have the same size as the current mode of the crtc. // that don't have the same size as the current mode of the crtc.
......
...@@ -4,10 +4,14 @@ ...@@ -4,10 +4,14 @@
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h"
#include <xf86drm.h>
#include <xf86drmMode.h>
#include "base/bind.h" #include "base/bind.h"
#include "base/files/platform_file.h" #include "base/files/platform_file.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h" #include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h" #include "ui/ozone/platform/drm/gpu/drm_device.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h"
...@@ -118,6 +122,50 @@ bool HardwareDisplayPlaneManagerAtomic::DisableOverlayPlanes( ...@@ -118,6 +122,50 @@ bool HardwareDisplayPlaneManagerAtomic::DisableOverlayPlanes(
return ret; return ret;
} }
bool HardwareDisplayPlaneManagerAtomic::SetColorCorrectionOnAllCrtcPlanes(
uint32_t crtc_id,
ScopedDrmColorCtmPtr ctm_blob_data) {
ScopedDrmAtomicReqPtr property_set(drmModeAtomicAlloc());
uint32_t blob_id = 0;
int fd = drm_->get_fd();
int ret = drmModeCreatePropertyBlob(fd, ctm_blob_data.get(),
sizeof(drm_color_ctm), &blob_id);
DCHECK(!ret && blob_id);
ScopedDrmPropertyBlob property_blob(fd, blob_id);
const int crtc_index = LookupCrtcIndex(crtc_id);
DCHECK_GE(crtc_index, 0);
const int crtc_bit = 1 << crtc_index;
ScopedDrmPlaneResPtr plane_resources(drmModeGetPlaneResources(fd));
DCHECK(plane_resources);
bool all_planes_ctm = true;
for (uint32_t i = 0; i < plane_resources->count_planes; ++i) {
ScopedDrmPlanePtr drm_plane(
drmModeGetPlane(fd, plane_resources->planes[i]));
DCHECK(drm_plane);
// This assumes planes can belong only to one crtc.
if (!(drm_plane->possible_crtcs & crtc_bit))
continue;
ScopedDrmObjectPropertyPtr plane_props(drmModeObjectGetProperties(
fd, plane_resources->planes[i], DRM_MODE_OBJECT_PLANE));
DCHECK(plane_props);
ScopedDrmPropertyPtr property(
FindDrmProperty(fd, plane_props.get(), "PLANE_CTM"));
if (property) {
int ret = drmModeAtomicAddProperty(
property_set.get(), plane_resources->planes[i], property->prop_id,
property_blob.blob_id);
LOG_IF(ERROR, ret < 0) << "Failed to set PLANE_CTM property.";
}
all_planes_ctm = all_planes_ctm && property;
}
drm_->CommitProperties(property_set.get(), DRM_MODE_ATOMIC_NONBLOCK, 0,
DrmDevice::PageFlipCallback());
return all_planes_ctm;
}
bool HardwareDisplayPlaneManagerAtomic::ValidatePrimarySize( bool HardwareDisplayPlaneManagerAtomic::ValidatePrimarySize(
const OverlayPlane& primary, const OverlayPlane& primary,
const drmModeModeInfo& mode) { const drmModeModeInfo& mode) {
......
...@@ -22,6 +22,10 @@ class HardwareDisplayPlaneManagerAtomic : public HardwareDisplayPlaneManager { ...@@ -22,6 +22,10 @@ class HardwareDisplayPlaneManagerAtomic : public HardwareDisplayPlaneManager {
bool test_only) override; bool test_only) override;
bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override; bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override;
bool SetColorCorrectionOnAllCrtcPlanes(
uint32_t crtc_id,
ScopedDrmColorCtmPtr ctm_blob_data) override;
bool ValidatePrimarySize(const OverlayPlane& primary, bool ValidatePrimarySize(const OverlayPlane& primary,
const drmModeModeInfo& mode) override; const drmModeModeInfo& mode) override;
......
...@@ -131,6 +131,14 @@ bool HardwareDisplayPlaneManagerLegacy::DisableOverlayPlanes( ...@@ -131,6 +131,14 @@ bool HardwareDisplayPlaneManagerLegacy::DisableOverlayPlanes(
return true; return true;
} }
bool HardwareDisplayPlaneManagerLegacy::SetColorCorrectionOnAllCrtcPlanes(
uint32_t crtc_id,
ScopedDrmColorCtmPtr ctm_blob_data) {
NOTREACHED()
<< "HardwareDisplayPlaneManagerLegacy doesn't support per plane CTM";
return false;
}
bool HardwareDisplayPlaneManagerLegacy::ValidatePrimarySize( bool HardwareDisplayPlaneManagerLegacy::ValidatePrimarySize(
const OverlayPlane& primary, const OverlayPlane& primary,
const drmModeModeInfo& mode) { const drmModeModeInfo& mode) {
......
...@@ -22,6 +22,10 @@ class HardwareDisplayPlaneManagerLegacy : public HardwareDisplayPlaneManager { ...@@ -22,6 +22,10 @@ class HardwareDisplayPlaneManagerLegacy : public HardwareDisplayPlaneManager {
bool test_only) override; bool test_only) override;
bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override; bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override;
bool SetColorCorrectionOnAllCrtcPlanes(
uint32_t crtc_id,
ScopedDrmColorCtmPtr ctm_blob_data) override;
bool ValidatePrimarySize(const OverlayPlane& primary, bool ValidatePrimarySize(const OverlayPlane& primary,
const drmModeModeInfo& mode) override; const drmModeModeInfo& mode) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment