Bug 455720

Summary: Night Light broken on ARM devices (Missing Color Transform Matrix support)
Product: [Plasma] kwin Reporter: Leonard Lausen <leonard>
Component: platform-drmAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: leonard, m.kurz, nate, xaver.hugl
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In: 5.27.3

Description Leonard Lausen 2022-06-21 13:39:01 UTC
Night Light is currently broken on ARM devices such as Acer Spin 513 Chromebook with Qualcomm Snapdragon 7c [1], as it relies on legacy GAMMA_LUT which is not supported by the Qualcomm SoCs.

Instead of relying on GAMMA_LUT, these SoCs implement Color Transform Matrix (CTM), which for example Chrome OS uses to implement their version of night light. Both GAMMA_LUT and TM are configured through the KMS CRTC Abstraction [2].

From IRC #aarch64-laptops:

> robclark | leezu: on CrOS we use display CTM (CRTC property) on internal display.. one could also use the GPU for that.. not sure off the top of my head what different de's support  
> robclark | leezu: yes, that is correct.. GAMMA_LUT is not supported, CTM (color transform matrix) is the way to achieve color transform  
> robclark | not supported in hw.. CTM is a more general purpose feature  
> robclark | GAMMA_LUT is kinda the legacy way, CTM is the new hotness ;-)

It would be great to support Night Light on ARM Laptops by implementing Night Light via Color Transform Matrix instead of GAMMA_LUT.


drm_info output showing lack of GAMMA_LUT support:

Node: /dev/dri/card1
├───Driver: msm (MSM Snapdragon DRM) version 1.9.0 (20130625)
│   ├───DRM_CLIENT_CAP_STEREO_3D supported
│   ├───DRM_CLIENT_CAP_UNIVERSAL_PLANES supported
│   ├───DRM_CLIENT_CAP_ATOMIC supported
│   ├───DRM_CLIENT_CAP_ASPECT_RATIO supported
│   ├───DRM_CLIENT_CAP_WRITEBACK_CONNECTORS supported
│   ├───DRM_CAP_DUMB_BUFFER = 1
│   ├───DRM_CAP_VBLANK_HIGH_CRTC = 1
│   ├───DRM_CAP_DUMB_PREFERRED_DEPTH = 0
│   ├───DRM_CAP_DUMB_PREFER_SHADOW = 0
│   ├───DRM_CAP_PRIME = 3
│   ├───DRM_CAP_TIMESTAMP_MONOTONIC = 1
│   ├───DRM_CAP_ASYNC_PAGE_FLIP = 0
│   ├───DRM_CAP_CURSOR_WIDTH = 64
│   ├───DRM_CAP_CURSOR_HEIGHT = 64
│   ├───DRM_CAP_ADDFB2_MODIFIERS = 1
│   ├───DRM_CAP_PAGE_FLIP_TARGET = 0
│   ├───DRM_CAP_CRTC_IN_VBLANK_EVENT = 1
│   ├───DRM_CAP_SYNCOBJ = 1
│   └───DRM_CAP_SYNCOBJ_TIMELINE = 0
├───Device: platform qcom,sc7180-mdss
│   └───Available nodes: primary, render
├───Framebuffer size
│   ├───Width: [0, 5120]
│   └───Height: [0, 4096]
├───Connectors
│   ├───Connector 0
│   │   ├───Object ID: 32
│   │   ├───Type: eDP
│   │   ├───Status: connected
│   │   ├───Physical size: 294x165 mm
│   │   ├───Subpixel: unknown
│   │   ├───Encoders: {0}
│   │   ├───Modes
│   │   │   └───1920x1080@60.00 preferred driver phsync nvsync 
│   │   └───Properties
│   │       ├───"EDID" (immutable): blob = 61
│   │       ├───"DPMS": enum {On, Standby, Suspend, Off} = On
│   │       ├───"link-status": enum {Good, Bad} = Good
│   │       ├───"non-desktop" (immutable): range [0, 1] = 0
│   │       ├───"TILE" (immutable): blob = 0
│   │       └───"CRTC_ID" (atomic): object CRTC = 59
│   └───Connector 1
│       ├───Object ID: 34
│       ├───Type: DisplayPort
│       ├───Status: disconnected
│       ├───Encoders: {1}
│       └───Properties
│           ├───"EDID" (immutable): blob = 0
│           ├───"DPMS": enum {On, Standby, Suspend, Off} = On
│           ├───"link-status": enum {Good, Bad} = Good
│           ├───"non-desktop" (immutable): range [0, 1] = 0
│           ├───"TILE" (immutable): blob = 0
│           └───"CRTC_ID" (atomic): object CRTC = 0
├───Encoders
│   ├───Encoder 0
│   │   ├───Object ID: 31
│   │   ├───Type: DSI
│   │   ├───CRTCS: {0, 1}
│   │   └───Clones: {0}
│   └───Encoder 1
│       ├───Object ID: 33
│       ├───Type: TMDS
│       ├───CRTCS: {0, 1}
│       └───Clones: {1}
├───CRTCs
│   ├───CRTC 0
│   │   ├───Object ID: 59
│   │   ├───Legacy info
│   │   │   ├───Mode: 1920x1080@60.00 preferred driver phsync nvsync 
│   │   │   └───Gamma size: 0
│   │   └───Properties
│   │       ├───"ACTIVE" (atomic): range [0, 1] = 1
│   │       ├───"MODE_ID" (atomic): blob = 66
│   │       │   └───1920x1080@60.00 preferred driver phsync nvsync 
│   │       ├───"OUT_FENCE_PTR" (atomic): range [0, UINT64_MAX] = 0
│   │       ├───"VRR_ENABLED": range [0, 1] = 0
│   │       └───"CTM": blob = 0
│   └───CRTC 1
│       ├───Object ID: 60
│       ├───Legacy info
│       │   └───Gamma size: 0
│       └───Properties
│           ├───"ACTIVE" (atomic): range [0, 1] = 0
│           ├───"MODE_ID" (atomic): blob = 0
│           ├───"OUT_FENCE_PTR" (atomic): range [0, UINT64_MAX] = 0
│           ├───"VRR_ENABLED": range [0, 1] = 0
│           └───"CTM": blob = 0
└───Planes
    ├───Plane 0
    │   ├───Object ID: 35
    │   ├───CRTCs: {0, 1, 2, 3, 4, 5, 6, 7}
    │   ├───Legacy info
    │   │   ├───FB ID: 63
    │   │   │   ├───Object ID: 63
    │   │   │   ├───Size: 1920x1080
    │   │   │   ├───Format: XRGB8888 (0x34325258)
    │   │   │   ├───Modifier: DRM_FORMAT_MOD_QCOM_COMPRESSED (0x500000000000001)
    │   │   │   └───Planes:
    │   │   │       └───Plane 0: offset = 0, pitch = 7680 bytes
    │   │   └───Formats:
    │   │       ├───ARGB8888 (0x34325241)
    │   │       ├───ABGR8888 (0x34324241)
    │   │       ├───RGBA8888 (0x34324152)
    │   │       ├───BGRX8888 (0x34325842)
    │   │       ├───BGRA8888 (0x34324142)
    │   │       ├───XRGB8888 (0x34325258)
    │   │       ├───XBGR8888 (0x34324258)
    │   │       ├───RGBX8888 (0x34325852)
    │   │       ├───RGB888 (0x34324752)
    │   │       ├───BGR888 (0x34324742)
    │   │       ├───RGB565 (0x36314752)
    │   │       ├───BGR565 (0x36314742)
    │   │       ├───ARGB1555 (0x35315241)
    │   │       ├───ABGR1555 (0x35314241)
    │   │       ├───RGBA5551 (0x35314152)
    │   │       ├───BGRA5551 (0x35314142)
    │   │       ├───XRGB1555 (0x35315258)
    │   │       ├───XBGR1555 (0x35314258)
    │   │       ├───RGBX5551 (0x35315852)
    │   │       ├───BGRX5551 (0x35315842)
    │   │       ├───ARGB4444 (0x32315241)
    │   │       ├───ABGR4444 (0x32314241)
    │   │       ├───RGBA4444 (0x32314152)
    │   │       ├───BGRA4444 (0x32314142)
    │   │       ├───XRGB4444 (0x32315258)
    │   │       ├───XBGR4444 (0x32314258)
    │   │       ├───RGBX4444 (0x32315852)
    │   │       ├───BGRX4444 (0x32315842)
    │   │       ├───NV12 (0x3231564e)
    │   │       ├───NV21 (0x3132564e)
    │   │       ├───NV16 (0x3631564e)
    │   │       ├───NV61 (0x3136564e)
    │   │       ├───VYUY (0x59555956)
    │   │       ├───UYVY (0x59565955)
    │   │       ├───YUYV (0x56595559)
    │   │       ├───YVYU (0x55595659)
    │   │       ├───YUV420 (0x32315559)
    │   │       └───YVU420 (0x32315659)
    │   └───Properties
    │       ├───"type" (immutable): enum {Overlay, Primary, Cursor} = Primary
    │       ├───"FB_ID" (atomic): object framebuffer = 63
    │       │   ├───Object ID: 63
    │       │   ├───Size: 1920x1080
    │       │   ├───Format: XRGB8888 (0x34325258)
    │       │   ├───Modifier: DRM_FORMAT_MOD_QCOM_COMPRESSED (0x500000000000001)
    │       │   └───Planes:
    │       │       └───Plane 0: offset = 0, pitch = 7680 bytes
    │       ├───"IN_FENCE_FD" (atomic): srange [-1, INT32_MAX] = -1
    │       ├───"CRTC_ID" (atomic): object CRTC = 59
    │       ├───"CRTC_X" (atomic): srange [INT32_MIN, INT32_MAX] = 0
    │       ├───"CRTC_Y" (atomic): srange [INT32_MIN, INT32_MAX] = 0
    │       ├───"CRTC_W" (atomic): range [0, INT32_MAX] = 1920
    │       ├───"CRTC_H" (atomic): range [0, INT32_MAX] = 1080
    │       ├───"SRC_X" (atomic): range [0, UINT32_MAX] = 0
    │       ├───"SRC_Y" (atomic): range [0, UINT32_MAX] = 0
    │       ├───"SRC_W" (atomic): range [0, UINT32_MAX] = 1920
    │       ├───"SRC_H" (atomic): range [0, UINT32_MAX] = 1080
    │       ├───"IN_FORMATS" (immutable): blob = 36
    │       │   ├───DRM_FORMAT_MOD_QCOM_COMPRESSED (0x500000000000001)
    │       │   │   ├───ARGB8888 (0x34325241)
    │       │   │   ├───ABGR8888 (0x34324241)
    │       │   │   ├───XRGB8888 (0x34325258)
    │       │   │   ├───XBGR8888 (0x34324258)
    │       │   │   ├───BGR565 (0x36314742)
    │       │   │   └───NV12 (0x3231564e)
    │       │   └───DRM_FORMAT_MOD_LINEAR (0x0)
    │       │       ├───ARGB8888 (0x34325241)
    │       │       ├───ABGR8888 (0x34324241)
    │       │       ├───RGBA8888 (0x34324152)
    │       │       ├───BGRX8888 (0x34325842)
    │       │       ├───BGRA8888 (0x34324142)
    │       │       ├───XRGB8888 (0x34325258)
    │       │       ├───XBGR8888 (0x34324258)
    │       │       ├───RGBX8888 (0x34325852)
    │       │       ├───RGB888 (0x34324752)
    │       │       ├───BGR888 (0x34324742)
    │       │       ├───RGB565 (0x36314752)
    │       │       ├───BGR565 (0x36314742)
    │       │       ├───ARGB1555 (0x35315241)
    │       │       ├───ABGR1555 (0x35314241)
    │       │       ├───RGBA5551 (0x35314152)
    │       │       ├───BGRA5551 (0x35314142)
    │       │       ├───XRGB1555 (0x35315258)
    │       │       ├───XBGR1555 (0x35314258)
    │       │       ├───RGBX5551 (0x35315852)
    │       │       ├───BGRX5551 (0x35315842)
    │       │       ├───ARGB4444 (0x32315241)
    │       │       ├───ABGR4444 (0x32314241)
    │       │       ├───RGBA4444 (0x32314152)
    │       │       ├───BGRA4444 (0x32314142)
    │       │       ├───XRGB4444 (0x32315258)
    │       │       ├───XBGR4444 (0x32314258)
    │       │       ├───RGBX4444 (0x32315852)
    │       │       ├───BGRX4444 (0x32315842)
    │       │       ├───NV12 (0x3231564e)
    │       │       ├───NV21 (0x3132564e)
    │       │       ├───NV16 (0x3631564e)
    │       │       ├───NV61 (0x3136564e)
    │       │       ├───VYUY (0x59555956)
    │       │       ├───UYVY (0x59565955)
    │       │       ├───YUYV (0x56595559)
    │       │       ├───YVYU (0x55595659)
    │       │       ├───YUV420 (0x32315559)
    │       │       └───YVU420 (0x32315659)
    │       ├───"zpos": range [0, 6] = 0
    │       ├───"alpha": range [0, UINT16_MAX] = 65535
    │       ├───"pixel blend mode": enum {None, Pre-multiplied, Coverage} = Pre-multiplied
    │       ├───"rotation": bitmask {rotate-0, rotate-180, reflect-x, reflect-y} = (rotate-0)
    │       └───"FB_DAMAGE_CLIPS" (atomic): blob = 65
    ├───Plane 1
    │   ├───Object ID: 41
    │   ├───CRTCs: {0, 1, 2, 3, 4, 5, 6, 7}
    │   ├───Legacy info
    │   │   ├───FB ID: 0
    │   │   └───Formats:
    │   │       ├───ARGB8888 (0x34325241)
    │   │       ├───ABGR8888 (0x34324241)
    │   │       ├───RGBA8888 (0x34324152)
    │   │       ├───BGRA8888 (0x34324142)
    │   │       ├───XRGB8888 (0x34325258)
    │   │       ├───RGBX8888 (0x34325852)
    │   │       ├───BGRX8888 (0x34325842)
    │   │       ├───XBGR8888 (0x34324258)
    │   │       ├───RGB888 (0x34324752)
    │   │       ├───BGR888 (0x34324742)
    │   │       ├───RGB565 (0x36314752)
    │   │       ├───BGR565 (0x36314742)
    │   │       ├───ARGB1555 (0x35315241)
    │   │       ├───ABGR1555 (0x35314241)
    │   │       ├───RGBA5551 (0x35314152)
    │   │       ├───BGRA5551 (0x35314142)
    │   │       ├───XRGB1555 (0x35315258)
    │   │       ├───XBGR1555 (0x35314258)
    │   │       ├───RGBX5551 (0x35315852)
    │   │       ├───BGRX5551 (0x35315842)
    │   │       ├───ARGB4444 (0x32315241)
    │   │       ├───ABGR4444 (0x32314241)
    │   │       ├───RGBA4444 (0x32314152)
    │   │       ├───BGRA4444 (0x32314142)
    │   │       ├───XRGB4444 (0x32315258)
    │   │       ├───XBGR4444 (0x32314258)
    │   │       ├───RGBX4444 (0x32315852)
    │   │       └───BGRX4444 (0x32315842)
    │   └───Properties
    │       ├───"type" (immutable): enum {Overlay, Primary, Cursor} = Primary
    │       ├───"FB_ID" (atomic): object framebuffer = 0
    │       ├───"IN_FENCE_FD" (atomic): srange [-1, INT32_MAX] = -1
    │       ├───"CRTC_ID" (atomic): object CRTC = 0
    │       ├───"CRTC_X" (atomic): srange [INT32_MIN, INT32_MAX] = 0
    │       ├───"CRTC_Y" (atomic): srange [INT32_MIN, INT32_MAX] = 0
    │       ├───"CRTC_W" (atomic): range [0, INT32_MAX] = 0
    │       ├───"CRTC_H" (atomic): range [0, INT32_MAX] = 0
    │       ├───"SRC_X" (atomic): range [0, UINT32_MAX] = 0
    │       ├───"SRC_Y" (atomic): range [0, UINT32_MAX] = 0
    │       ├───"SRC_W" (atomic): range [0, UINT32_MAX] = 0
    │       ├───"SRC_H" (atomic): range [0, UINT32_MAX] = 0
    │       ├───"IN_FORMATS" (immutable): blob = 42
    │       │   ├───DRM_FORMAT_MOD_QCOM_COMPRESSED (0x500000000000001)
    │       │   │   ├───ARGB8888 (0x34325241)
    │       │   │   ├───ABGR8888 (0x34324241)
    │       │   │   ├───XRGB8888 (0x34325258)
    │       │   │   ├───XBGR8888 (0x34324258)
    │       │   │   └───BGR565 (0x36314742)
    │       │   └───DRM_FORMAT_MOD_LINEAR (0x0)
    │       │       ├───ARGB8888 (0x34325241)
    │       │       ├───ABGR8888 (0x34324241)
    │       │       ├───RGBA8888 (0x34324152)
    │       │       ├───BGRA8888 (0x34324142)
    │       │       ├───XRGB8888 (0x34325258)
    │       │       ├───RGBX8888 (0x34325852)
    │       │       ├───BGRX8888 (0x34325842)
    │       │       ├───XBGR8888 (0x34324258)
    │       │       ├───RGB888 (0x34324752)
    │       │       ├───BGR888 (0x34324742)
    │       │       ├───RGB565 (0x36314752)
    │       │       ├───BGR565 (0x36314742)
    │       │       ├───ARGB1555 (0x35315241)
    │       │       ├───ABGR1555 (0x35314241)
    │       │       ├───RGBA5551 (0x35314152)
    │       │       ├───BGRA5551 (0x35314142)
    │       │       ├───XRGB1555 (0x35315258)
    │       │       ├───XBGR1555 (0x35314258)
    │       │       ├───RGBX5551 (0x35315852)
    │       │       ├───BGRX5551 (0x35315842)
    │       │       ├───ARGB4444 (0x32315241)
    │       │       ├───ABGR4444 (0x32314241)
    │       │       ├───RGBA4444 (0x32314152)
    │       │       ├───BGRA4444 (0x32314142)
    │       │       ├───XRGB4444 (0x32315258)
    │       │       ├───XBGR4444 (0x32314258)
    │       │       ├───RGBX4444 (0x32315852)
    │       │       └───BGRX4444 (0x32315842)
    │       ├───"zpos": range [0, 6] = 0
    │       ├───"alpha": range [0, UINT16_MAX] = 65535
    │       ├───"pixel blend mode": enum {None, Pre-multiplied, Coverage} = Pre-multiplied
    │       ├───"rotation": bitmask {rotate-0, rotate-180, reflect-x, reflect-y} = (rotate-0)
    │       └───"FB_DAMAGE_CLIPS" (atomic): blob = 0
    ├───Plane 2
    │   ├───Object ID: 47
    │   ├───CRTCs: {0, 1, 2, 3, 4, 5, 6, 7}
    │   ├───Legacy info
    │   │   ├───FB ID: 0
    │   │   └───Formats:
    │   │       ├───ARGB8888 (0x34325241)
    │   │       ├───ABGR8888 (0x34324241)
    │   │       ├───RGBA8888 (0x34324152)
    │   │       ├───BGRA8888 (0x34324142)
    │   │       ├───XRGB8888 (0x34325258)
    │   │       ├───RGBX8888 (0x34325852)
    │   │       ├───BGRX8888 (0x34325842)
    │   │       ├───XBGR8888 (0x34324258)
    │   │       ├───RGB888 (0x34324752)
    │   │       ├───BGR888 (0x34324742)
    │   │       ├───RGB565 (0x36314752)
    │   │       ├───BGR565 (0x36314742)
    │   │       ├───ARGB1555 (0x35315241)
    │   │       ├───ABGR1555 (0x35314241)
    │   │       ├───RGBA5551 (0x35314152)
    │   │       ├───BGRA5551 (0x35314142)
    │   │       ├───XRGB1555 (0x35315258)
    │   │       ├───XBGR1555 (0x35314258)
    │   │       ├───RGBX5551 (0x35315852)
    │   │       ├───BGRX5551 (0x35315842)
    │   │       ├───ARGB4444 (0x32315241)
    │   │       ├───ABGR4444 (0x32314241)
    │   │       ├───RGBA4444 (0x32314152)
    │   │       ├───BGRA4444 (0x32314142)
    │   │       ├───XRGB4444 (0x32315258)
    │   │       ├───XBGR4444 (0x32314258)
    │   │       ├───RGBX4444 (0x32315852)
    │   │       └───BGRX4444 (0x32315842)
    │   └───Properties
    │       ├───"type" (immutable): enum {Overlay, Primary, Cursor} = Cursor
    │       ├───"FB_ID" (atomic): object framebuffer = 0
    │       ├───"IN_FENCE_FD" (atomic): srange [-1, INT32_MAX] = -1
    │       ├───"CRTC_ID" (atomic): object CRTC = 0
    │       ├───"CRTC_X" (atomic): srange [INT32_MIN, INT32_MAX] = 515
    │       ├───"CRTC_Y" (atomic): srange [INT32_MIN, INT32_MAX] = 716
    │       ├───"CRTC_W" (atomic): range [0, INT32_MAX] = 64
    │       ├───"CRTC_H" (atomic): range [0, INT32_MAX] = 64
    │       ├───"SRC_X" (atomic): range [0, UINT32_MAX] = 0
    │       ├───"SRC_Y" (atomic): range [0, UINT32_MAX] = 0
    │       ├───"SRC_W" (atomic): range [0, UINT32_MAX] = 64
    │       ├───"SRC_H" (atomic): range [0, UINT32_MAX] = 64
    │       ├───"IN_FORMATS" (immutable): blob = 48
    │       │   ├───DRM_FORMAT_MOD_QCOM_COMPRESSED (0x500000000000001)
    │       │   │   ├───ARGB8888 (0x34325241)
    │       │   │   ├───ABGR8888 (0x34324241)
    │       │   │   ├───XRGB8888 (0x34325258)
    │       │   │   ├───XBGR8888 (0x34324258)
    │       │   │   └───BGR565 (0x36314742)
    │       │   └───DRM_FORMAT_MOD_LINEAR (0x0)
    │       │       ├───ARGB8888 (0x34325241)
    │       │       ├───ABGR8888 (0x34324241)
    │       │       ├───RGBA8888 (0x34324152)
    │       │       ├───BGRA8888 (0x34324142)
    │       │       ├───XRGB8888 (0x34325258)
    │       │       ├───RGBX8888 (0x34325852)
    │       │       ├───BGRX8888 (0x34325842)
    │       │       ├───XBGR8888 (0x34324258)
    │       │       ├───RGB888 (0x34324752)
    │       │       ├───BGR888 (0x34324742)
    │       │       ├───RGB565 (0x36314752)
    │       │       ├───BGR565 (0x36314742)
    │       │       ├───ARGB1555 (0x35315241)
    │       │       ├───ABGR1555 (0x35314241)
    │       │       ├───RGBA5551 (0x35314152)
    │       │       ├───BGRA5551 (0x35314142)
    │       │       ├───XRGB1555 (0x35315258)
    │       │       ├───XBGR1555 (0x35314258)
    │       │       ├───RGBX5551 (0x35315852)
    │       │       ├───BGRX5551 (0x35315842)
    │       │       ├───ARGB4444 (0x32315241)
    │       │       ├───ABGR4444 (0x32314241)
    │       │       ├───RGBA4444 (0x32314152)
    │       │       ├───BGRA4444 (0x32314142)
    │       │       ├───XRGB4444 (0x32315258)
    │       │       ├───XBGR4444 (0x32314258)
    │       │       ├───RGBX4444 (0x32315852)
    │       │       └───BGRX4444 (0x32315842)
    │       ├───"zpos": range [0, 6] = 0
    │       ├───"alpha": range [0, UINT16_MAX] = 65535
    │       ├───"pixel blend mode": enum {None, Pre-multiplied, Coverage} = Pre-multiplied
    │       ├───"rotation": bitmask {rotate-0, rotate-180, reflect-x, reflect-y} = (rotate-0)
    │       └───"FB_DAMAGE_CLIPS" (atomic): blob = 0
    └───Plane 3
        ├───Object ID: 53
        ├───CRTCs: {0, 1, 2, 3, 4, 5, 6, 7}
        ├───Legacy info
        │   ├───FB ID: 0
        │   └───Formats:
        │       ├───ARGB8888 (0x34325241)
        │       ├───ABGR8888 (0x34324241)
        │       ├───RGBA8888 (0x34324152)
        │       ├───BGRA8888 (0x34324142)
        │       ├───XRGB8888 (0x34325258)
        │       ├───RGBX8888 (0x34325852)
        │       ├───BGRX8888 (0x34325842)
        │       ├───XBGR8888 (0x34324258)
        │       ├───RGB888 (0x34324752)
        │       ├───BGR888 (0x34324742)
        │       ├───RGB565 (0x36314752)
        │       ├───BGR565 (0x36314742)
        │       ├───ARGB1555 (0x35315241)
        │       ├───ABGR1555 (0x35314241)
        │       ├───RGBA5551 (0x35314152)
        │       ├───BGRA5551 (0x35314142)
        │       ├───XRGB1555 (0x35315258)
        │       ├───XBGR1555 (0x35314258)
        │       ├───RGBX5551 (0x35315852)
        │       ├───BGRX5551 (0x35315842)
        │       ├───ARGB4444 (0x32315241)
        │       ├───ABGR4444 (0x32314241)
        │       ├───RGBA4444 (0x32314152)
        │       ├───BGRA4444 (0x32314142)
        │       ├───XRGB4444 (0x32315258)
        │       ├───XBGR4444 (0x32314258)
        │       ├───RGBX4444 (0x32315852)
        │       └───BGRX4444 (0x32315842)
        └───Properties
            ├───"type" (immutable): enum {Overlay, Primary, Cursor} = Cursor
            ├───"FB_ID" (atomic): object framebuffer = 0
            ├───"IN_FENCE_FD" (atomic): srange [-1, INT32_MAX] = -1
            ├───"CRTC_ID" (atomic): object CRTC = 0
            ├───"CRTC_X" (atomic): srange [INT32_MIN, INT32_MAX] = 0
            ├───"CRTC_Y" (atomic): srange [INT32_MIN, INT32_MAX] = 0
            ├───"CRTC_W" (atomic): range [0, INT32_MAX] = 0
            ├───"CRTC_H" (atomic): range [0, INT32_MAX] = 0
            ├───"SRC_X" (atomic): range [0, UINT32_MAX] = 0
            ├───"SRC_Y" (atomic): range [0, UINT32_MAX] = 0
            ├───"SRC_W" (atomic): range [0, UINT32_MAX] = 0
            ├───"SRC_H" (atomic): range [0, UINT32_MAX] = 0
            ├───"IN_FORMATS" (immutable): blob = 54
            │   ├───DRM_FORMAT_MOD_QCOM_COMPRESSED (0x500000000000001)
            │   │   ├───ARGB8888 (0x34325241)
            │   │   ├───ABGR8888 (0x34324241)
            │   │   ├───XRGB8888 (0x34325258)
            │   │   ├───XBGR8888 (0x34324258)
            │   │   └───BGR565 (0x36314742)
            │   └───DRM_FORMAT_MOD_LINEAR (0x0)
            │       ├───ARGB8888 (0x34325241)
            │       ├───ABGR8888 (0x34324241)
            │       ├───RGBA8888 (0x34324152)
            │       ├───BGRA8888 (0x34324142)
            │       ├───XRGB8888 (0x34325258)
            │       ├───RGBX8888 (0x34325852)
            │       ├───BGRX8888 (0x34325842)
            │       ├───XBGR8888 (0x34324258)
            │       ├───RGB888 (0x34324752)
            │       ├───BGR888 (0x34324742)
            │       ├───RGB565 (0x36314752)
            │       ├───BGR565 (0x36314742)
            │       ├───ARGB1555 (0x35315241)
            │       ├───ABGR1555 (0x35314241)
            │       ├───RGBA5551 (0x35314152)
            │       ├───BGRA5551 (0x35314142)
            │       ├───XRGB1555 (0x35315258)
            │       ├───XBGR1555 (0x35314258)
            │       ├───RGBX5551 (0x35315852)
            │       ├───BGRX5551 (0x35315842)
            │       ├───ARGB4444 (0x32315241)
            │       ├───ABGR4444 (0x32314241)
            │       ├───RGBA4444 (0x32314152)
            │       ├───BGRA4444 (0x32314142)
            │       ├───XRGB4444 (0x32315258)
            │       ├───XBGR4444 (0x32314258)
            │       ├───RGBX4444 (0x32315852)
            │       └───BGRX4444 (0x32315842)
            ├───"zpos": range [0, 6] = 0
            ├───"alpha": range [0, UINT16_MAX] = 65535
            ├───"pixel blend mode": enum {None, Pre-multiplied, Coverage} = Pre-multiplied
            ├───"rotation": bitmask {rotate-0, rotate-180, reflect-x, reflect-y} = (rotate-0)
            └───"FB_DAMAGE_CLIPS" (atomic): blob = 0

[1]: https://acerrecertified.com/acer-spin-513-13-3-chromebook-qualcomm-7c-2-1ghz-4gb-ram-64gb-flash-chromeos-cp513-1h-s60f/
[2]: https://www.kernel.org/doc/html/v5.18/gpu/drm-kms.html#crtc-abstraction
Comment 1 Zamundaaa 2022-07-12 09:19:13 UTC
GAMMA_LUT is not legacy at all, CTM is supposed to be used in combination with gamma and degamma, not instead of it. That's at least the state with upstream drivers and desktop GPUs: the color pipeline is degamma -> ctm -> gamma.

Support for using the CTM without gamma and degamma can be added though - I just need to figure out how to generate the needed color transformation matrix...
ChromiumOS hardcodes a single CTM for "night color enabled", which is not very useful for us - we have brightness, ICC profile, night mode and soon gamma adjustment that all need to play together.
Afaiu the 3x3 CTM that drm provides is also a lot less accurate than the LUTs, so that may complicate things as well -  we might need to quantify that error and fall back to a shader based solution instead where needed.
Comment 2 Bug Janitor Service 2022-12-11 15:03:33 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/3296
Comment 3 Bug Janitor Service 2023-03-07 16:19:39 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/3771
Comment 4 Zamundaaa 2023-03-07 16:20:06 UTC
Git commit f2417a85233e1b7c1c68039230c45554f1069694 by Xaver Hugl.
Committed on 07/03/2023 at 16:03.
Pushed by vladz into branch 'master'.

backends/drm: support CTM for simple color transformations

In order to work around hardware and drivers that aren't capable of applying
a LUT, calculate a per-channel factor for brightness and color temperature
modification. While this ignores color calibration, this makes night color
work until a proper shader based color pipeline is implemented.

M  +1    -1    src/backends/drm/drm_crtc.cpp
M  +1    -0    src/backends/drm/drm_crtc.h
M  +17   -2    src/backends/drm/drm_output.cpp
M  +2    -1    src/backends/drm/drm_output.h
M  +52   -2    src/backends/drm/drm_pipeline.cpp
M  +16   -1    src/backends/drm/drm_pipeline.h
M  +3    -2    src/backends/x11/standalone/x11_standalone_output.cpp
M  +1    -1    src/backends/x11/standalone/x11_standalone_output.h
M  +15   -6    src/colors/colordevice.cpp
M  +7    -1    src/core/output.cpp
M  +3    -1    src/core/output.h

https://invent.kde.org/plasma/kwin/commit/f2417a85233e1b7c1c68039230c45554f1069694
Comment 5 Vlad Zahorodnii 2023-03-08 19:21:51 UTC
Git commit 114032d2ac4d2eb9433bf75c0e6a82ecce7fa558 by Vlad Zahorodnii, on behalf of Xaver Hugl.
Committed on 08/03/2023 at 19:09.
Pushed by vladz into branch 'Plasma/5.27'.

backends/drm: support CTM for simple color transformations

In order to work around hardware and drivers that aren't capable of applying
a LUT, calculate a per-channel factor for brightness and color temperature
modification. While this ignores color calibration, this makes night color
work until a proper shader based color pipeline is implemented.
(cherry picked from commit f2417a85233e1b7c1c68039230c45554f1069694)

M  +1    -1    src/backends/drm/drm_crtc.cpp
M  +1    -0    src/backends/drm/drm_crtc.h
M  +17   -2    src/backends/drm/drm_output.cpp
M  +2    -1    src/backends/drm/drm_output.h
M  +52   -2    src/backends/drm/drm_pipeline.cpp
M  +16   -1    src/backends/drm/drm_pipeline.h
M  +3    -2    src/backends/x11/standalone/x11_standalone_output.cpp
M  +1    -1    src/backends/x11/standalone/x11_standalone_output.h
M  +15   -6    src/colors/colordevice.cpp
M  +7    -1    src/core/output.cpp
M  +3    -1    src/core/output.h

https://invent.kde.org/plasma/kwin/commit/114032d2ac4d2eb9433bf75c0e6a82ecce7fa558