drm/tegra: Expose color key and plane blending controls to userspace
PATCH 1/1 drm/tegra: Expose color key and plane blending controls to userspace
Chromakey is a simple way of video overlay overlap implementation. This patch adds 2 new IOCTL's: first - sets color key and is common across of all Tegra SoC's, second - sets plane blending controls and allows to utilize the color key, this one is exclusive to Tegra20/30.
--- drivers/gpu/drm/tegra/dc.c | 150 +++++++++++++++++++++++++++++++++------- drivers/gpu/drm/tegra/dc.h | 6 ++ drivers/gpu/drm/tegra/drm.c | 159 +++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 14 ++++ include/uapi/drm/tegra_drm.h | 34 +++++++++ 5 files changed, 337 insertions(+), 26 deletions(-)
drivers/gpu/drm/tegra/dc.c +124 -26
@@ -42,6 +42,11 @@ static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane) return container_of(plane, struct tegra_plane, base); } +struct tegra_dc_color_key { +u32 upper; +u32 lower; +}; +struct tegra_dc_state {struct drm_crtc_state base;
@@ -50,6 +55,9 @@ struct tegra_dc_state {unsigned int div;u32 planes; + +struct tegra_dc_color_key color_key0; +struct tegra_dc_color_key color_key1; };static inline struct tegra_dc_state *to_dc_state (struct drm_crtc_state *state)
@@ -66,6 +74,11 @@ struct tegra_plane_state {struct tegra_bo_tiling tiling;u32 format;u32 swap; +u32 blend_nokey; +u32 blend_1win; +u32 blend_2win_x; +u32 blend_2win_y; +u32 blend_3win_xy; }; static inline struct tegra_plane_state *
@@ -77,6 +90,66 @@ to_tegra_plane_state(struct drm_plane_state *state)return NULL ; } +void tegra_dc_set_color_key (struct drm_crtc_state *crtc_state, +int key_id,u32 upper,u32 lower) +{ +struct tegra_dc_state *state =to_dc_state (crtc_state); +struct tegra_dc_color_key *color_key; + +if (key_id ==0 ) + color_key = &state->color_key0; +else + color_key = &state->color_key1; + + color_key->lower = lower; + color_key->upper = upper; +} + +void tegra20_dc_plane_set_blending (struct drm_plane_state *plane_state, +unsigned int blend_config, +unsigned int blend_control, +unsigned int blend_weight0, +unsigned int blend_weight1, +bool use_color_key0, +bool use_color_key1) +{ +struct tegra_plane_state *state =to_tegra_plane_state (plane_state); +u32 value; + +if (blend_config ==DRM_TEGRA_PLANE_BLEND_CONFIG_NOKEY ) { + value =DC_WIN_BLEND_CONTROL_NOKEY (blend_control); + }else { + value =DC_WIN_BLEND_CONTROL (blend_control); + +if (use_color_key0) + value |=DC_WIN_BLEND_CKEY0 ; + +if (use_color_key1) + value |=DC_WIN_BLEND_CKEY1 ; + } + + value |=DC_WIN_BLEND_WEIGHT0 (blend_weight0); + value |=DC_WIN_BLEND_WEIGHT1 (blend_weight1); + +switch (blend_config) { +case DRM_TEGRA_PLANE_BLEND_CONFIG_NOKEY : + state->blend_nokey = value; +break ; +case DRM_TEGRA_PLANE_BLEND_CONFIG_1WIN : + state->blend_1win = value; +break ; +case DRM_TEGRA_PLANE_BLEND_CONFIG_2WIN_X : + state->blend_2win_x = value; +break ; +case DRM_TEGRA_PLANE_BLEND_CONFIG_2WIN_Y : + state->blend_2win_y = value; +break ; +case DRM_TEGRA_PLANE_BLEND_CONFIG_3WIN_XY : + state->blend_3win_xy = value; +break ; + } +} +static void tegra_dc_stats_reset (struct tegra_dc_stats *stats) { stats->frames =0 ;
@@ -381,32 +454,11 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,tegra_dc_writel (dc, value,DC_WIN_WIN_OPTIONS ); -/* -* Disable blending and assume Window A is the bottom-most window, -* Window C is the top-most window and Window B is in the middle. -*/ -tegra_dc_writel (dc,0xffff00 ,DC_WIN_BLEND_NOKEY ); -tegra_dc_writel (dc,0xffff00 ,DC_WIN_BLEND_1WIN ); - -switch (index) { -case 0 : -tegra_dc_writel (dc,0x000000 ,DC_WIN_BLEND_2WIN_X ); -tegra_dc_writel (dc,0x000000 ,DC_WIN_BLEND_2WIN_Y ); -tegra_dc_writel (dc,0x000000 ,DC_WIN_BLEND_3WIN_XY ); -break ; - -case 1 : -tegra_dc_writel (dc,0xffff00 ,DC_WIN_BLEND_2WIN_X ); -tegra_dc_writel (dc,0x000000 ,DC_WIN_BLEND_2WIN_Y ); -tegra_dc_writel (dc,0x000000 ,DC_WIN_BLEND_3WIN_XY ); -break ; - -case 2 : -tegra_dc_writel (dc,0xffff00 ,DC_WIN_BLEND_2WIN_X ); -tegra_dc_writel (dc,0xffff00 ,DC_WIN_BLEND_2WIN_Y ); -tegra_dc_writel (dc,0xffff00 ,DC_WIN_BLEND_3WIN_XY ); -break ; - } +tegra_dc_writel (dc, window->blend_nokey,DC_WIN_BLEND_NOKEY ); +tegra_dc_writel (dc, window->blend_1win,DC_WIN_BLEND_1WIN ); +tegra_dc_writel (dc, window->blend_2win_x,DC_WIN_BLEND_2WIN_X ); +tegra_dc_writel (dc, window->blend_2win_y,DC_WIN_BLEND_2WIN_Y ); +tegra_dc_writel (dc, window->blend_3win_xy,DC_WIN_BLEND_3WIN_XY );spin_unlock_irqrestore (&dc->lock, flags); }
@@ -444,6 +496,34 @@ static void tegra_plane_reset(struct drm_plane *plane)if (state) { plane->state = &state->base; plane->state->plane = plane; + +/* +* By default, disable blending and assume Window A is the +* bottom-most window, Window C is the top-most window and +* Window B is in the middle. +*/ + state->blend_nokey =0xffff00 ; + state->blend_1win =0xffff00 ; + +switch (plane->index) { +case 0 : + state->blend_2win_x =0x000000 ; + state->blend_2win_y =0x000000 ; + state->blend_3win_xy =0x000000 ; +break ; + +case 1 : + state->blend_2win_x =0xffff00 ; + state->blend_2win_y =0x000000 ; + state->blend_3win_xy =0x000000 ; +break ; + +case 2 : + state->blend_2win_x =0xffff00 ; + state->blend_2win_y =0xffff00 ; + state->blend_3win_xy =0xffff00 ; +break ; + } } }
@@ -460,6 +540,11 @@ static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_pla copy->tiling = state->tiling; copy->format = state->format; copy->swap = state->swap; + copy->blend_nokey = state->blend_nokey; + copy->blend_1win = state->blend_1win; + copy->blend_2win_x = state->blend_2win_x; + copy->blend_2win_y = state->blend_2win_y; + copy->blend_3win_xy = state->blend_3win_xy;return ©->base; }
@@ -593,6 +678,11 @@ static void tegra_plane_atomic_update(struct drm_plane *plane, window.tiling = state->tiling; window.format = state->format; window.swap = state->swap; + window.blend_nokey = state->blend_nokey; + window.blend_1win = state->blend_1win; + window.blend_2win_x = state->blend_2win_x; + window.blend_2win_y = state->blend_2win_y; + window.blend_3win_xy = state->blend_3win_xy;for (i =0 ; i <drm_format_num_planes (fb->pixel_format); i++) {struct tegra_bo *bo =tegra_fb_get_plane (fb, i);
@@ -1045,6 +1135,8 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc) copy->pclk = state->pclk; copy->div = state->div; copy->planes = state->planes; + copy->color_key0 = state->color_key0; + copy->color_key1 = state->color_key1;return ©->base; }
@@ -1343,6 +1435,12 @@ static void tegra_crtc_atomic_flush(struct drm_crtc *crtc,tegra_dc_writel (dc, state->planes <<8 ,DC_CMD_STATE_CONTROL );tegra_dc_writel (dc, state->planes,DC_CMD_STATE_CONTROL ); + +tegra_dc_writel (dc, state->color_key0.lower,DC_DISP_COLOR_KEY0_LOWER ); +tegra_dc_writel (dc, state->color_key0.upper,DC_DISP_COLOR_KEY0_UPPER ); +tegra_dc_writel (dc, state->color_key1.lower,DC_DISP_COLOR_KEY1_LOWER ); +tegra_dc_writel (dc, state->color_key1.upper,DC_DISP_COLOR_KEY1_UPPER ); +tegra_dc_commit (dc); }static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
drivers/gpu/drm/tegra/dc.h +6 -0
@@ -433,6 +433,12 @@#define DC_WIN_BLEND_2WIN_X 0x711#define DC_WIN_BLEND_2WIN_Y 0x712#define DC_WIN_BLEND_3WIN_XY 0x713 +#define DC_WIN_BLEND_CKEY0 (1 << 0) +#define DC_WIN_BLEND_CKEY1 (1 << 1) +#define DC_WIN_BLEND_CONTROL (x) ((x) << 2) +#define DC_WIN_BLEND_CONTROL_NOKEY (x) ((x) << 0) +#define DC_WIN_BLEND_WEIGHT0 (x) ((x) << 8) +#define DC_WIN_BLEND_WEIGHT1 (x) ((x) << 16)#define DC_WIN_HP_FETCH_CONTROL 0x714
drivers/gpu/drm/tegra/drm.c +159 -0
177 lines not on this page · raw message
drivers/gpu/drm/tegra/drm.h +14 -0
@@ -189,6 +189,11 @@ struct tegra_dc_window {struct tegra_bo_tiling tiling;u32 format;u32 swap; +u32 blend_nokey; +u32 blend_1win; +u32 blend_2win_x; +u32 blend_2win_y; +u32 blend_3win_xy; };/* from dc.c */
@@ -200,6 +205,15 @@ int tegra_dc_state_setup_clock(struct tegra_dc *dc,struct drm_crtc_state *crtc_state, struct clk *clk, unsigned long pclk, unsigned int div); +void tegra_dc_set_color_key (struct drm_crtc_state *crtc_state, +int key_id,u32 upper,u32 lower); +void tegra20_dc_plane_set_blending (struct drm_plane_state *plane_state, +unsigned int blend_config, +unsigned int blend_control, +unsigned int blend_weight0, +unsigned int blend_weight1, +bool use_color_key0, +bool use_color_key1);struct tegra_output {struct device_node *of_node;
include/uapi/drm/tegra_drm.h +34 -0
@@ -172,6 +172,36 @@ struct drm_tegra_gem_get_flags {__u32 flags; }; +struct drm_tegra_set_color_key { +/* input */ +__u32 crtc_mask;/* Display controllers to use that key */ +__u32 key_id;/* Specify what color key to set, 0 or 1 */ +__u32 upper;/* Color key itself in ARGB_8888 format */ +__u32 lower;/* in range lower..upper */ +}; + +#define DRM_TEGRA_PLANE_BLEND_CONFIG_NOKEY 0 +#define DRM_TEGRA_PLANE_BLEND_CONFIG_1WIN 1 +#define DRM_TEGRA_PLANE_BLEND_CONFIG_2WIN_X 2 +#define DRM_TEGRA_PLANE_BLEND_CONFIG_2WIN_Y 3 +#define DRM_TEGRA_PLANE_BLEND_CONFIG_3WIN_XY 4 + +#define DRM_TEGRA_PLANE_BLEND_CONTROL_FIX_WEIGHT 0 +#define DRM_TEGRA_PLANE_BLEND_CONTROL_ALPHA_WEIGHT 1 +#define DRM_TEGRA_PLANE_BLEND_CONTROL_DEPENDENT_WEIGHT 2 + +struct drm_tegra20_plane_set_blending { +/* input */ +__u32 plane_id; +__u32 blend_config;/* Specify blending configuration to set */ +__u32 blend_control; +__u32 blend_weight0; +__u32 blend_weight1; +__u32 use_color_key0;/* Ignored by the NOKEY blending config */ +__u32 use_color_key1;/* Ignored by the NOKEY blending config */ +__u32 pad; +}; +#define DRM_TEGRA_GEM_CREATE 0x00#define DRM_TEGRA_GEM_MMAP 0x01#define DRM_TEGRA_SYNCPT_READ 0x02
@@ -186,6 +216,8 @@ struct drm_tegra_gem_get_flags {#define DRM_TEGRA_GEM_GET_TILING 0x0b#define DRM_TEGRA_GEM_SET_FLAGS 0x0c#define DRM_TEGRA_GEM_GET_FLAGS 0x0d +#define DRM_TEGRA_SET_COLOR_KEY 0x0e +#define DRM_TEGRA20_PLANE_SET_BLENDING 0x0f#define DRM_IOCTL_TEGRA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_CREATE, struct drm_tegra_gem_create)#define DRM_IOCTL_TEGRA_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_MMAP, struct drm_tegra_gem_mmap)
@@ -201,6 +233,8 @@ struct drm_tegra_gem_get_flags {#define DRM_IOCTL_TEGRA_GEM_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_TILING, struct drm_tegra_gem_get_tiling)#define DRM_IOCTL_TEGRA_GEM_SET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_SET_FLAGS, struct drm_tegra_gem_set_flags)#define DRM_IOCTL_TEGRA_GEM_GET_FLAGS DRM_IOWR(DRM_COMMAND_BASE + DRM_TEGRA_GEM_GET_FLAGS, struct drm_tegra_gem_get_flags) +#define DRM_IOCTL_TEGRA_SET_COLOR_KEY DRM_IOW(DRM_COMMAND_BASE + DRM_TEGRA_SET_COLOR_KEY, struct drm_tegra_set_color_key) +#define DRM_IOCTL_TEGRA20_PLANE_SET_BLENDING DRM_IOW(DRM_COMMAND_BASE + DRM_TEGRA20_PLANE_SET_BLENDING, struct drm_tegra20_plane_set_blending)#if defined(__cplusplus) }
Signature · 1 line
2.9.3
Quoted 5 lines · Dmitry Osipenko
Chromakey is a simple way of video overlay overlap implementation. This patch adds 2 new IOCTL's: first - sets color key and is common across of all Tegra SoC's, second - sets plane blending controls and allows to utilize the color key, this one is exclusive to Tegra20/30.
Quoted 8 lines
Signed-off-by Dmitry Osipenko <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 150 +++++++++++++++++++++++++++++++++------- drivers/gpu/drm/tegra/dc.h | 6 ++ drivers/gpu/drm/tegra/drm.c | 159 +++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 14 ++++ include/uapi/drm/tegra_drm.h | 34 +++++++++ 5 files changed, 337 insertions(+), 26 deletions(-)
I think these are really nice features to have, but these would need to be exposed as properties, rather than custom driver-specific IOCTLs. It seems to me like the colorkey feature could be implemented in much the same way as in the Armada, RCar and Nouveau drivers.
As for the blending options, I think they should be exposed in terms of the zpos property, to allow generic userspace to make use of them. Also can you explain why this needs to be exclusive to Tegra20 and Tegra30?
Thierry
Quoted 15 lines · Thierry Reding
Quoted 5 lines · Dmitry Osipenko
Chromakey is a simple way of video overlay overlap implementation. This patch adds 2 new IOCTL's: first - sets color key and is common across of all Tegra SoC's, second - sets plane blending controls and allows to utilize the color key, this one is exclusive to Tegra20/30.
Quoted 8 lines
Signed-off-by Dmitry Osipenko <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 150 +++++++++++++++++++++++++++++++++------- drivers/gpu/drm/tegra/dc.h | 6 ++ drivers/gpu/drm/tegra/drm.c | 159 +++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 14 ++++ include/uapi/drm/tegra_drm.h | 34 +++++++++ 5 files changed, 337 insertions(+), 26 deletions(-)
Quoted 8 lines
I think these are really nice features to have, but these would need to be exposed as properties, rather than custom driver-specific IOCTLs. It seems to me like the colorkey feature could be implemented in much the same way as in the Armada, RCar and Nouveau drivers.
As for the blending options, I think they should be exposed in terms of the zpos property, to allow generic userspace to make use of them. Also can you explain why this needs to be exclusive to Tegra20 and Tegra30?
Ah... I just realized that the blending interface changed on Tegra124. All the more reason to expose this more generically, that way we can hide the differences between a property and support the same interface across all generations of Tegra.
Also see this:
https://chromium.googlesource.com/chromiumos/third_party/kernel/+/de9295aabdb7f80555c9b77b29ac77bcdac3280b
Thierry
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 16 lines · Thierry Reding
Quoted 15 lines · Thierry Reding
Quoted 13 lines · Dmitry Osipenko
Chromakey is a simple way of video overlay overlap implementation. This patch adds 2 new IOCTL's: first - sets color key and is common across of all Tegra SoC's, second - sets plane blending controls and allows to utilize the color key, this one is exclusive to Tegra20/30.
Signed-off-by Dmitry Osipenko <[email protected]>--- drivers/gpu/drm/tegra/dc.c | 150 +++++++++++++++++++++++++++++++++------- drivers/gpu/drm/tegra/dc.h | 6 ++ drivers/gpu/drm/tegra/drm.c | 159 +++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/tegra/drm.h | 14 ++++ include/uapi/drm/tegra_drm.h | 34 +++++++++ 5 files changed, 337 insertions(+), 26 deletions(-)
Quoted 5 lines
Quoted 5 lines
I think these are really nice features to have, but these would need to be exposed as properties, rather than custom driver-specific IOCTLs. It seems to me like the colorkey feature could be implemented in much the same way as in the Armada, RCar and Nouveau drivers.
Now, instead of custom driver-specific IOCTL's we would have custom driver-specific DRM object properties. I'm not sure how they should be represented.
Should we assume that primary plane is the only source of colorkey? On Tegra, colorkey isn't matched against the underlying plane, it represents area on the plane (that uses that colorkey) that should be blended. In case of Xv, I have to enable colorkey matching for the primary plane and make transparent areas of the primary plane where colorkey matches and overlapped by the overlay, areas that are overlapped and NOT matching colorkey are displayed on top of the overlay (like mouse cursor or some window).
Should we assign colorkey (0xkey value itself) property per overlay plane? WIN_B will use colokey0, WIN_C colorkey1.
Or make colorkey values property of CRTC? So it would be possible (probably not so useful) to have 2 color keys used for one overlay.
Should colorkey be enabled/disabled via properties? I.e. it will be "use_colorkey" plane property. Feels a bit icky to me.
I see only DRM_IOCTL_MODE_OBJ_SETPROPERTY, so no way to set all properties at once?
Quoted 3 lines
Quoted 3 lines
As for the blending options, I think they should be exposed in terms of the zpos property, to allow generic userspace to make use of them. Also can you explain why this needs to be exclusive to Tegra20 and Tegra30?
What about the actual alpha blending? What about having different blending modes?
Should we sacrifice it all and support only 1-2 use cases?
Given that properties are specific to each driver, I can hardly imagine such generic userspace. Could you give an example?
Quoted 9 lines
Ah... I just realized that the blending interface changed on Tegra124. All the more reason to expose this more generically, that way we can hide the differences between a property and support the same interface across all generations of Tegra.
Also see this:
https://chromium.googlesource.com/chromiumos/third_party/kernel/+/de9295aabdb7f80555c9b77b29ac77bcdac3280b
Signature · 1 line
Dmitry