Skip to content

Commit e90bee2

Browse files
cristicc6by9
authored andcommitted
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 dedicated drm_argb64() utility macro. Individual color components can be extracted with desired precision using the corresponding DRM_ARGB64_*() macros. Co-developed-by: Matt Roper <[email protected]> Signed-off-by: Matt Roper <[email protected]> Signed-off-by: Cristian Ciocaltea <[email protected]>
1 parent 49dd122 commit e90bee2

File tree

8 files changed

+94
-6
lines changed

8 files changed

+94
-6
lines changed

drivers/gpu/drm/drm_atomic_state_helper.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
7474
struct drm_crtc *crtc)
7575
{
7676
crtc_state->crtc = crtc;
77+
crtc_state->background_color = drm_argb64(0xffff, 0, 0, 0);
7778
}
7879
EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
7980

drivers/gpu/drm/drm_atomic_uapi.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
405405
&replaced);
406406
state->color_mgmt_changed |= replaced;
407407
return ret;
408+
} else if (property == config->background_color_property) {
409+
state->background_color = val;
408410
} else if (property == config->prop_out_fence_ptr) {
409411
s32 __user *fence_ptr = u64_to_user_ptr(val);
410412

@@ -450,6 +452,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
450452
*val = (state->ctm) ? state->ctm->base.id : 0;
451453
else if (property == config->gamma_lut_property)
452454
*val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
455+
else if (property == config->background_color_property)
456+
*val = state->background_color;
453457
else if (property == config->prop_out_fence_ptr)
454458
*val = 0;
455459
else if (property == crtc->scaling_filter_property)

drivers/gpu/drm/drm_blend.c

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,6 @@
185185
* plane does not expose the "alpha" property, then this is
186186
* assumed to be 1.0
187187
*
188-
* Note that all the property extensions described here apply either to the
189-
* plane or the CRTC (e.g. for the background color, which currently is not
190-
* exposed and assumed to be black).
191-
*
192188
* SCALING_FILTER:
193189
* Indicates scaling filter to be used for plane scaler
194190
*
@@ -201,6 +197,23 @@
201197
*
202198
* Drivers can set up this property for a plane by calling
203199
* drm_plane_create_scaling_filter_property
200+
*
201+
* The property extensions described above all apply to the plane. Drivers
202+
* may also expose the following crtc property extension:
203+
*
204+
* BACKGROUND_COLOR:
205+
* Background color is set via drm_crtc_attach_background_color_property().
206+
* It controls the ARGB color of a full-screen layer that exists below all
207+
* planes. This color will be used for pixels not covered by any plane and
208+
* may also be blended with plane contents as allowed by a plane's alpha
209+
* values. The background color defaults to black, and is assumed to be
210+
* black for drivers that do not expose this property. Although background
211+
* color isn't a plane, it is assumed that the color provided here
212+
* undergoes the same pipe-level degamma/CSC/gamma transformations that
213+
* planes undergo. Note that the color value provided here includes an
214+
* alpha channel, hence non-opaque background color values are allowed, but
215+
* are generally only honored in special cases (e.g. when a memory
216+
* writeback connector is in use).
204217
*/
205218

206219
/**
@@ -648,3 +661,19 @@ int drm_plane_create_blend_mode_property(struct drm_plane *plane,
648661
return 0;
649662
}
650663
EXPORT_SYMBOL(drm_plane_create_blend_mode_property);
664+
665+
/**
666+
* drm_crtc_attach_background_color_property - attach background color property
667+
* @crtc: drm crtc
668+
*
669+
* Attaches the background color property to @crtc. The property defaults to
670+
* solid black and will accept 64-bit ARGB values in the format generated by
671+
* drm_argb64().
672+
*/
673+
void drm_crtc_attach_background_color_property(struct drm_crtc *crtc)
674+
{
675+
drm_object_attach_property(&crtc->base,
676+
crtc->dev->mode_config.background_color_property,
677+
drm_argb64(0xffff, 0, 0, 0));
678+
}
679+
EXPORT_SYMBOL(drm_crtc_attach_background_color_property);

drivers/gpu/drm/drm_mode_config.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
365365
return -ENOMEM;
366366
dev->mode_config.gamma_lut_size_property = prop;
367367

368+
prop = drm_property_create_range(dev, 0,
369+
"BACKGROUND_COLOR", 0, U64_MAX);
370+
if (!prop)
371+
return -ENOMEM;
372+
dev->mode_config.background_color_property = prop;
373+
368374
prop = drm_property_create(dev,
369375
DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_BLOB,
370376
"IN_FORMATS", 0);

include/drm/drm_blend.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@
3131
#define DRM_MODE_BLEND_COVERAGE 1
3232
#define DRM_MODE_BLEND_PIXEL_NONE 2
3333

34-
struct drm_device;
3534
struct drm_atomic_state;
35+
struct drm_crtc;
36+
struct drm_device;
3637
struct drm_plane;
3738
struct drm_connector;
3839

@@ -59,7 +60,7 @@ int drm_atomic_normalize_zpos(struct drm_device *dev,
5960
struct drm_atomic_state *state);
6061
int drm_plane_create_blend_mode_property(struct drm_plane *plane,
6162
unsigned int supported_modes);
62-
63+
void drm_crtc_attach_background_color_property(struct drm_crtc *crtc);
6364
int drm_connector_create_rotation_property(struct drm_connector *conn,
6465
unsigned int rotation,
6566
unsigned int supported_rotations);

include/drm/drm_crtc.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,18 @@ struct drm_crtc_state {
274274
*/
275275
struct drm_property_blob *gamma_lut;
276276

277+
/**
278+
* @background_color:
279+
*
280+
* RGB value representing the pipe's background color. The background
281+
* color (aka "canvas color") of a pipe 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(), while
284+
* the individual color components can be extracted with desired
285+
* precision via the DRM_ARGB64_*() macros.
286+
*/
287+
u64 background_color;
288+
277289
/**
278290
* @target_vblank:
279291
*

include/drm/drm_mode_config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,11 @@ struct drm_mode_config {
813813
* gamma LUT as supported by the driver (read-only).
814814
*/
815815
struct drm_property *gamma_lut_size_property;
816+
/**
817+
* @background_color_property: Optional CRTC property to set the
818+
* background color.
819+
*/
820+
struct drm_property *background_color_property;
816821

817822
/**
818823
* @suggested_x_property: Optional connector property with a hint for

include/uapi/drm/drm_mode.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,36 @@ struct drm_mode_closefb {
13561356
__u32 pad;
13571357
};
13581358

1359+
/*
1360+
* Put 16-bit ARGB values into a standard 64-bit representation that
1361+
* can be used for ioctl parameters, inter-driver communication, etc.
1362+
*/
1363+
static inline __u64
1364+
drm_argb64(__u16 alpha, __u16 red, __u16 green, __u16 blue)
1365+
{
1366+
return (__u64)alpha << 48 | (__u64)red << 32 | (__u64)green << 16 | blue;
1367+
}
1368+
1369+
/*
1370+
* Extract the specified number of least-significant bits of a specific
1371+
* color component from a standard 64-bit ARGB value.
1372+
*/
1373+
#define DRM_ARGB64_COMP(c, shift, numlsb) \
1374+
((__u16)(((c) >> (shift)) & ((1UL << (numlsb) % 17) - 1)))
1375+
#define DRM_ARGB64_ALPHA_LSB(c, numlsb) DRM_ARGB64_COMP(c, 48, numlsb)
1376+
#define DRM_ARGB64_RED_LSB(c, numlsb) DRM_ARGB64_COMP(c, 32, numlsb)
1377+
#define DRM_ARGB64_GREEN_LSB(c, numlsb) DRM_ARGB64_COMP(c, 16, numlsb)
1378+
#define DRM_ARGB64_BLUE_LSB(c, numlsb) DRM_ARGB64_COMP(c, 0, numlsb)
1379+
1380+
/*
1381+
* Convenience wrappers to extract all 16 bits of a specific color
1382+
* component from a standard 64-bit ARGB value.
1383+
*/
1384+
#define DRM_ARGB64_ALPHA(c) DRM_ARGB64_ALPHA_LSB(c, 16)
1385+
#define DRM_ARGB64_RED(c) DRM_ARGB64_RED_LSB(c, 16)
1386+
#define DRM_ARGB64_GREEN(c) DRM_ARGB64_GREEN_LSB(c, 16)
1387+
#define DRM_ARGB64_BLUE(c) DRM_ARGB64_BLUE_LSB(c, 16)
1388+
13591389
#if defined(__cplusplus)
13601390
}
13611391
#endif

0 commit comments

Comments
 (0)