Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm: Add CRTC background color property

Some display controllers can be hardware programmed to show non-black
colors for pixels that are either not covered by any plane or are
exposed through transparent regions of higher planes. This feature can
help reduce memory bandwidth usage, e.g. in compositors managing a UI
with a solid background color while using smaller planes to render the
remaining content.

To support this capability, introduce the BACKGROUND_COLOR standard DRM
mode property, which can be attached to a CRTC through the
drm_crtc_attach_background_color_property() helper function.

Additionally, define a 64-bit ARGB format value to be built with the
help of a couple of dedicated DRM_ARGB64_PREP*() helpers. Individual
color components can be extracted with desired precision using the
corresponding DRM_ARGB64_GET*() macros.

Co-developed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Tested-by: Diederik de Haas <diederik@cknow-tech.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Link: https://patch.msgid.link/20260303-rk3588-bgcolor-v8-2-fee377037ad1@collabora.com
Signed-off-by: Daniel Stone <daniels@collabora.com>

authored by

Cristian Ciocaltea and committed by
Daniel Stone
4c684596 de9e2b3d

+147 -5
+1
drivers/gpu/drm/drm_atomic.c
··· 475 475 drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask); 476 476 drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask); 477 477 drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode)); 478 + drm_printf(p, "\tbackground_color=%llx\n", state->background_color); 478 479 479 480 if (crtc->funcs->atomic_print_state) 480 481 crtc->funcs->atomic_print_state(p, state);
+1
drivers/gpu/drm/drm_atomic_state_helper.c
··· 75 75 struct drm_crtc *crtc) 76 76 { 77 77 crtc_state->crtc = crtc; 78 + crtc_state->background_color = DRM_ARGB64_PREP(0xffff, 0, 0, 0); 78 79 } 79 80 EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset); 80 81
+4
drivers/gpu/drm/drm_atomic_uapi.c
··· 454 454 &replaced); 455 455 state->color_mgmt_changed |= replaced; 456 456 return ret; 457 + } else if (property == config->background_color_property) { 458 + state->background_color = val; 457 459 } else if (property == config->prop_out_fence_ptr) { 458 460 s32 __user *fence_ptr = u64_to_user_ptr(val); 459 461 ··· 503 501 *val = (state->ctm) ? state->ctm->base.id : 0; 504 502 else if (property == config->gamma_lut_property) 505 503 *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; 504 + else if (property == config->background_color_property) 505 + *val = state->background_color; 506 506 else if (property == config->prop_out_fence_ptr) 507 507 *val = 0; 508 508 else if (property == crtc->scaling_filter_property)
+35 -4
drivers/gpu/drm/drm_blend.c
··· 191 191 * plane does not expose the "alpha" property, then this is 192 192 * assumed to be 1.0 193 193 * 194 - * Note that all the property extensions described here apply either to the 195 - * plane or the CRTC (e.g. for the background color, which currently is not 196 - * exposed and assumed to be black). 197 - * 198 194 * SCALING_FILTER: 199 195 * Indicates scaling filter to be used for plane scaler 200 196 * ··· 203 207 * 204 208 * Drivers can set up this property for a plane by calling 205 209 * drm_plane_create_scaling_filter_property 210 + * 211 + * The property extensions described above all apply to the plane. Drivers 212 + * may also expose the following crtc property extension: 213 + * 214 + * BACKGROUND_COLOR: 215 + * Background color is set up with drm_crtc_attach_background_color_property(), 216 + * and expects a 64-bit ARGB value following DRM_FORMAT_ARGB16161616, as 217 + * generated by the DRM_ARGB64_PREP*() helpers. It controls the color of a 218 + * full-screen layer that exists below all planes. This color will be used 219 + * for pixels not covered by any plane and may also be blended with plane 220 + * contents as allowed by a plane's alpha values. 221 + * The background color defaults to black, and is assumed to be black for 222 + * drivers that do not expose this property. Although background color 223 + * isn't a plane, it is assumed that the color provided here undergoes the 224 + * CRTC degamma/CSC/gamma transformations applied after the planes blending. 225 + * Note that the color value includes an alpha channel, hence non-opaque 226 + * background color values are allowed, but since physically transparent 227 + * monitors do not (yet) exists, the final alpha value may not reach the 228 + * video sink or it may simply ignore it. 206 229 */ 207 230 208 231 /** ··· 636 621 return 0; 637 622 } 638 623 EXPORT_SYMBOL(drm_plane_create_blend_mode_property); 624 + 625 + /** 626 + * drm_crtc_attach_background_color_property - attach background color property 627 + * @crtc: drm crtc 628 + * 629 + * Attaches the background color property to @crtc. The property defaults to 630 + * solid black and will accept 64-bit ARGB values in the format generated by 631 + * DRM_ARGB64_PREP*() helpers. 632 + */ 633 + void drm_crtc_attach_background_color_property(struct drm_crtc *crtc) 634 + { 635 + drm_object_attach_property(&crtc->base, 636 + crtc->dev->mode_config.background_color_property, 637 + DRM_ARGB64_PREP(0xffff, 0, 0, 0)); 638 + } 639 + EXPORT_SYMBOL(drm_crtc_attach_background_color_property);
+6
drivers/gpu/drm/drm_mode_config.c
··· 380 380 return -ENOMEM; 381 381 dev->mode_config.gamma_lut_size_property = prop; 382 382 383 + prop = drm_property_create_range(dev, 0, 384 + "BACKGROUND_COLOR", 0, U64_MAX); 385 + if (!prop) 386 + return -ENOMEM; 387 + dev->mode_config.background_color_property = prop; 388 + 383 389 prop = drm_property_create(dev, 384 390 DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB, 385 391 "IN_FORMATS", 0);
+3 -1
include/drm/drm_blend.h
··· 31 31 #define DRM_MODE_BLEND_COVERAGE 1 32 32 #define DRM_MODE_BLEND_PIXEL_NONE 2 33 33 34 - struct drm_device; 35 34 struct drm_atomic_state; 35 + struct drm_crtc; 36 + struct drm_device; 36 37 struct drm_plane; 37 38 38 39 static inline bool drm_rotation_90_or_270(unsigned int rotation) ··· 59 58 struct drm_atomic_state *state); 60 59 int drm_plane_create_blend_mode_property(struct drm_plane *plane, 61 60 unsigned int supported_modes); 61 + void drm_crtc_attach_background_color_property(struct drm_crtc *crtc); 62 62 #endif
+12
include/drm/drm_crtc.h
··· 275 275 struct drm_property_blob *gamma_lut; 276 276 277 277 /** 278 + * @background_color: 279 + * 280 + * RGB value representing the CRTC's background color. The background 281 + * color (aka "canvas color") of a CRTC is the color that will be used 282 + * for pixels not covered by a plane, or covered by transparent pixels 283 + * of a plane. The value here should be built using DRM_ARGB64_PREP*() 284 + * helpers, while the individual color components can be extracted with 285 + * desired precision via the DRM_ARGB64_GET*() macros. 286 + */ 287 + u64 background_color; 288 + 289 + /** 278 290 * @target_vblank: 279 291 * 280 292 * Target vertical blank period when a page flip
+5
include/drm/drm_mode_config.h
··· 836 836 * gamma LUT as supported by the driver (read-only). 837 837 */ 838 838 struct drm_property *gamma_lut_size_property; 839 + /** 840 + * @background_color_property: Optional CRTC property to set the 841 + * background color. 842 + */ 843 + struct drm_property *background_color_property; 839 844 840 845 /** 841 846 * @suggested_x_property: Optional connector property with a hint for
+80
include/uapi/drm/drm_mode.h
··· 27 27 #ifndef _DRM_MODE_H 28 28 #define _DRM_MODE_H 29 29 30 + #include <linux/bits.h> 31 + #include <linux/const.h> 32 + 30 33 #include "drm.h" 31 34 32 35 #if defined(__cplusplus) ··· 1551 1548 __u32 fb_id; 1552 1549 __u32 pad; 1553 1550 }; 1551 + 1552 + /* 1553 + * Put 16-bit ARGB values into a standard 64-bit representation that can be 1554 + * used for ioctl parameters, inter-driver communication, etc. 1555 + * 1556 + * If the component values being provided contain less than 16 bits of 1557 + * precision, use a conversion ratio to get a better color approximation. 1558 + * The ratio is computed as (2^16 - 1) / (2^bpc - 1), where bpc and 16 are 1559 + * the input and output precision, respectively. 1560 + * Also note bpc must be greater than 0. 1561 + */ 1562 + #define __DRM_ARGB64_PREP(c, shift) \ 1563 + (((__u64)(c) & __GENMASK(15, 0)) << (shift)) 1564 + 1565 + #define __DRM_ARGB64_PREP_BPC(c, shift, bpc) \ 1566 + ({ \ 1567 + __u16 mask = __GENMASK((bpc) - 1, 0); \ 1568 + __u16 conv = __KERNEL_DIV_ROUND_CLOSEST((mask & (c)) * \ 1569 + __GENMASK(15, 0), mask);\ 1570 + __DRM_ARGB64_PREP(conv, shift); \ 1571 + }) 1572 + 1573 + #define DRM_ARGB64_PREP(alpha, red, green, blue) \ 1574 + ( \ 1575 + __DRM_ARGB64_PREP(alpha, 48) | \ 1576 + __DRM_ARGB64_PREP(red, 32) | \ 1577 + __DRM_ARGB64_PREP(green, 16) | \ 1578 + __DRM_ARGB64_PREP(blue, 0) \ 1579 + ) 1580 + 1581 + #define DRM_ARGB64_PREP_BPC(alpha, red, green, blue, bpc) \ 1582 + ({ \ 1583 + __typeof__(bpc) __bpc = bpc; \ 1584 + __DRM_ARGB64_PREP_BPC(alpha, 48, __bpc) | \ 1585 + __DRM_ARGB64_PREP_BPC(red, 32, __bpc) | \ 1586 + __DRM_ARGB64_PREP_BPC(green, 16, __bpc) | \ 1587 + __DRM_ARGB64_PREP_BPC(blue, 0, __bpc); \ 1588 + }) 1589 + 1590 + /* 1591 + * Extract the specified color component from a standard 64-bit ARGB value. 1592 + * 1593 + * If the requested precision is less than 16 bits, make use of a conversion 1594 + * ratio calculated as (2^bpc - 1) / (2^16 - 1), where bpc and 16 are the 1595 + * output and input precision, respectively. 1596 + * 1597 + * If speed is more important than accuracy, use DRM_ARGB64_GET*_BPCS() 1598 + * instead of DRM_ARGB64_GET*_BPC() in order to replace the expensive 1599 + * division with a simple bit right-shift operation. 1600 + */ 1601 + #define __DRM_ARGB64_GET(c, shift) \ 1602 + ((__u16)(((__u64)(c) >> (shift)) & __GENMASK(15, 0))) 1603 + 1604 + #define __DRM_ARGB64_GET_BPC(c, shift, bpc) \ 1605 + ({ \ 1606 + __u16 comp = __DRM_ARGB64_GET(c, shift); \ 1607 + __KERNEL_DIV_ROUND_CLOSEST(comp * __GENMASK((bpc) - 1, 0), \ 1608 + __GENMASK(15, 0)); \ 1609 + }) 1610 + 1611 + #define __DRM_ARGB64_GET_BPCS(c, shift, bpc) \ 1612 + (__DRM_ARGB64_GET(c, shift) >> (16 - (bpc))) 1613 + 1614 + #define DRM_ARGB64_GETA(c) __DRM_ARGB64_GET(c, 48) 1615 + #define DRM_ARGB64_GETR(c) __DRM_ARGB64_GET(c, 32) 1616 + #define DRM_ARGB64_GETG(c) __DRM_ARGB64_GET(c, 16) 1617 + #define DRM_ARGB64_GETB(c) __DRM_ARGB64_GET(c, 0) 1618 + 1619 + #define DRM_ARGB64_GETA_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 48, bpc) 1620 + #define DRM_ARGB64_GETR_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 32, bpc) 1621 + #define DRM_ARGB64_GETG_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 16, bpc) 1622 + #define DRM_ARGB64_GETB_BPC(c, bpc) __DRM_ARGB64_GET_BPC(c, 0, bpc) 1623 + 1624 + #define DRM_ARGB64_GETA_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 48, bpc) 1625 + #define DRM_ARGB64_GETR_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 32, bpc) 1626 + #define DRM_ARGB64_GETG_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 16, bpc) 1627 + #define DRM_ARGB64_GETB_BPCS(c, bpc) __DRM_ARGB64_GET_BPCS(c, 0, bpc) 1554 1628 1555 1629 #if defined(__cplusplus) 1556 1630 }