Hi,
This serie aims at enhancing the support for our planes in the current drm
driver on the first generation of Allwinner's display engine.
This also introduces a few generic stuff, as well as some conversion for
some other drivers.
This series basically implements three things that look orthogonal, but due
to the way the hardware works are kind of related.
The main feature is that instead of implementing 2 planes per backend, we
are now able to use the planes that are available in hardware. This was
unsupported before because of the way the composition works in the
hardware.
Indeed, the planes are first grouped into 2 pipes that are doing a basic
composition, in case of overlapping planes, it just takes whatever plane
has the highest priority (=> zpos). Then, the alpha blending is done
between the two pipes. This was simplified so far by only using two planes,
one for each pipe, which was allowing us to have an illusion of proper
alpha blending. This is further complicated by the bug/feature that the
lowest plane must not have any alpha at all, otherwise the pixel will turn
black, no matter what the value of alpha is. This basically means that we
can have a plane with alpha only in the second pipe.
However, as we have more and more blocks being worked on, 2 planes are
getting really limited and we need to support all 4 of them.
This is mostly possible by extending our atomic_check and to make sure that
we enforce those constraints, and assign the pipes automatically. This is
done by looking at the number of planes using an alpha component, and we
then end up in various scenarios:
- 0 plane with alpha
=> we don't care for the pipes at all. All the planes are assigned to
the first pipe
- 1 plane with alpha
=> we assign all the planes without alpha below the plane with alpha to
the first pipe, and then all the remaining planes to the second
pipe. The plane with alpha will be the lowest plane on that pipe,
which means that whatever plane is above it will have precedence,
but the alpha component will remain and will be used on pixels that
are not overlapping
- 2-4 planes with alpha
=> we can't operate that way, we just reject the configuration.
In addition to the formats that embed an alpha component, we also add
support for plane-wide alpha property, and in order to tweak the
configuration the way we want to, we also add support for configurable
zpos.
Let me know what you think,
Maxime
Maxime Ripard (19):
drm/fourcc: Add a function to tell if the format embeds alpha
drm/atmel-hlcdc: Use the alpha format helper
drm/exynos: Use the alpha format helper
drm/rockchip: Use the alpha format helper
drm/vc4: Use the alpha format helper
drm/blend: Add a generic alpha property
drm/atmel-hclcdc: Convert to the new generic alpha property
drm/rcar-du: Convert to the new generic alpha property
drm/sun4i: backend: Fix structure indentation
drm/sun4i: backend: Fix define typo
drm/sun4i: framebuffer: Add a custom atomic_check
drm/sun4i: backend: Move the coord function in the shared part
drm/sun4i: backend: Set a default zpos in our reset hook
drm/sun4i: backend: Add support for zpos
drm/sun4i: backend: Check for the number of alpha planes
drm/sun4i: backend: Assign the pipes automatically
drm/sun4i: backend: Make zpos configurable
drm/sun4i: Add support for plane alpha
drm/sun4i: backend: Remove ARGB spoofing
Documentation/gpu/kms-properties.csv | 2 +-
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 13 +--
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 109 ++-------------
drivers/gpu/drm/drm_atomic.c | 4 +-
drivers/gpu/drm/drm_atomic_helper.c | 1 +-
drivers/gpu/drm/drm_blend.c | 32 ++++-
drivers/gpu/drm/drm_fourcc.c | 43 ++++++-
drivers/gpu/drm/exynos/exynos_mixer.c | 14 +--
drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 +-
drivers/gpu/drm/rcar-du/rcar_du_kms.c | 5 +-
drivers/gpu/drm/rcar-du/rcar_du_plane.c | 15 +--
drivers/gpu/drm/rcar-du/rcar_du_plane.h | 2 +-
drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 42 +------
drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +-
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 +--
drivers/gpu/drm/sun4i/sun4i_backend.c | 126 +++++++++++++++--
drivers/gpu/drm/sun4i/sun4i_backend.h | 11 +-
drivers/gpu/drm/sun4i/sun4i_framebuffer.c | 18 +-
drivers/gpu/drm/sun4i/sun4i_layer.c | 84 ++---------
drivers/gpu/drm/sun4i/sun4i_layer.h | 1 +-
drivers/gpu/drm/vc4/vc4_plane.c | 19 +--
include/drm/drm_blend.h | 1 +-
include/drm/drm_fourcc.h | 1 +-
include/drm/drm_plane.h | 6 +-
24 files changed, 289 insertions(+), 276 deletions(-)
base-commit: 53b519deaf2e507b121b64abcb4ba0da075bd6a7
--
git-series 0.9.1
There was a typo in the width spelling of the (unused)
SUN4I_BACKEND_IYUVLINEWITDTH_REG macro. Fix it.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_backend.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index b5edf2d50a24..1ca8b7db6807 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -112,7 +112,9 @@
#define SUN4I_BACKEND_SPRALPHACTL_REG 0x90c
#define SUN4I_BACKEND_IYUVCTL_REG 0x920
#define SUN4I_BACKEND_IYUVADD_REG(c) (0x930 + (0x4 * (c)))
-#define SUN4I_BACKEND_IYUVLINEWITDTH_REG(c) (0x940 + (0x4 * (c)))
+
+#define SUN4I_BACKEND_IYUVLINEWIDTH_REG(c) (0x940 + (0x4 * (c)))
+
#define SUN4I_BACKEND_YGCOEF_REG(c) (0x950 + (0x4 * (c)))
#define SUN4I_BACKEND_YGCONS_REG 0x95c
#define SUN4I_BACKEND_URCOEF_REG(c) (0x960 + (0x4 * (c)))
--
git-series 0.9.1
In order to support normalized zpos, we need to call
drm_atomic_normalize_zpos in our driver's drm_mode_config_funcs'
atomic_check.
Let's duplicate the definition of drm_atomic_helper_check for now.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_framebuffer.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c
index a01a5b7d46e6..e68004844abe 100644
--- a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c
@@ -26,9 +26,21 @@ static void sun4i_de_output_poll_changed(struct drm_device *drm)
drm_fbdev_cma_hotplug_event(drv->fbdev);
}
+static int sun4i_de_atomic_check(struct drm_device *dev,
+ struct drm_atomic_state *state)
+{
+ int ret;
+
+ ret = drm_atomic_helper_check_modeset(dev, state);
+ if (ret)
+ return ret;
+
+ return drm_atomic_helper_check_planes(dev, state);
+}
+
static const struct drm_mode_config_funcs sun4i_de_mode_config_funcs = {
.output_poll_changed = sun4i_de_output_poll_changed,
- .atomic_check = drm_atomic_helper_check,
+ .atomic_check = sun4i_de_atomic_check,
.atomic_commit = drm_atomic_helper_commit,
.fb_create = drm_gem_fb_create,
};
--
git-series 0.9.1
The function supposed to update a plane's coordinates is called in both
branches of our function. Let's move it out the if statement.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_layer.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index f03da16eb92a..c448cb6b9fa9 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -106,14 +106,13 @@ static void sun4i_backend_layer_atomic_update(struct drm_plane *plane,
DRM_FORMAT_ARGB8888);
sun4i_backend_update_layer_frontend(backend, layer->id,
DRM_FORMAT_ARGB8888);
- sun4i_backend_update_layer_coord(backend, layer->id, plane);
sun4i_frontend_enable(frontend);
} else {
- sun4i_backend_update_layer_coord(backend, layer->id, plane);
sun4i_backend_update_layer_formats(backend, layer->id, plane);
sun4i_backend_update_layer_buffer(backend, layer->id, plane);
}
+ sun4i_backend_update_layer_coord(backend, layer->id, plane);
sun4i_backend_layer_enable(backend, layer->id, true);
}
--
git-series 0.9.1
Now that the core has a drm format helper to tell if a format embeds an
alpha component in it, let's use it.
Cc: Boris Brezillon <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 20 ++----------------
1 file changed, 3 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 703c2d13603f..1a9318810a29 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -194,20 +194,6 @@ static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode)
return 0;
}
-static bool atmel_hlcdc_format_embeds_alpha(u32 format)
-{
- int i;
-
- for (i = 0; i < sizeof(format); i++) {
- char tmp = (format >> (8 * i)) & 0xff;
-
- if (tmp == 'A')
- return true;
- }
-
- return false;
-}
-
static u32 heo_downscaling_xcoef[] = {
0x11343311,
0x000000f7,
@@ -395,7 +381,7 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
cfg |= ATMEL_HLCDC_LAYER_OVR | ATMEL_HLCDC_LAYER_ITER2BL |
ATMEL_HLCDC_LAYER_ITER;
- if (atmel_hlcdc_format_embeds_alpha(format))
+ if (drm_format_has_alpha(format))
cfg |= ATMEL_HLCDC_LAYER_LAEN;
else
cfg |= ATMEL_HLCDC_LAYER_GAEN |
@@ -566,7 +552,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state)
ovl_state = drm_plane_state_to_atmel_hlcdc_plane_state(ovl_s);
if (!ovl_s->fb ||
- atmel_hlcdc_format_embeds_alpha(ovl_s->fb->format->format) ||
+ drm_format_has_alpha(ovl_s->fb->format->format) ||
ovl_state->alpha != 255)
continue;
@@ -769,7 +755,7 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
if ((state->crtc_h != state->src_h || state->crtc_w != state->src_w) &&
(!desc->layout.memsize ||
- atmel_hlcdc_format_embeds_alpha(state->base.fb->format->format)))
+ drm_format_has_alpha(state->base.fb->format->format)))
return -EINVAL;
if (state->crtc_x < 0 || state->crtc_y < 0)
--
git-series 0.9.1
The sun4i_plane_desc structure was somehow indented to two tabulations
instead of one as we shoud do. Fix that.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_layer.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 4652b25be0d2..f03da16eb92a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -20,10 +20,10 @@
#include "sunxi_engine.h"
struct sun4i_plane_desc {
- enum drm_plane_type type;
- u8 pipe;
- const uint32_t *formats;
- uint32_t nformats;
+ enum drm_plane_type type;
+ u8 pipe;
+ const uint32_t *formats;
+ uint32_t nformats;
};
static void sun4i_backend_layer_reset(struct drm_plane *plane)
--
git-series 0.9.1
Now that we have support for per-plane alpha in the core, let's use it.
Cc: Laurent Pinchart <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 +-
drivers/gpu/drm/rcar-du/rcar_du_kms.c | 5 +---
drivers/gpu/drm/rcar-du/rcar_du_plane.c | 15 +++------
drivers/gpu/drm/rcar-du/rcar_du_plane.h | 2 +-
drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 42 ++------------------------
drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +-
6 files changed, 9 insertions(+), 58 deletions(-)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index f8cd79488ece..aff04adaae53 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -89,7 +89,6 @@ struct rcar_du_device {
struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
struct {
- struct drm_property *alpha;
struct drm_property *colorkey;
} props;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index 566d1a948c8f..e1b5a7b460cc 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -417,11 +417,6 @@ static int rcar_du_encoders_init(struct rcar_du_device *rcdu)
static int rcar_du_properties_init(struct rcar_du_device *rcdu)
{
- rcdu->props.alpha =
- drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255);
- if (rcdu->props.alpha == NULL)
- return -ENOMEM;
-
/*
* The color key is expressed as an RGB888 triplet stored in a 32-bit
* integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 61833cc1c699..5b34e8092c8b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -423,7 +423,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_group *rgrp,
rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0);
else
rcar_du_plane_write(rgrp, index, PnALPHAR,
- PnALPHAR_ABIT_X | state->alpha);
+ PnALPHAR_ABIT_X | state->state.alpha);
pnmr = PnMR_BM_MD | state->format->pnmr;
@@ -667,11 +667,11 @@ static void rcar_du_plane_reset(struct drm_plane *plane)
state->hwindex = -1;
state->source = RCAR_DU_PLANE_MEMORY;
- state->alpha = 255;
state->colorkey = RCAR_DU_COLORKEY_NONE;
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
plane->state = &state->state;
+ plane->state->alpha = 255;
plane->state->plane = plane;
}
@@ -683,9 +683,7 @@ static int rcar_du_plane_atomic_set_property(struct drm_plane *plane,
struct rcar_du_plane_state *rstate = to_rcar_plane_state(state);
struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev;
- if (property == rcdu->props.alpha)
- rstate->alpha = val;
- else if (property == rcdu->props.colorkey)
+ if (property == rcdu->props.colorkey)
rstate->colorkey = val;
else
return -EINVAL;
@@ -701,9 +699,7 @@ static int rcar_du_plane_atomic_get_property(struct drm_plane *plane,
container_of(state, const struct rcar_du_plane_state, state);
struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev;
- if (property == rcdu->props.alpha)
- *val = rstate->alpha;
- else if (property == rcdu->props.colorkey)
+ if (property == rcdu->props.colorkey)
*val = rstate->colorkey;
else
return -EINVAL;
@@ -772,10 +768,9 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
continue;
drm_object_attach_property(&plane->plane.base,
- rcdu->props.alpha, 255);
- drm_object_attach_property(&plane->plane.base,
rcdu->props.colorkey,
RCAR_DU_COLORKEY_NONE);
+ drm_plane_create_alpha_property(&plane->plane, 255);
drm_plane_create_zpos_property(&plane->plane, 1, 1, 7);
}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
index f62e09f195de..2dc793ebd1a2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
@@ -50,7 +50,6 @@ static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane)
* @state: base DRM plane state
* @format: information about the pixel format used by the plane
* @hwindex: 0-based hardware plane index, -1 means unused
- * @alpha: value of the plane alpha property
* @colorkey: value of the plane colorkey property
*/
struct rcar_du_plane_state {
@@ -60,7 +59,6 @@ struct rcar_du_plane_state {
int hwindex;
enum rcar_du_plane_source source;
- unsigned int alpha;
unsigned int colorkey;
};
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 2c96147bc444..ee85f6fdffad 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -54,6 +54,7 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
};
struct rcar_du_plane_state state = {
.state = {
+ .alpha = 255,
.crtc = &crtc->crtc,
.crtc_x = 0,
.crtc_y = 0,
@@ -67,7 +68,6 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
},
.format = rcar_du_format_info(DRM_FORMAT_ARGB8888),
.source = RCAR_DU_PLANE_VSPD1,
- .alpha = 255,
.colorkey = 0,
};
@@ -173,7 +173,7 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
struct vsp1_du_atomic_config cfg = {
.pixelformat = 0,
.pitch = fb->pitches[0],
- .alpha = state->alpha,
+ .alpha = state->state.alpha,
.zpos = state->state.zpos,
};
unsigned int i;
@@ -351,44 +351,13 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane)
if (state == NULL)
return;
- state->alpha = 255;
+ state->state.alpha = 255;
state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
plane->state = &state->state;
plane->state->plane = plane;
}
-static int rcar_du_vsp_plane_atomic_set_property(struct drm_plane *plane,
- struct drm_plane_state *state, struct drm_property *property,
- uint64_t val)
-{
- struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
- struct rcar_du_device *rcdu = to_rcar_vsp_plane(plane)->vsp->dev;
-
- if (property == rcdu->props.alpha)
- rstate->alpha = val;
- else
- return -EINVAL;
-
- return 0;
-}
-
-static int rcar_du_vsp_plane_atomic_get_property(struct drm_plane *plane,
- const struct drm_plane_state *state, struct drm_property *property,
- uint64_t *val)
-{
- const struct rcar_du_vsp_plane_state *rstate =
- container_of(state, const struct rcar_du_vsp_plane_state, state);
- struct rcar_du_device *rcdu = to_rcar_vsp_plane(plane)->vsp->dev;
-
- if (property == rcdu->props.alpha)
- *val = rstate->alpha;
- else
- return -EINVAL;
-
- return 0;
-}
-
static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane,
@@ -396,8 +365,6 @@ static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
.destroy = drm_plane_cleanup,
.atomic_duplicate_state = rcar_du_vsp_plane_atomic_duplicate_state,
.atomic_destroy_state = rcar_du_vsp_plane_atomic_destroy_state,
- .atomic_set_property = rcar_du_vsp_plane_atomic_set_property,
- .atomic_get_property = rcar_du_vsp_plane_atomic_get_property,
};
int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
@@ -454,8 +421,7 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
if (type == DRM_PLANE_TYPE_PRIMARY)
continue;
- drm_object_attach_property(&plane->plane.base,
- rcdu->props.alpha, 255);
+ drm_plane_create_alpha_property(&plane->plane, 255);
drm_plane_create_zpos_property(&plane->plane, 1, 1,
vsp->num_planes - 1);
}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
index f876c512163c..8b19914761e4 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
@@ -44,7 +44,6 @@ static inline struct rcar_du_vsp_plane *to_rcar_vsp_plane(struct drm_plane *p)
* @state: base DRM plane state
* @format: information about the pixel format used by the plane
* @sg_tables: scatter-gather tables for the frame buffer memory
- * @alpha: value of the plane alpha property
* @zpos: value of the plane zpos property
*/
struct rcar_du_vsp_plane_state {
@@ -53,7 +52,6 @@ struct rcar_du_vsp_plane_state {
const struct rcar_du_format_info *format;
struct sg_table sg_tables[3];
- unsigned int alpha;
unsigned int zpos;
};
--
git-series 0.9.1
Our backend supports a per-plane alpha property. Support it through our new
helper.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_backend.c | 18 +++++++++++++++---
drivers/gpu/drm/sun4i/sun4i_backend.h | 3 +++
drivers/gpu/drm/sun4i/sun4i_layer.c | 2 ++
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index ad370ce66b4d..ec47098bfdb2 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -191,6 +191,15 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n",
interlaced ? "on" : "off");
+ val = SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA(state->alpha);
+ if (state->alpha != 255)
+ val |= SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_EN;
+ regmap_update_bits(backend->engine.regs,
+ SUN4I_BACKEND_ATTCTL_REG0(layer),
+ SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_MASK |
+ SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_EN,
+ val);
+
ret = sun4i_backend_drm_format_to_layer(plane, fb->format->format,
&val);
if (ret) {
@@ -366,7 +375,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
DRM_DEBUG_DRIVER("Plane FB format is %s\n",
drm_get_format_name(fb->format->format,
&format_name));
- if (drm_format_has_alpha(fb->format->format))
+ if (drm_format_has_alpha(fb->format->format) ||
+ (plane_state->alpha != 255))
num_alpha_planes++;
DRM_DEBUG_DRIVER("Plane zpos is %d\n",
@@ -419,7 +429,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
}
/* We can't have an alpha plane at the lowest position */
- if (drm_format_has_alpha(plane_states[0]->fb->format->format))
+ if (drm_format_has_alpha(plane_states[0]->fb->format->format) ||
+ (plane_states[0]->alpha != 255))
return -EINVAL;
for (i = 1; i < num_planes; i++) {
@@ -431,7 +442,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
* The only alpha position is the lowest plane of the
* second pipe.
*/
- if (drm_format_has_alpha(fb->format->format))
+ if (drm_format_has_alpha(fb->format->format) ||
+ (p_state->alpha != 255))
current_pipe++;
s_state->pipe = current_pipe;
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index 52e77591186a..03294d5dd1a2 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -68,11 +68,14 @@
#define SUN4I_BACKEND_CKMIN_REG 0x884
#define SUN4I_BACKEND_CKCFG_REG 0x888
#define SUN4I_BACKEND_ATTCTL_REG0(l) (0x890 + (0x4 * (l)))
+#define SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_MASK GENMASK(31, 24)
+#define SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA(x) ((x) << 24)
#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK BIT(15)
#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(x) ((x) << 15)
#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK GENMASK(11, 10)
#define SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(x) ((x) << 10)
#define SUN4I_BACKEND_ATTCTL_REG0_LAY_VDOEN BIT(1)
+#define SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_EN BIT(0)
#define SUN4I_BACKEND_ATTCTL_REG1(l) (0x8a0 + (0x4 * (l)))
#define SUN4I_BACKEND_ATTCTL_REG1_LAY_HSCAFCT GENMASK(15, 14)
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 9e538f761dcb..d5598de92f85 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -37,6 +37,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane)
if (state) {
plane->state = &state->state;
plane->state->plane = plane;
+ plane->state->alpha = 255;
plane->state->zpos = layer->id;
}
}
@@ -163,6 +164,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
&sun4i_backend_layer_helper_funcs);
layer->backend = backend;
+ drm_plane_create_alpha_property(&layer->plane, 255);
drm_plane_create_zpos_property(&layer->plane, 0, 0,
SUN4I_BACKEND_NUM_LAYERS - 1);
--
git-series 0.9.1
Our various planes have a configurable zpos, that combined with the pipes
allow to configure the composition.
Since the interaction between the pipes, zpos and alphas framebuffers are
not trivials, let's just enable the zpos as an immutable property for now,
and use that zpos in our atomic_update part.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_backend.c | 15 +++++++++++++++
drivers/gpu/drm/sun4i/sun4i_backend.h | 2 ++
drivers/gpu/drm/sun4i/sun4i_framebuffer.c | 4 ++++
drivers/gpu/drm/sun4i/sun4i_layer.c | 3 +++
4 files changed, 24 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index a18c86a15748..c4986054909b 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -272,6 +272,21 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
return 0;
}
+int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer,
+ struct drm_plane *plane)
+{
+ struct drm_plane_state *state = plane->state;
+ unsigned int priority = state->normalized_zpos;
+
+ DRM_DEBUG_DRIVER("Setting layer %d priority to %d\n", layer, priority);
+
+ regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
+ SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK,
+ SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(priority));
+
+ return 0;
+}
+
static bool sun4i_backend_plane_uses_scaler(struct drm_plane_state *state)
{
u16 src_h = state->src_h >> 16;
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index 1ca8b7db6807..04a4f11b87a8 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -182,5 +182,7 @@ int sun4i_backend_update_layer_buffer(struct sun4i_backend *backend,
int layer, struct drm_plane *plane);
int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend,
int layer, uint32_t in_fmt);
+int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend,
+ int layer, struct drm_plane *plane);
#endif /* _SUN4I_BACKEND_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c
index e68004844abe..5b3986437a50 100644
--- a/drivers/gpu/drm/sun4i/sun4i_framebuffer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_framebuffer.c
@@ -35,6 +35,10 @@ static int sun4i_de_atomic_check(struct drm_device *dev,
if (ret)
return ret;
+ ret = drm_atomic_normalize_zpos(dev, state);
+ if (ret)
+ return ret;
+
return drm_atomic_helper_check_planes(dev, state);
}
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 03549646528a..fbf25d59cf88 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -115,6 +115,7 @@ static void sun4i_backend_layer_atomic_update(struct drm_plane *plane,
}
sun4i_backend_update_layer_coord(backend, layer->id, plane);
+ sun4i_backend_update_layer_zpos(backend, layer->id, plane);
sun4i_backend_layer_enable(backend, layer->id, true);
}
@@ -237,6 +238,8 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm,
return ERR_CAST(layer);
};
+ drm_plane_create_zpos_immutable_property(&layer->plane, i);
+
DRM_DEBUG_DRIVER("Assigning %s plane to pipe %d\n",
i ? "overlay" : "primary", plane->pipe);
regmap_update_bits(engine->regs, SUN4I_BACKEND_ATTCTL_REG0(i),
--
git-series 0.9.1
Due to the way the composition is done in hardware, we can only have a
single alpha-enabled plane active at a time, placed in the second (highest
priority) pipe.
Make sure of that in our atomic_check to not end up in an impossible
scenario.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_backend.c | 50 ++++++++++++++++++++++++++++-
drivers/gpu/drm/sun4i/sun4i_backend.h | 2 +-
drivers/gpu/drm/sun4i/sun4i_layer.c | 23 +-------------
3 files changed, 53 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index c4986054909b..dd995a6b8b12 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -329,6 +329,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
struct drm_atomic_state *state = crtc_state->state;
struct drm_device *drm = state->dev;
struct drm_plane *plane;
+ unsigned int num_planes = 0;
+ unsigned int num_alpha_planes = 0;
unsigned int num_frontend_planes = 0;
DRM_DEBUG_DRIVER("Starting checking our planes\n");
@@ -341,6 +343,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
drm_atomic_get_plane_state(state, plane);
struct sun4i_layer_state *layer_state =
state_to_sun4i_layer_state(plane_state);
+ struct drm_framebuffer *fb = plane_state->fb;
if (sun4i_backend_plane_uses_frontend(plane_state)) {
DRM_DEBUG_DRIVER("Using the frontend for plane %d\n",
@@ -351,6 +354,50 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
} else {
layer_state->uses_frontend = false;
}
+
+ DRM_DEBUG_DRIVER("Plane FB format is %s\n",
+ drm_get_format_name(fb->format->format,
+ &format_name));
+ if (drm_format_has_alpha(fb->format->format))
+ num_alpha_planes++;
+
+ num_planes++;
+ }
+
+ /*
+ * The hardware is a bit unusual here.
+ *
+ * Even though it supports 4 layers, it does the composition
+ * in two separate steps.
+ *
+ * The first one is assigning a layer to one of its two
+ * pipes. If more that 1 layer is assigned to the same pipe,
+ * and if pixels overlaps, the pipe will take the pixel from
+ * the layer with the highest priority.
+ *
+ * The second step is the actual alpha blending, that takes
+ * the two pipes as input, and uses the eventual alpha
+ * component to do the transparency between the two.
+ *
+ * This two steps scenario makes us unable to guarantee a
+ * robust alpha blending between the 4 layers in all
+ * situations, since this means that we need to have one layer
+ * with alpha at the lowest position of our two pipes.
+ *
+ * However, we cannot even do that, since the hardware has a
+ * bug where the lowest plane of the lowest pipe (pipe 0,
+ * priority 0), if it has any alpha, will discard the pixel
+ * entirely and just display the pixels in the background
+ * color (black by default).
+ *
+ * Since means that we effectively have only three valid
+ * configurations with alpha, all of them with the alpha being
+ * on pipe1 with the lowest position, which can be 1, 2 or 3
+ * depending on the number of planes and their zpos.
+ */
+ if (num_alpha_planes > SUN4I_BACKEND_NUM_ALPHA_LAYERS) {
+ DRM_DEBUG_DRIVER("Too many planes with alpha, rejecting...\n");
+ return -EINVAL;
}
if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) {
@@ -358,6 +405,9 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
return -EINVAL;
}
+ DRM_DEBUG_DRIVER("State valid with %u planes, %u alpha, %u video\n",
+ num_planes, num_alpha_planes, num_frontend_planes);
+
return 0;
}
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.h b/drivers/gpu/drm/sun4i/sun4i_backend.h
index 04a4f11b87a8..52e77591186a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.h
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.h
@@ -146,6 +146,8 @@
#define SUN4I_BACKEND_HWCCOLORTAB_OFF 0x4c00
#define SUN4I_BACKEND_PIPE_OFF(p) (0x5000 + (0x400 * (p)))
+#define SUN4I_BACKEND_NUM_LAYERS 4
+#define SUN4I_BACKEND_NUM_ALPHA_LAYERS 1
#define SUN4I_BACKEND_NUM_FRONTEND_LAYERS 1
struct sun4i_backend {
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index fbf25d59cf88..900e716443b8 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -201,32 +201,11 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm,
struct sun4i_backend *backend = engine_to_sun4i_backend(engine);
int i;
- planes = devm_kcalloc(drm->dev, ARRAY_SIZE(sun4i_backend_planes) + 1,
+ planes = devm_kcalloc(drm->dev, SUN4I_BACKEND_NUM_LAYERS,
sizeof(*planes), GFP_KERNEL);
if (!planes)
return ERR_PTR(-ENOMEM);
- /*
- * The hardware is a bit unusual here.
- *
- * Even though it supports 4 layers, it does the composition
- * in two separate steps.
- *
- * The first one is assigning a layer to one of its two
- * pipes. If more that 1 layer is assigned to the same pipe,
- * and if pixels overlaps, the pipe will take the pixel from
- * the layer with the highest priority.
- *
- * The second step is the actual alpha blending, that takes
- * the two pipes as input, and uses the eventual alpha
- * component to do the transparency between the two.
- *
- * This two steps scenario makes us unable to guarantee a
- * robust alpha blending between the 4 layers in all
- * situations. So we just expose two layers, one per pipe. On
- * SoCs that support it, sprites could fill the need for more
- * layers.
- */
for (i = 0; i < ARRAY_SIZE(sun4i_backend_planes); i++) {
const struct sun4i_plane_desc *plane = &sun4i_backend_planes[i];
struct sun4i_layer *layer;
--
git-series 0.9.1
Now that we have everything in place, we can make zpos configurable now.
Change the zpos property from an immutable one to a regular.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_layer.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index ec7b906dbb84..9e538f761dcb 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -163,6 +163,9 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
&sun4i_backend_layer_helper_funcs);
layer->backend = backend;
+ drm_plane_create_zpos_property(&layer->plane, 0, 0,
+ SUN4I_BACKEND_NUM_LAYERS - 1);
+
return layer;
}
@@ -189,8 +192,6 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm,
return ERR_CAST(layer);
};
- drm_plane_create_zpos_immutable_property(&layer->plane, i);
-
layer->id = i;
planes[i] = &layer->plane;
};
--
git-series 0.9.1
We've had some code for quite some time to prevent the alpha bug from
happening on the lowest primary plane. Since we now check for this in our
atomic_check, we can simply remove it.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_backend.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index ec47098bfdb2..15a7bce27412 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -92,13 +92,8 @@ void sun4i_backend_layer_enable(struct sun4i_backend *backend,
SUN4I_BACKEND_MODCTL_LAY_EN(layer), val);
}
-static int sun4i_backend_drm_format_to_layer(struct drm_plane *plane,
- u32 format, u32 *mode)
+static int sun4i_backend_drm_format_to_layer(u32 format, u32 *mode)
{
- if (plane && (plane->type == DRM_PLANE_TYPE_PRIMARY) &&
- (format == DRM_FORMAT_ARGB8888))
- format = DRM_FORMAT_XRGB8888;
-
switch (format) {
case DRM_FORMAT_ARGB8888:
*mode = SUN4I_BACKEND_LAY_FBFMT_ARGB8888;
@@ -200,8 +195,7 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend,
SUN4I_BACKEND_ATTCTL_REG0_LAY_GLBALPHA_EN,
val);
- ret = sun4i_backend_drm_format_to_layer(plane, fb->format->format,
- &val);
+ ret = sun4i_backend_drm_format_to_layer(fb->format->format, &val);
if (ret) {
DRM_DEBUG_DRIVER("Invalid format\n");
return ret;
@@ -220,7 +214,7 @@ int sun4i_backend_update_layer_frontend(struct sun4i_backend *backend,
u32 val;
int ret;
- ret = sun4i_backend_drm_format_to_layer(NULL, fmt, &val);
+ ret = sun4i_backend_drm_format_to_layer(fmt, &val);
if (ret) {
DRM_DEBUG_DRIVER("Invalid format\n");
return ret;
--
git-series 0.9.1
Since we now have a way to enforce the zpos, check for the number of alpha
planes, the only missing part is to assign our pipe automatically instead
of hardcoding it.
The algorithm is quite simple, but requires two iterations over the list of
planes.
In the first one (which is the same one that we've had to check for alpha,
the frontend usage, and so on), we order the planes by their zpos.
We can then do a second iteration over that array by ascending zpos
starting with the pipe 0. When and if we encounter our alpha plane, we put
it and all the other subsequent planes in the second pipe.
And since we have runtime checks and pipe assignments now, we can just
remove the static declaration of the planes we used to have.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_backend.c | 41 +++++++++++++++++++++--
drivers/gpu/drm/sun4i/sun4i_layer.c | 50 ++++------------------------
drivers/gpu/drm/sun4i/sun4i_layer.h | 1 +-
3 files changed, 48 insertions(+), 44 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index dd995a6b8b12..ad370ce66b4d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -276,12 +276,16 @@ int sun4i_backend_update_layer_zpos(struct sun4i_backend *backend, int layer,
struct drm_plane *plane)
{
struct drm_plane_state *state = plane->state;
+ struct sun4i_layer_state *p_state = state_to_sun4i_layer_state(state);
unsigned int priority = state->normalized_zpos;
+ unsigned int pipe = p_state->pipe;
- DRM_DEBUG_DRIVER("Setting layer %d priority to %d\n", layer, priority);
-
+ DRM_DEBUG_DRIVER("Setting layer %d priority to %d and pipe %d\n",
+ layer, priority, pipe);
regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer),
+ SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK |
SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL_MASK,
+ SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(p_state->pipe) |
SUN4I_BACKEND_ATTCTL_REG0_LAY_PRISEL(priority));
return 0;
@@ -326,12 +330,15 @@ static void sun4i_backend_atomic_begin(struct sunxi_engine *engine,
static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
struct drm_crtc_state *crtc_state)
{
+ struct drm_plane_state *plane_states[SUN4I_BACKEND_NUM_LAYERS] = { 0 };
struct drm_atomic_state *state = crtc_state->state;
struct drm_device *drm = state->dev;
struct drm_plane *plane;
unsigned int num_planes = 0;
unsigned int num_alpha_planes = 0;
unsigned int num_frontend_planes = 0;
+ unsigned int current_pipe = 0;
+ unsigned int i;
DRM_DEBUG_DRIVER("Starting checking our planes\n");
@@ -344,6 +351,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
struct sun4i_layer_state *layer_state =
state_to_sun4i_layer_state(plane_state);
struct drm_framebuffer *fb = plane_state->fb;
+ struct drm_format_name_buf format_name;
if (sun4i_backend_plane_uses_frontend(plane_state)) {
DRM_DEBUG_DRIVER("Using the frontend for plane %d\n",
@@ -361,9 +369,19 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
if (drm_format_has_alpha(fb->format->format))
num_alpha_planes++;
+ DRM_DEBUG_DRIVER("Plane zpos is %d\n",
+ plane_state->normalized_zpos);
+
+ /* Sort our planes by Zpos */
+ plane_states[plane_state->normalized_zpos] = plane_state;
+
num_planes++;
}
+ /* All our planes were disabled, bail out */
+ if (!num_planes)
+ return 0;
+
/*
* The hardware is a bit unusual here.
*
@@ -400,6 +418,25 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
return -EINVAL;
}
+ /* We can't have an alpha plane at the lowest position */
+ if (drm_format_has_alpha(plane_states[0]->fb->format->format))
+ return -EINVAL;
+
+ for (i = 1; i < num_planes; i++) {
+ struct drm_plane_state *p_state = plane_states[i];
+ struct drm_framebuffer *fb = p_state->fb;
+ struct sun4i_layer_state *s_state = state_to_sun4i_layer_state(p_state);
+
+ /*
+ * The only alpha position is the lowest plane of the
+ * second pipe.
+ */
+ if (drm_format_has_alpha(fb->format->format))
+ current_pipe++;
+
+ s_state->pipe = current_pipe;
+ }
+
if (num_frontend_planes > SUN4I_BACKEND_NUM_FRONTEND_LAYERS) {
DRM_DEBUG_DRIVER("Too many planes going through the frontend, rejecting\n");
return -EINVAL;
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index 900e716443b8..ec7b906dbb84 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -19,13 +19,6 @@
#include "sun4i_layer.h"
#include "sunxi_engine.h"
-struct sun4i_plane_desc {
- enum drm_plane_type type;
- u8 pipe;
- const uint32_t *formats;
- uint32_t nformats;
-};
-
static void sun4i_backend_layer_reset(struct drm_plane *plane)
{
struct sun4i_layer *layer = plane_to_sun4i_layer(plane);
@@ -133,14 +126,7 @@ static const struct drm_plane_funcs sun4i_backend_layer_funcs = {
.update_plane = drm_atomic_helper_update_plane,
};
-static const uint32_t sun4i_backend_layer_formats_primary[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGB888,
- DRM_FORMAT_RGB565,
- DRM_FORMAT_XRGB8888,
-};
-
-static const uint32_t sun4i_backend_layer_formats_overlay[] = {
+static const uint32_t sun4i_backend_layer_formats[] = {
DRM_FORMAT_ARGB8888,
DRM_FORMAT_ARGB4444,
DRM_FORMAT_ARGB1555,
@@ -151,24 +137,9 @@ static const uint32_t sun4i_backend_layer_formats_overlay[] = {
DRM_FORMAT_XRGB8888,
};
-static const struct sun4i_plane_desc sun4i_backend_planes[] = {
- {
- .type = DRM_PLANE_TYPE_PRIMARY,
- .pipe = 0,
- .formats = sun4i_backend_layer_formats_primary,
- .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_primary),
- },
- {
- .type = DRM_PLANE_TYPE_OVERLAY,
- .pipe = 1,
- .formats = sun4i_backend_layer_formats_overlay,
- .nformats = ARRAY_SIZE(sun4i_backend_layer_formats_overlay),
- },
-};
-
static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
struct sun4i_backend *backend,
- const struct sun4i_plane_desc *plane)
+ enum drm_plane_type type)
{
struct sun4i_layer *layer;
int ret;
@@ -180,8 +151,9 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm,
/* possible crtcs are set later */
ret = drm_universal_plane_init(drm, &layer->plane, 0,
&sun4i_backend_layer_funcs,
- plane->formats, plane->nformats,
- NULL, plane->type, NULL);
+ sun4i_backend_layer_formats,
+ ARRAY_SIZE(sun4i_backend_layer_formats),
+ NULL, type, NULL);
if (ret) {
dev_err(drm->dev, "Couldn't initialize layer\n");
return ERR_PTR(ret);
@@ -206,11 +178,11 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm,
if (!planes)
return ERR_PTR(-ENOMEM);
- for (i = 0; i < ARRAY_SIZE(sun4i_backend_planes); i++) {
- const struct sun4i_plane_desc *plane = &sun4i_backend_planes[i];
+ for (i = 0; i < SUN4I_BACKEND_NUM_LAYERS; i++) {
+ enum drm_plane_type type = i ? DRM_PLANE_TYPE_OVERLAY : DRM_PLANE_TYPE_PRIMARY;
struct sun4i_layer *layer;
- layer = sun4i_layer_init_one(drm, backend, plane);
+ layer = sun4i_layer_init_one(drm, backend, type);
if (IS_ERR(layer)) {
dev_err(drm->dev, "Couldn't initialize %s plane\n",
i ? "overlay" : "primary");
@@ -219,12 +191,6 @@ struct drm_plane **sun4i_layers_init(struct drm_device *drm,
drm_plane_create_zpos_immutable_property(&layer->plane, i);
- DRM_DEBUG_DRIVER("Assigning %s plane to pipe %d\n",
- i ? "overlay" : "primary", plane->pipe);
- regmap_update_bits(engine->regs, SUN4I_BACKEND_ATTCTL_REG0(i),
- SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL_MASK,
- SUN4I_BACKEND_ATTCTL_REG0_LAY_PIPESEL(plane->pipe));
-
layer->id = i;
planes[i] = &layer->plane;
};
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.h b/drivers/gpu/drm/sun4i/sun4i_layer.h
index 75b4868ba87c..36b20265bd31 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.h
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.h
@@ -24,6 +24,7 @@ struct sun4i_layer {
struct sun4i_layer_state {
struct drm_plane_state state;
+ unsigned int pipe;
bool uses_frontend;
};
--
git-series 0.9.1
The our plane state zpos value will be set only if there's an existing
state attached to the plane when creating the property.
However, this is not the case during the probe, and we therefore need to
put our default value in our reset hook.
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/sun4i/sun4i_layer.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c
index c448cb6b9fa9..03549646528a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_layer.c
+++ b/drivers/gpu/drm/sun4i/sun4i_layer.c
@@ -28,6 +28,7 @@ struct sun4i_plane_desc {
static void sun4i_backend_layer_reset(struct drm_plane *plane)
{
+ struct sun4i_layer *layer = plane_to_sun4i_layer(plane);
struct sun4i_layer_state *state;
if (plane->state) {
@@ -43,6 +44,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane)
if (state) {
plane->state = &state->state;
plane->state->plane = plane;
+ plane->state->zpos = layer->id;
}
}
--
git-series 0.9.1
Now that we have support for per-plane alpha in the core, let's use it.
Cc: Boris Brezillon <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 13 +---
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 89 ++----------------
2 files changed, 14 insertions(+), 88 deletions(-)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index 6833ee253cfa..704cac6399eb 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -298,7 +298,6 @@ struct atmel_hlcdc_layer {
struct atmel_hlcdc_plane {
struct drm_plane base;
struct atmel_hlcdc_layer layer;
- struct atmel_hlcdc_plane_properties *properties;
};
static inline struct atmel_hlcdc_plane *
@@ -345,18 +344,6 @@ struct atmel_hlcdc_dc_desc {
};
/**
- * Atmel HLCDC Plane properties.
- *
- * This structure stores plane property definitions.
- *
- * @alpha: alpha blending (or transparency) property
- * @rotation: rotation property
- */
-struct atmel_hlcdc_plane_properties {
- struct drm_property *alpha;
-};
-
-/**
* Atmel HLCDC Display Controller.
*
* @desc: HLCDC Display Controller description
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index 1a9318810a29..dbc508889e87 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -31,7 +31,6 @@
* @src_y: y buffer position
* @src_w: buffer width
* @src_h: buffer height
- * @alpha: alpha blending of the plane
* @disc_x: x discard position
* @disc_y: y discard position
* @disc_w: discard width
@@ -54,8 +53,6 @@ struct atmel_hlcdc_plane_state {
uint32_t src_w;
uint32_t src_h;
- u8 alpha;
-
int disc_x;
int disc_y;
int disc_w;
@@ -385,7 +382,7 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
cfg |= ATMEL_HLCDC_LAYER_LAEN;
else
cfg |= ATMEL_HLCDC_LAYER_GAEN |
- ATMEL_HLCDC_LAYER_GA(state->alpha);
+ ATMEL_HLCDC_LAYER_GA(state->base.alpha);
}
if (state->disc_h && state->disc_w)
@@ -553,7 +550,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state)
if (!ovl_s->fb ||
drm_format_has_alpha(ovl_s->fb->format->format) ||
- ovl_state->alpha != 255)
+ ovl_s->alpha != 255)
continue;
/* TODO: implement a smarter hidden area detection */
@@ -829,51 +826,18 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
drm_plane_cleanup(p);
}
-static int atmel_hlcdc_plane_atomic_set_property(struct drm_plane *p,
- struct drm_plane_state *s,
- struct drm_property *property,
- uint64_t val)
-{
- struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
- struct atmel_hlcdc_plane_properties *props = plane->properties;
- struct atmel_hlcdc_plane_state *state =
- drm_plane_state_to_atmel_hlcdc_plane_state(s);
-
- if (property == props->alpha)
- state->alpha = val;
- else
- return -EINVAL;
-
- return 0;
-}
-
-static int atmel_hlcdc_plane_atomic_get_property(struct drm_plane *p,
- const struct drm_plane_state *s,
- struct drm_property *property,
- uint64_t *val)
-{
- struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
- struct atmel_hlcdc_plane_properties *props = plane->properties;
- const struct atmel_hlcdc_plane_state *state =
- container_of(s, const struct atmel_hlcdc_plane_state, base);
-
- if (property == props->alpha)
- *val = state->alpha;
- else
- return -EINVAL;
-
- return 0;
-}
-
-static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
- struct atmel_hlcdc_plane_properties *props)
+static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
- desc->type == ATMEL_HLCDC_CURSOR_LAYER)
- drm_object_attach_property(&plane->base.base,
- props->alpha, 255);
+ desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
+ int ret;
+
+ ret = drm_plane_create_alpha_property(&plane->base, 255);
+ if (ret)
+ return ret;
+ }
if (desc->layout.xstride && desc->layout.pstride) {
int ret;
@@ -988,8 +952,8 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
return;
}
- state->alpha = 255;
p->state = &state->base;
+ p->state->alpha = 255;
p->state->plane = p;
}
}
@@ -1042,13 +1006,10 @@ static const struct drm_plane_funcs layer_plane_funcs = {
.reset = atmel_hlcdc_plane_reset,
.atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state,
.atomic_destroy_state = atmel_hlcdc_plane_atomic_destroy_state,
- .atomic_set_property = atmel_hlcdc_plane_atomic_set_property,
- .atomic_get_property = atmel_hlcdc_plane_atomic_get_property,
};
static int atmel_hlcdc_plane_create(struct drm_device *dev,
- const struct atmel_hlcdc_layer_desc *desc,
- struct atmel_hlcdc_plane_properties *props)
+ const struct atmel_hlcdc_layer_desc *desc)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
struct atmel_hlcdc_plane *plane;
@@ -1060,7 +1021,6 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
return -ENOMEM;
atmel_hlcdc_layer_init(&plane->layer, desc, dc->hlcdc->regmap);
- plane->properties = props;
if (desc->type == ATMEL_HLCDC_BASE_LAYER)
type = DRM_PLANE_TYPE_PRIMARY;
@@ -1081,7 +1041,7 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
&atmel_hlcdc_layer_plane_helper_funcs);
/* Set default property values*/
- ret = atmel_hlcdc_plane_init_properties(plane, props);
+ ret = atmel_hlcdc_plane_init_properties(plane);
if (ret)
return ret;
@@ -1090,34 +1050,13 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
return 0;
}
-static struct atmel_hlcdc_plane_properties *
-atmel_hlcdc_plane_create_properties(struct drm_device *dev)
-{
- struct atmel_hlcdc_plane_properties *props;
-
- props = devm_kzalloc(dev->dev, sizeof(*props), GFP_KERNEL);
- if (!props)
- return ERR_PTR(-ENOMEM);
-
- props->alpha = drm_property_create_range(dev, 0, "alpha", 0, 255);
- if (!props->alpha)
- return ERR_PTR(-ENOMEM);
-
- return props;
-}
-
int atmel_hlcdc_create_planes(struct drm_device *dev)
{
struct atmel_hlcdc_dc *dc = dev->dev_private;
- struct atmel_hlcdc_plane_properties *props;
const struct atmel_hlcdc_layer_desc *descs = dc->desc->layers;
int nlayers = dc->desc->nlayers;
int i, ret;
- props = atmel_hlcdc_plane_create_properties(dev);
- if (IS_ERR(props))
- return PTR_ERR(props);
-
dc->dscrpool = dmam_pool_create("atmel-hlcdc-dscr", dev->dev,
sizeof(struct atmel_hlcdc_dma_channel_dscr),
sizeof(u64), 0);
@@ -1130,7 +1069,7 @@ int atmel_hlcdc_create_planes(struct drm_device *dev)
descs[i].type != ATMEL_HLCDC_CURSOR_LAYER)
continue;
- ret = atmel_hlcdc_plane_create(dev, &descs[i], props);
+ ret = atmel_hlcdc_plane_create(dev, &descs[i]);
if (ret)
return ret;
}
--
git-series 0.9.1
Some drivers duplicate the logic to create a property to store a per-plane
alpha.
Let's create a helper in order to move that to the core.
Cc: Boris Brezillon <[email protected]>
Cc: Laurent Pinchart <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
---
Documentation/gpu/kms-properties.csv | 2 +-
drivers/gpu/drm/drm_atomic.c | 4 ++++-
drivers/gpu/drm/drm_atomic_helper.c | 1 +-
drivers/gpu/drm/drm_blend.c | 32 +++++++++++++++++++++++++++++-
include/drm/drm_blend.h | 1 +-
include/drm/drm_plane.h | 6 +++++-
6 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
index 927b65e14219..a3c3969c1992 100644
--- a/Documentation/gpu/kms-properties.csv
+++ b/Documentation/gpu/kms-properties.csv
@@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD
,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD
,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD
,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD
-rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD
+,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from transparent (0) to opaque (255)
,,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c2da5585e201..ade18cf62c89 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -749,6 +749,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
state->src_w = val;
} else if (property == config->prop_src_h) {
state->src_h = val;
+ } else if (property == plane->alpha_property) {
+ state->alpha = val;
} else if (property == plane->rotation_property) {
if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
return -EINVAL;
@@ -810,6 +812,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
*val = state->src_w;
} else if (property == config->prop_src_h) {
*val = state->src_h;
+ } else if (property == plane->alpha_property) {
+ *val = state->alpha;
} else if (property == plane->rotation_property) {
*val = state->rotation;
} else if (property == plane->zpos_property) {
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 71d712f1b56a..018993df4c18 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3372,6 +3372,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
if (plane->state) {
plane->state->plane = plane;
+ plane->state->alpha = 255;
plane->state->rotation = DRM_MODE_ROTATE_0;
}
}
diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
index 2e5e089dd912..8eea2a8af458 100644
--- a/drivers/gpu/drm/drm_blend.c
+++ b/drivers/gpu/drm/drm_blend.c
@@ -104,6 +104,38 @@
*/
/**
+ * drm_plane_create_alpha_property - create a new alpha property
+ * @plane: drm plane
+ * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque)
+ *
+ * This function initializes a generic, mutable, alpha property and
+ * enables support for it in the DRM core.
+ *
+ * Drivers can then attach this property to their plane to enable
+ * support for configurable plane alpha.
+ *
+ * Returns:
+ * 0 on success, negative error code on failure.
+ */
+int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha)
+{
+ struct drm_property *prop;
+
+ prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255);
+ if (!prop)
+ return -ENOMEM;
+
+ drm_object_attach_property(&plane->base, prop, alpha);
+ plane->alpha_property = prop;
+
+ if (plane->state)
+ plane->state->alpha = alpha;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_plane_create_alpha_property);
+
+/**
* drm_plane_create_rotation_property - create a new rotation property
* @plane: drm plane
* @rotation: initial value of the rotation property
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index 17606026590b..5979a8fce453 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -36,6 +36,7 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation)
return rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270);
}
+int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha);
int drm_plane_create_rotation_property(struct drm_plane *plane,
unsigned int rotation,
unsigned int supported_rotations);
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 571615079230..a5e26064b132 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -42,6 +42,7 @@ struct drm_modeset_acquire_ctx;
* plane (in 16.16)
* @src_w: width of visible portion of plane (in 16.16)
* @src_h: height of visible portion of plane (in 16.16)
+ * @alpha: opacity of the plane
* @rotation: rotation of the plane
* @zpos: priority of the given plane on crtc (optional)
* Note that multiple active planes on the same crtc can have an identical
@@ -105,6 +106,9 @@ struct drm_plane_state {
uint32_t src_x, src_y;
uint32_t src_h, src_w;
+ /* Plane opacity */
+ u8 alpha;
+
/* Plane rotation */
unsigned int rotation;
@@ -481,6 +485,7 @@ enum drm_plane_type {
* @funcs: helper functions
* @properties: property tracking for this plane
* @type: type of plane (overlay, primary, cursor)
+ * @alpha_property: alpha property for this plane
* @zpos_property: zpos property for this plane
* @rotation_property: rotation property for this plane
* @helper_private: mid-layer private data
@@ -546,6 +551,7 @@ struct drm_plane {
*/
struct drm_plane_state *state;
+ struct drm_property *alpha_property;
struct drm_property *zpos_property;
struct drm_property *rotation_property;
};
--
git-series 0.9.1
Now that the core has a drm format helper to tell if a format embeds an
alpha component in it, let's use it.
Cc: Eric Anholt <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/vc4/vc4_plane.c | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 423a23ed8fc2..2c0e25128dcd 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -85,40 +85,39 @@ static const struct hvs_format {
u32 drm; /* DRM_FORMAT_* */
u32 hvs; /* HVS_FORMAT_* */
u32 pixel_order;
- bool has_alpha;
bool flip_cbcr;
} hvs_formats[] = {
{
.drm = DRM_FORMAT_XRGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
- .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
},
{
.drm = DRM_FORMAT_ARGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
- .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true,
+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
},
{
.drm = DRM_FORMAT_ABGR8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
- .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = true,
+ .pixel_order = HVS_PIXEL_ORDER_ARGB,
},
{
.drm = DRM_FORMAT_XBGR8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
- .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = false,
+ .pixel_order = HVS_PIXEL_ORDER_ARGB,
},
{
.drm = DRM_FORMAT_RGB565, .hvs = HVS_PIXEL_FORMAT_RGB565,
- .pixel_order = HVS_PIXEL_ORDER_XRGB, .has_alpha = false,
+ .pixel_order = HVS_PIXEL_ORDER_XRGB,
},
{
.drm = DRM_FORMAT_BGR565, .hvs = HVS_PIXEL_FORMAT_RGB565,
- .pixel_order = HVS_PIXEL_ORDER_XBGR, .has_alpha = false,
+ .pixel_order = HVS_PIXEL_ORDER_XBGR,
},
{
.drm = DRM_FORMAT_ARGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551,
- .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true,
+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
},
{
.drm = DRM_FORMAT_XRGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551,
- .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
+ .pixel_order = HVS_PIXEL_ORDER_ABGR,
},
{
.drm = DRM_FORMAT_YUV422,
@@ -601,7 +600,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
/* Position Word 2: Source Image Size, Alpha Mode */
vc4_state->pos2_offset = vc4_state->dlist_count;
vc4_dlist_write(vc4_state,
- VC4_SET_FIELD(format->has_alpha ?
+ VC4_SET_FIELD(drm_format_has_alpha(format->drm) ?
SCALER_POS2_ALPHA_MODE_PIPELINE :
SCALER_POS2_ALPHA_MODE_FIXED,
SCALER_POS2_ALPHA_MODE) |
--
git-series 0.9.1
There's a bunch of drivers that duplicate the same function to know if a
particular format embeds an alpha component or not.
Let's create a helper to avoid duplicating that logic.
Cc: Boris Brezillon <[email protected]>
Cc: Eric Anholt <[email protected]>
Cc: Inki Dae <[email protected]>
Cc: Joonyoung Shim <[email protected]>
Cc: Kyungmin Park <[email protected]>
Cc: Laurent Pinchart <[email protected]>
Cc: Mark Yao <[email protected]>
Cc: Seung-Woo Kim <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/drm_fourcc.c | 43 +++++++++++++++++++++++++++++++++++++-
include/drm/drm_fourcc.h | 1 +-
2 files changed, 44 insertions(+)
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 9c0152df45ad..6e6227d6a46b 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t format, int plane)
return height / info->vsub;
}
EXPORT_SYMBOL(drm_format_plane_height);
+
+/**
+ * drm_format_has_alpha - get whether the format embeds an alpha component
+ * @format: pixel format (DRM_FORMAT_*)
+ *
+ * Returns:
+ * true if the format embeds an alpha component, false otherwise.
+ */
+bool drm_format_has_alpha(uint32_t format)
+{
+ switch (format) {
+ case DRM_FORMAT_ARGB4444:
+ case DRM_FORMAT_ABGR4444:
+ case DRM_FORMAT_RGBA4444:
+ case DRM_FORMAT_BGRA4444:
+ case DRM_FORMAT_ARGB1555:
+ case DRM_FORMAT_ABGR1555:
+ case DRM_FORMAT_RGBA5551:
+ case DRM_FORMAT_BGRA5551:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_RGBA8888:
+ case DRM_FORMAT_BGRA8888:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_RGBA1010102:
+ case DRM_FORMAT_BGRA1010102:
+ case DRM_FORMAT_AYUV:
+ case DRM_FORMAT_XRGB8888_A8:
+ case DRM_FORMAT_XBGR8888_A8:
+ case DRM_FORMAT_RGBX8888_A8:
+ case DRM_FORMAT_BGRX8888_A8:
+ case DRM_FORMAT_RGB888_A8:
+ case DRM_FORMAT_BGR888_A8:
+ case DRM_FORMAT_RGB565_A8:
+ case DRM_FORMAT_BGR565_A8:
+ return true;
+
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL(drm_format_has_alpha);
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 6942e84b6edd..e08fc22c5f78 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -69,5 +69,6 @@ int drm_format_vert_chroma_subsampling(uint32_t format);
int drm_format_plane_width(int width, uint32_t format, int plane);
int drm_format_plane_height(int height, uint32_t format, int plane);
const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf);
+bool drm_format_has_alpha(uint32_t format);
#endif /* __DRM_FOURCC_H__ */
--
git-series 0.9.1
Now that the core has a drm format helper to tell if a format embeds an
alpha component in it, let's use it.
Cc: Inki Dae <[email protected]>
Cc: Joonyoung Shim <[email protected]>
Cc: Kyungmin Park <[email protected]>
Cc: Seung-Woo Kim <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/exynos/exynos_mixer.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index dc5d79465f9b..d7339a6d072c 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -179,18 +179,6 @@ static const u8 filter_cr_horiz_tap4[] = {
70, 59, 48, 37, 27, 19, 11, 5,
};
-static inline bool is_alpha_format(unsigned int pixel_format)
-{
- switch (pixel_format) {
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_ARGB1555:
- case DRM_FORMAT_ARGB4444:
- return true;
- default:
- return false;
- }
-}
-
static inline u32 vp_reg_read(struct mixer_context *ctx, u32 reg_id)
{
return readl(ctx->vp_regs + reg_id);
@@ -625,7 +613,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr);
mixer_cfg_layer(ctx, win, priority, true);
- mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format));
+ mixer_cfg_gfx_blend(ctx, win, drm_format_has_alpha(fb->format->format));
/* layer update mandatory for mixer 16.0.33.0 */
if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
--
git-series 0.9.1
Now that the core has a drm format helper to tell if a format embeds an
alpha component in it, let's use it.
Cc: Mark Yao <[email protected]>
Signed-off-by: Maxime Ripard <[email protected]>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 +------------
1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 19128b4dea54..cfc4d4909185 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -253,17 +253,6 @@ static bool is_yuv_support(uint32_t format)
}
}
-static bool is_alpha_support(uint32_t format)
-{
- switch (format) {
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_ABGR8888:
- return true;
- default:
- return false;
- }
-}
-
static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
uint32_t dst, bool is_horizontal,
int vsu_mode, int *vskiplines)
@@ -790,7 +779,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
rb_swap = has_rb_swapped(fb->format->format);
VOP_WIN_SET(vop, win, rb_swap, rb_swap);
- if (is_alpha_support(fb->format->format)) {
+ if (drm_format_has_alpha(fb->format->format)) {
VOP_WIN_SET(vop, win, dst_alpha_ctl,
DST_FACTOR_M0(ALPHA_SRC_INVERSE));
val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
--
git-series 0.9.1
On Tue, 9 Jan 2018 11:56:20 +0100
Maxime Ripard <[email protected]> wrote:
> There's a bunch of drivers that duplicate the same function to know if a
> particular format embeds an alpha component or not.
>
> Let's create a helper to avoid duplicating that logic.
>
> Cc: Boris Brezillon <[email protected]>
Reviewed-by: Boris Brezillon <[email protected]>
> Cc: Eric Anholt <[email protected]>
> Cc: Inki Dae <[email protected]>
> Cc: Joonyoung Shim <[email protected]>
> Cc: Kyungmin Park <[email protected]>
> Cc: Laurent Pinchart <[email protected]>
> Cc: Mark Yao <[email protected]>
> Cc: Seung-Woo Kim <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
> ---
> drivers/gpu/drm/drm_fourcc.c | 43 +++++++++++++++++++++++++++++++++++++-
> include/drm/drm_fourcc.h | 1 +-
> 2 files changed, 44 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 9c0152df45ad..6e6227d6a46b 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t format, int plane)
> return height / info->vsub;
> }
> EXPORT_SYMBOL(drm_format_plane_height);
> +
> +/**
> + * drm_format_has_alpha - get whether the format embeds an alpha component
> + * @format: pixel format (DRM_FORMAT_*)
> + *
> + * Returns:
> + * true if the format embeds an alpha component, false otherwise.
> + */
> +bool drm_format_has_alpha(uint32_t format)
> +{
> + switch (format) {
> + case DRM_FORMAT_ARGB4444:
> + case DRM_FORMAT_ABGR4444:
> + case DRM_FORMAT_RGBA4444:
> + case DRM_FORMAT_BGRA4444:
> + case DRM_FORMAT_ARGB1555:
> + case DRM_FORMAT_ABGR1555:
> + case DRM_FORMAT_RGBA5551:
> + case DRM_FORMAT_BGRA5551:
> + case DRM_FORMAT_ARGB8888:
> + case DRM_FORMAT_ABGR8888:
> + case DRM_FORMAT_RGBA8888:
> + case DRM_FORMAT_BGRA8888:
> + case DRM_FORMAT_ARGB2101010:
> + case DRM_FORMAT_ABGR2101010:
> + case DRM_FORMAT_RGBA1010102:
> + case DRM_FORMAT_BGRA1010102:
> + case DRM_FORMAT_AYUV:
> + case DRM_FORMAT_XRGB8888_A8:
> + case DRM_FORMAT_XBGR8888_A8:
> + case DRM_FORMAT_RGBX8888_A8:
> + case DRM_FORMAT_BGRX8888_A8:
> + case DRM_FORMAT_RGB888_A8:
> + case DRM_FORMAT_BGR888_A8:
> + case DRM_FORMAT_RGB565_A8:
> + case DRM_FORMAT_BGR565_A8:
> + return true;
> +
> + default:
> + return false;
> + }
> +}
> +EXPORT_SYMBOL(drm_format_has_alpha);
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index 6942e84b6edd..e08fc22c5f78 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -69,5 +69,6 @@ int drm_format_vert_chroma_subsampling(uint32_t format);
> int drm_format_plane_width(int width, uint32_t format, int plane);
> int drm_format_plane_height(int height, uint32_t format, int plane);
> const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf);
> +bool drm_format_has_alpha(uint32_t format);
>
> #endif /* __DRM_FOURCC_H__ */
On Tue, 9 Jan 2018 11:56:21 +0100
Maxime Ripard <[email protected]> wrote:
> Now that the core has a drm format helper to tell if a format embeds an
> alpha component in it, let's use it.
>
> Cc: Boris Brezillon <[email protected]>
Acked-by: Boris Brezillon <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
> ---
> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 20 ++----------------
> 1 file changed, 3 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index 703c2d13603f..1a9318810a29 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -194,20 +194,6 @@ static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode)
> return 0;
> }
>
> -static bool atmel_hlcdc_format_embeds_alpha(u32 format)
> -{
> - int i;
> -
> - for (i = 0; i < sizeof(format); i++) {
> - char tmp = (format >> (8 * i)) & 0xff;
> -
> - if (tmp == 'A')
> - return true;
> - }
> -
> - return false;
> -}
> -
> static u32 heo_downscaling_xcoef[] = {
> 0x11343311,
> 0x000000f7,
> @@ -395,7 +381,7 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> cfg |= ATMEL_HLCDC_LAYER_OVR | ATMEL_HLCDC_LAYER_ITER2BL |
> ATMEL_HLCDC_LAYER_ITER;
>
> - if (atmel_hlcdc_format_embeds_alpha(format))
> + if (drm_format_has_alpha(format))
> cfg |= ATMEL_HLCDC_LAYER_LAEN;
> else
> cfg |= ATMEL_HLCDC_LAYER_GAEN |
> @@ -566,7 +552,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state)
> ovl_state = drm_plane_state_to_atmel_hlcdc_plane_state(ovl_s);
>
> if (!ovl_s->fb ||
> - atmel_hlcdc_format_embeds_alpha(ovl_s->fb->format->format) ||
> + drm_format_has_alpha(ovl_s->fb->format->format) ||
> ovl_state->alpha != 255)
> continue;
>
> @@ -769,7 +755,7 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
>
> if ((state->crtc_h != state->src_h || state->crtc_w != state->src_w) &&
> (!desc->layout.memsize ||
> - atmel_hlcdc_format_embeds_alpha(state->base.fb->format->format)))
> + drm_format_has_alpha(state->base.fb->format->format)))
> return -EINVAL;
>
> if (state->crtc_x < 0 || state->crtc_y < 0)
Hi Maxime,
Thank you for the patch.
On Tuesday, 9 January 2018 12:56:20 EET Maxime Ripard wrote:
> There's a bunch of drivers that duplicate the same function to know if a
> particular format embeds an alpha component or not.
>
> Let's create a helper to avoid duplicating that logic.
>
> Cc: Boris Brezillon <[email protected]>
> Cc: Eric Anholt <[email protected]>
> Cc: Inki Dae <[email protected]>
> Cc: Joonyoung Shim <[email protected]>
> Cc: Kyungmin Park <[email protected]>
> Cc: Laurent Pinchart <[email protected]>
> Cc: Mark Yao <[email protected]>
> Cc: Seung-Woo Kim <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
> ---
> drivers/gpu/drm/drm_fourcc.c | 43 +++++++++++++++++++++++++++++++++++++-
> include/drm/drm_fourcc.h | 1 +-
> 2 files changed, 44 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 9c0152df45ad..6e6227d6a46b 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t
> format, int plane) return height / info->vsub;
> }
> EXPORT_SYMBOL(drm_format_plane_height);
> +
> +/**
> + * drm_format_has_alpha - get whether the format embeds an alpha component
> + * @format: pixel format (DRM_FORMAT_*)
> + *
> + * Returns:
> + * true if the format embeds an alpha component, false otherwise.
> + */
> +bool drm_format_has_alpha(uint32_t format)
> +{
> + switch (format) {
> + case DRM_FORMAT_ARGB4444:
> + case DRM_FORMAT_ABGR4444:
> + case DRM_FORMAT_RGBA4444:
> + case DRM_FORMAT_BGRA4444:
> + case DRM_FORMAT_ARGB1555:
> + case DRM_FORMAT_ABGR1555:
> + case DRM_FORMAT_RGBA5551:
> + case DRM_FORMAT_BGRA5551:
> + case DRM_FORMAT_ARGB8888:
> + case DRM_FORMAT_ABGR8888:
> + case DRM_FORMAT_RGBA8888:
> + case DRM_FORMAT_BGRA8888:
> + case DRM_FORMAT_ARGB2101010:
> + case DRM_FORMAT_ABGR2101010:
> + case DRM_FORMAT_RGBA1010102:
> + case DRM_FORMAT_BGRA1010102:
> + case DRM_FORMAT_AYUV:
> + case DRM_FORMAT_XRGB8888_A8:
> + case DRM_FORMAT_XBGR8888_A8:
> + case DRM_FORMAT_RGBX8888_A8:
> + case DRM_FORMAT_BGRX8888_A8:
> + case DRM_FORMAT_RGB888_A8:
> + case DRM_FORMAT_BGR888_A8:
> + case DRM_FORMAT_RGB565_A8:
> + case DRM_FORMAT_BGR565_A8:
> + return true;
> +
> + default:
> + return false;
> + }
> +}
> +EXPORT_SYMBOL(drm_format_has_alpha);
How about adding the information to struct drm_format_info instead ?
drm_format_has_alpha() could then be implemented as
bool drm_format_has_alpha(uint32_t format)
{
const struct drm_format_info *info;
info = drm_format_info(format);
return info ? info->has_alpha : false;
}
although drivers should really use the drm_framebuffer::format field directly
in most cases, so the helper might not be needed at all.
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index 6942e84b6edd..e08fc22c5f78 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -69,5 +69,6 @@ int drm_format_vert_chroma_subsampling(uint32_t format);
> int drm_format_plane_width(int width, uint32_t format, int plane);
> int drm_format_plane_height(int height, uint32_t format, int plane);
> const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf
> *buf);
> +bool drm_format_has_alpha(uint32_t format);
>
> #endif /* __DRM_FOURCC_H__ */
--
Regards,
Laurent Pinchart
On Tue, 9 Jan 2018 11:56:25 +0100
Maxime Ripard <[email protected]> wrote:
> Some drivers duplicate the logic to create a property to store a per-plane
> alpha.
>
> Let's create a helper in order to move that to the core.
>
> Cc: Boris Brezillon <[email protected]>
Reviewed-by: Boris Brezillon <[email protected]>
> Cc: Laurent Pinchart <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
> ---
> Documentation/gpu/kms-properties.csv | 2 +-
> drivers/gpu/drm/drm_atomic.c | 4 ++++-
> drivers/gpu/drm/drm_atomic_helper.c | 1 +-
> drivers/gpu/drm/drm_blend.c | 32 +++++++++++++++++++++++++++++-
> include/drm/drm_blend.h | 1 +-
> include/drm/drm_plane.h | 6 +++++-
> 6 files changed, 45 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
> index 927b65e14219..a3c3969c1992 100644
> --- a/Documentation/gpu/kms-properties.csv
> +++ b/Documentation/gpu/kms-properties.csv
> @@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD
> ,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD
> ,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD
> ,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD
> -rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD
> +,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from transparent (0) to opaque (255)
> ,,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index c2da5585e201..ade18cf62c89 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -749,6 +749,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
> state->src_w = val;
> } else if (property == config->prop_src_h) {
> state->src_h = val;
> + } else if (property == plane->alpha_property) {
> + state->alpha = val;
> } else if (property == plane->rotation_property) {
> if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> return -EINVAL;
> @@ -810,6 +812,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
> *val = state->src_w;
> } else if (property == config->prop_src_h) {
> *val = state->src_h;
> + } else if (property == plane->alpha_property) {
> + *val = state->alpha;
> } else if (property == plane->rotation_property) {
> *val = state->rotation;
> } else if (property == plane->zpos_property) {
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 71d712f1b56a..018993df4c18 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -3372,6 +3372,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
>
> if (plane->state) {
> plane->state->plane = plane;
> + plane->state->alpha = 255;
> plane->state->rotation = DRM_MODE_ROTATE_0;
> }
> }
> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> index 2e5e089dd912..8eea2a8af458 100644
> --- a/drivers/gpu/drm/drm_blend.c
> +++ b/drivers/gpu/drm/drm_blend.c
> @@ -104,6 +104,38 @@
> */
>
> /**
> + * drm_plane_create_alpha_property - create a new alpha property
> + * @plane: drm plane
> + * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque)
> + *
> + * This function initializes a generic, mutable, alpha property and
> + * enables support for it in the DRM core.
> + *
> + * Drivers can then attach this property to their plane to enable
> + * support for configurable plane alpha.
> + *
> + * Returns:
> + * 0 on success, negative error code on failure.
> + */
> +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha)
> +{
> + struct drm_property *prop;
> +
> + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255);
> + if (!prop)
> + return -ENOMEM;
> +
> + drm_object_attach_property(&plane->base, prop, alpha);
> + plane->alpha_property = prop;
> +
> + if (plane->state)
> + plane->state->alpha = alpha;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_plane_create_alpha_property);
> +
> +/**
> * drm_plane_create_rotation_property - create a new rotation property
> * @plane: drm plane
> * @rotation: initial value of the rotation property
> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> index 17606026590b..5979a8fce453 100644
> --- a/include/drm/drm_blend.h
> +++ b/include/drm/drm_blend.h
> @@ -36,6 +36,7 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation)
> return rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270);
> }
>
> +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha);
> int drm_plane_create_rotation_property(struct drm_plane *plane,
> unsigned int rotation,
> unsigned int supported_rotations);
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index 571615079230..a5e26064b132 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -42,6 +42,7 @@ struct drm_modeset_acquire_ctx;
> * plane (in 16.16)
> * @src_w: width of visible portion of plane (in 16.16)
> * @src_h: height of visible portion of plane (in 16.16)
> + * @alpha: opacity of the plane
> * @rotation: rotation of the plane
> * @zpos: priority of the given plane on crtc (optional)
> * Note that multiple active planes on the same crtc can have an identical
> @@ -105,6 +106,9 @@ struct drm_plane_state {
> uint32_t src_x, src_y;
> uint32_t src_h, src_w;
>
> + /* Plane opacity */
> + u8 alpha;
> +
> /* Plane rotation */
> unsigned int rotation;
>
> @@ -481,6 +485,7 @@ enum drm_plane_type {
> * @funcs: helper functions
> * @properties: property tracking for this plane
> * @type: type of plane (overlay, primary, cursor)
> + * @alpha_property: alpha property for this plane
> * @zpos_property: zpos property for this plane
> * @rotation_property: rotation property for this plane
> * @helper_private: mid-layer private data
> @@ -546,6 +551,7 @@ struct drm_plane {
> */
> struct drm_plane_state *state;
>
> + struct drm_property *alpha_property;
> struct drm_property *zpos_property;
> struct drm_property *rotation_property;
> };
On Tue, 9 Jan 2018 11:56:26 +0100
Maxime Ripard <[email protected]> wrote:
> Now that we have support for per-plane alpha in the core, let's use it.
>
> Cc: Boris Brezillon <[email protected]>
Acked-by: Boris Brezillon <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
> ---
> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 13 +---
> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 89 ++----------------
> 2 files changed, 14 insertions(+), 88 deletions(-)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> index 6833ee253cfa..704cac6399eb 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> @@ -298,7 +298,6 @@ struct atmel_hlcdc_layer {
> struct atmel_hlcdc_plane {
> struct drm_plane base;
> struct atmel_hlcdc_layer layer;
> - struct atmel_hlcdc_plane_properties *properties;
> };
>
> static inline struct atmel_hlcdc_plane *
> @@ -345,18 +344,6 @@ struct atmel_hlcdc_dc_desc {
> };
>
> /**
> - * Atmel HLCDC Plane properties.
> - *
> - * This structure stores plane property definitions.
> - *
> - * @alpha: alpha blending (or transparency) property
> - * @rotation: rotation property
> - */
> -struct atmel_hlcdc_plane_properties {
> - struct drm_property *alpha;
> -};
> -
> -/**
> * Atmel HLCDC Display Controller.
> *
> * @desc: HLCDC Display Controller description
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index 1a9318810a29..dbc508889e87 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -31,7 +31,6 @@
> * @src_y: y buffer position
> * @src_w: buffer width
> * @src_h: buffer height
> - * @alpha: alpha blending of the plane
> * @disc_x: x discard position
> * @disc_y: y discard position
> * @disc_w: discard width
> @@ -54,8 +53,6 @@ struct atmel_hlcdc_plane_state {
> uint32_t src_w;
> uint32_t src_h;
>
> - u8 alpha;
> -
> int disc_x;
> int disc_y;
> int disc_w;
> @@ -385,7 +382,7 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> cfg |= ATMEL_HLCDC_LAYER_LAEN;
> else
> cfg |= ATMEL_HLCDC_LAYER_GAEN |
> - ATMEL_HLCDC_LAYER_GA(state->alpha);
> + ATMEL_HLCDC_LAYER_GA(state->base.alpha);
> }
>
> if (state->disc_h && state->disc_w)
> @@ -553,7 +550,7 @@ atmel_hlcdc_plane_prepare_disc_area(struct drm_crtc_state *c_state)
>
> if (!ovl_s->fb ||
> drm_format_has_alpha(ovl_s->fb->format->format) ||
> - ovl_state->alpha != 255)
> + ovl_s->alpha != 255)
> continue;
>
> /* TODO: implement a smarter hidden area detection */
> @@ -829,51 +826,18 @@ static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
> drm_plane_cleanup(p);
> }
>
> -static int atmel_hlcdc_plane_atomic_set_property(struct drm_plane *p,
> - struct drm_plane_state *s,
> - struct drm_property *property,
> - uint64_t val)
> -{
> - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> - struct atmel_hlcdc_plane_properties *props = plane->properties;
> - struct atmel_hlcdc_plane_state *state =
> - drm_plane_state_to_atmel_hlcdc_plane_state(s);
> -
> - if (property == props->alpha)
> - state->alpha = val;
> - else
> - return -EINVAL;
> -
> - return 0;
> -}
> -
> -static int atmel_hlcdc_plane_atomic_get_property(struct drm_plane *p,
> - const struct drm_plane_state *s,
> - struct drm_property *property,
> - uint64_t *val)
> -{
> - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> - struct atmel_hlcdc_plane_properties *props = plane->properties;
> - const struct atmel_hlcdc_plane_state *state =
> - container_of(s, const struct atmel_hlcdc_plane_state, base);
> -
> - if (property == props->alpha)
> - *val = state->alpha;
> - else
> - return -EINVAL;
> -
> - return 0;
> -}
> -
> -static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
> - struct atmel_hlcdc_plane_properties *props)
> +static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
> {
> const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
>
> if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
> - desc->type == ATMEL_HLCDC_CURSOR_LAYER)
> - drm_object_attach_property(&plane->base.base,
> - props->alpha, 255);
> + desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
> + int ret;
> +
> + ret = drm_plane_create_alpha_property(&plane->base, 255);
> + if (ret)
> + return ret;
> + }
>
> if (desc->layout.xstride && desc->layout.pstride) {
> int ret;
> @@ -988,8 +952,8 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
> return;
> }
>
> - state->alpha = 255;
> p->state = &state->base;
> + p->state->alpha = 255;
> p->state->plane = p;
> }
> }
> @@ -1042,13 +1006,10 @@ static const struct drm_plane_funcs layer_plane_funcs = {
> .reset = atmel_hlcdc_plane_reset,
> .atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state,
> .atomic_destroy_state = atmel_hlcdc_plane_atomic_destroy_state,
> - .atomic_set_property = atmel_hlcdc_plane_atomic_set_property,
> - .atomic_get_property = atmel_hlcdc_plane_atomic_get_property,
> };
>
> static int atmel_hlcdc_plane_create(struct drm_device *dev,
> - const struct atmel_hlcdc_layer_desc *desc,
> - struct atmel_hlcdc_plane_properties *props)
> + const struct atmel_hlcdc_layer_desc *desc)
> {
> struct atmel_hlcdc_dc *dc = dev->dev_private;
> struct atmel_hlcdc_plane *plane;
> @@ -1060,7 +1021,6 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
> return -ENOMEM;
>
> atmel_hlcdc_layer_init(&plane->layer, desc, dc->hlcdc->regmap);
> - plane->properties = props;
>
> if (desc->type == ATMEL_HLCDC_BASE_LAYER)
> type = DRM_PLANE_TYPE_PRIMARY;
> @@ -1081,7 +1041,7 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
> &atmel_hlcdc_layer_plane_helper_funcs);
>
> /* Set default property values*/
> - ret = atmel_hlcdc_plane_init_properties(plane, props);
> + ret = atmel_hlcdc_plane_init_properties(plane);
> if (ret)
> return ret;
>
> @@ -1090,34 +1050,13 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
> return 0;
> }
>
> -static struct atmel_hlcdc_plane_properties *
> -atmel_hlcdc_plane_create_properties(struct drm_device *dev)
> -{
> - struct atmel_hlcdc_plane_properties *props;
> -
> - props = devm_kzalloc(dev->dev, sizeof(*props), GFP_KERNEL);
> - if (!props)
> - return ERR_PTR(-ENOMEM);
> -
> - props->alpha = drm_property_create_range(dev, 0, "alpha", 0, 255);
> - if (!props->alpha)
> - return ERR_PTR(-ENOMEM);
> -
> - return props;
> -}
> -
> int atmel_hlcdc_create_planes(struct drm_device *dev)
> {
> struct atmel_hlcdc_dc *dc = dev->dev_private;
> - struct atmel_hlcdc_plane_properties *props;
> const struct atmel_hlcdc_layer_desc *descs = dc->desc->layers;
> int nlayers = dc->desc->nlayers;
> int i, ret;
>
> - props = atmel_hlcdc_plane_create_properties(dev);
> - if (IS_ERR(props))
> - return PTR_ERR(props);
> -
> dc->dscrpool = dmam_pool_create("atmel-hlcdc-dscr", dev->dev,
> sizeof(struct atmel_hlcdc_dma_channel_dscr),
> sizeof(u64), 0);
> @@ -1130,7 +1069,7 @@ int atmel_hlcdc_create_planes(struct drm_device *dev)
> descs[i].type != ATMEL_HLCDC_CURSOR_LAYER)
> continue;
>
> - ret = atmel_hlcdc_plane_create(dev, &descs[i], props);
> + ret = atmel_hlcdc_plane_create(dev, &descs[i]);
> if (ret)
> return ret;
> }
On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote:
> Some drivers duplicate the logic to create a property to store a per-plane
> alpha.
>
> Let's create a helper in order to move that to the core.
>
> Cc: Boris Brezillon <[email protected]>
> Cc: Laurent Pinchart <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
Do we have userspace for this? Is encoding a fixed 0-255 range really the
best idea?
I know other drivers have skimped on the rules here a bit ... But at least
internally (i.e. within the drm_plane_state) we probably should restrict
ourselves to u8. And this needs real docs (i.e. the full blend equation
drivers are supposed to implement).
-Daniel
> ---
> Documentation/gpu/kms-properties.csv | 2 +-
> drivers/gpu/drm/drm_atomic.c | 4 ++++-
> drivers/gpu/drm/drm_atomic_helper.c | 1 +-
> drivers/gpu/drm/drm_blend.c | 32 +++++++++++++++++++++++++++++-
> include/drm/drm_blend.h | 1 +-
> include/drm/drm_plane.h | 6 +++++-
> 6 files changed, 45 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/gpu/kms-properties.csv b/Documentation/gpu/kms-properties.csv
> index 927b65e14219..a3c3969c1992 100644
> --- a/Documentation/gpu/kms-properties.csv
> +++ b/Documentation/gpu/kms-properties.csv
> @@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD
> ,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD
> ,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD
> ,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD
> -rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD
> +,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from transparent (0) to opaque (255)
> ,,"""colorkey""",RANGE,"Min=0, Max=0x01ffffff",Plane,TBD
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index c2da5585e201..ade18cf62c89 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -749,6 +749,8 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
> state->src_w = val;
> } else if (property == config->prop_src_h) {
> state->src_h = val;
> + } else if (property == plane->alpha_property) {
> + state->alpha = val;
> } else if (property == plane->rotation_property) {
> if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> return -EINVAL;
> @@ -810,6 +812,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
> *val = state->src_w;
> } else if (property == config->prop_src_h) {
> *val = state->src_h;
> + } else if (property == plane->alpha_property) {
> + *val = state->alpha;
> } else if (property == plane->rotation_property) {
> *val = state->rotation;
> } else if (property == plane->zpos_property) {
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
> index 71d712f1b56a..018993df4c18 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -3372,6 +3372,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
>
> if (plane->state) {
> plane->state->plane = plane;
> + plane->state->alpha = 255;
> plane->state->rotation = DRM_MODE_ROTATE_0;
> }
> }
> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> index 2e5e089dd912..8eea2a8af458 100644
> --- a/drivers/gpu/drm/drm_blend.c
> +++ b/drivers/gpu/drm/drm_blend.c
> @@ -104,6 +104,38 @@
> */
>
> /**
> + * drm_plane_create_alpha_property - create a new alpha property
> + * @plane: drm plane
> + * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque)
> + *
> + * This function initializes a generic, mutable, alpha property and
> + * enables support for it in the DRM core.
> + *
> + * Drivers can then attach this property to their plane to enable
> + * support for configurable plane alpha.
> + *
> + * Returns:
> + * 0 on success, negative error code on failure.
> + */
> +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha)
> +{
> + struct drm_property *prop;
> +
> + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255);
> + if (!prop)
> + return -ENOMEM;
> +
> + drm_object_attach_property(&plane->base, prop, alpha);
> + plane->alpha_property = prop;
> +
> + if (plane->state)
> + plane->state->alpha = alpha;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_plane_create_alpha_property);
> +
> +/**
> * drm_plane_create_rotation_property - create a new rotation property
> * @plane: drm plane
> * @rotation: initial value of the rotation property
> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> index 17606026590b..5979a8fce453 100644
> --- a/include/drm/drm_blend.h
> +++ b/include/drm/drm_blend.h
> @@ -36,6 +36,7 @@ static inline bool drm_rotation_90_or_270(unsigned int rotation)
> return rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270);
> }
>
> +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha);
> int drm_plane_create_rotation_property(struct drm_plane *plane,
> unsigned int rotation,
> unsigned int supported_rotations);
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index 571615079230..a5e26064b132 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -42,6 +42,7 @@ struct drm_modeset_acquire_ctx;
> * plane (in 16.16)
> * @src_w: width of visible portion of plane (in 16.16)
> * @src_h: height of visible portion of plane (in 16.16)
> + * @alpha: opacity of the plane
> * @rotation: rotation of the plane
> * @zpos: priority of the given plane on crtc (optional)
> * Note that multiple active planes on the same crtc can have an identical
> @@ -105,6 +106,9 @@ struct drm_plane_state {
> uint32_t src_x, src_y;
> uint32_t src_h, src_w;
>
> + /* Plane opacity */
> + u8 alpha;
> +
> /* Plane rotation */
> unsigned int rotation;
>
> @@ -481,6 +485,7 @@ enum drm_plane_type {
> * @funcs: helper functions
> * @properties: property tracking for this plane
> * @type: type of plane (overlay, primary, cursor)
> + * @alpha_property: alpha property for this plane
> * @zpos_property: zpos property for this plane
> * @rotation_property: rotation property for this plane
> * @helper_private: mid-layer private data
> @@ -546,6 +551,7 @@ struct drm_plane {
> */
> struct drm_plane_state *state;
>
> + struct drm_property *alpha_property;
> struct drm_property *zpos_property;
> struct drm_property *rotation_property;
> };
> --
> git-series 0.9.1
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
Hi Maxime,
Thank you for the patch.
On Tuesday, 9 January 2018 12:56:25 EET Maxime Ripard wrote:
> Some drivers duplicate the logic to create a property to store a per-plane
> alpha.
>
> Let's create a helper in order to move that to the core.
>
> Cc: Boris Brezillon <[email protected]>
> Cc: Laurent Pinchart <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
> ---
> Documentation/gpu/kms-properties.csv | 2 +-
> drivers/gpu/drm/drm_atomic.c | 4 ++++-
> drivers/gpu/drm/drm_atomic_helper.c | 1 +-
> drivers/gpu/drm/drm_blend.c | 32 +++++++++++++++++++++++++++++-
> include/drm/drm_blend.h | 1 +-
> include/drm/drm_plane.h | 6 +++++-
> 6 files changed, 45 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/gpu/kms-properties.csv
> b/Documentation/gpu/kms-properties.csv index 927b65e14219..a3c3969c1992
> 100644
> --- a/Documentation/gpu/kms-properties.csv
> +++ b/Documentation/gpu/kms-properties.csv
> @@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD
> ,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD
> ,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD
> ,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD
> -rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD
> +,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from
> transparent (0) to opaque (255) ,,"""colorkey""",RANGE,"Min=0,
> Max=0x01ffffff",Plane,TBD
I think more documentation is needed. You should explain how the property
operates and which formats it is applicable to. For instance you need to
clarify what happens for format that contain an alpha component.
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index c2da5585e201..ade18cf62c89 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -749,6 +749,8 @@ static int drm_atomic_plane_set_property(struct
> drm_plane *plane, state->src_w = val;
> } else if (property == config->prop_src_h) {
> state->src_h = val;
> + } else if (property == plane->alpha_property) {
> + state->alpha = val;
> } else if (property == plane->rotation_property) {
> if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
> return -EINVAL;
> @@ -810,6 +812,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
> *val = state->src_w;
> } else if (property == config->prop_src_h) {
> *val = state->src_h;
> + } else if (property == plane->alpha_property) {
> + *val = state->alpha;
> } else if (property == plane->rotation_property) {
> *val = state->rotation;
> } else if (property == plane->zpos_property) {
> diff --git a/drivers/gpu/drm/drm_atomic_helper.c
> b/drivers/gpu/drm/drm_atomic_helper.c index 71d712f1b56a..018993df4c18
> 100644
> --- a/drivers/gpu/drm/drm_atomic_helper.c
> +++ b/drivers/gpu/drm/drm_atomic_helper.c
> @@ -3372,6 +3372,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane
> *plane)
>
> if (plane->state) {
> plane->state->plane = plane;
> + plane->state->alpha = 255;
If you keep the ability to select an initial value other than fully opaque
(see my comment below about that) you should reset to that value instead of
hardcoding 255.
> plane->state->rotation = DRM_MODE_ROTATE_0;
> }
> }
> diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c
> index 2e5e089dd912..8eea2a8af458 100644
> --- a/drivers/gpu/drm/drm_blend.c
> +++ b/drivers/gpu/drm/drm_blend.c
> @@ -104,6 +104,38 @@
> */
>
> /**
> + * drm_plane_create_alpha_property - create a new alpha property
> + * @plane: drm plane
> + * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque)
Do you have a use case for initializing the alpha value to something else than
fully opaque ?
> + * This function initializes a generic, mutable, alpha property and
> + * enables support for it in the DRM core.
> + *
> + * Drivers can then attach this property to their plane to enable
> + * support for configurable plane alpha.
The function attaches the property to the plane, is the documentation outdated
?
> + * Returns:
> + * 0 on success, negative error code on failure.
> + */
> +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha)
> +{
> + struct drm_property *prop;
> +
> + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255);
Do you think the 0-255 range will fit all use cases ?
> + if (!prop)
> + return -ENOMEM;
> +
> + drm_object_attach_property(&plane->base, prop, alpha);
> + plane->alpha_property = prop;
> +
> + if (plane->state)
> + plane->state->alpha = alpha;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(drm_plane_create_alpha_property);
> +
> +/**
> * drm_plane_create_rotation_property - create a new rotation property
> * @plane: drm plane
> * @rotation: initial value of the rotation property
> diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
> index 17606026590b..5979a8fce453 100644
> --- a/include/drm/drm_blend.h
> +++ b/include/drm/drm_blend.h
> @@ -36,6 +36,7 @@ static inline bool drm_rotation_90_or_270(unsigned int
> rotation) return rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270);
> }
>
> +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha);
> int drm_plane_create_rotation_property(struct drm_plane *plane,
> unsigned int rotation,
> unsigned int supported_rotations);
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index 571615079230..a5e26064b132 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -42,6 +42,7 @@ struct drm_modeset_acquire_ctx;
> * plane (in 16.16)
> * @src_w: width of visible portion of plane (in 16.16)
> * @src_h: height of visible portion of plane (in 16.16)
> + * @alpha: opacity of the plane
> * @rotation: rotation of the plane
> * @zpos: priority of the given plane on crtc (optional)
> * Note that multiple active planes on the same crtc can have an identical
> @@ -105,6 +106,9 @@ struct drm_plane_state {
> uint32_t src_x, src_y;
> uint32_t src_h, src_w;
>
> + /* Plane opacity */
> + u8 alpha;
> +
> /* Plane rotation */
> unsigned int rotation;
>
> @@ -481,6 +485,7 @@ enum drm_plane_type {
> * @funcs: helper functions
> * @properties: property tracking for this plane
> * @type: type of plane (overlay, primary, cursor)
> + * @alpha_property: alpha property for this plane
> * @zpos_property: zpos property for this plane
> * @rotation_property: rotation property for this plane
> * @helper_private: mid-layer private data
> @@ -546,6 +551,7 @@ struct drm_plane {
> */
> struct drm_plane_state *state;
>
> + struct drm_property *alpha_property;
> struct drm_property *zpos_property;
> struct drm_property *rotation_property;
> };
--
Regards,
Laurent Pinchart
On Tue, Jan 09, 2018 at 11:56:24AM +0100, Maxime Ripard wrote:
> Now that the core has a drm format helper to tell if a format embeds an
> alpha component in it, let's use it.
>
> Cc: Eric Anholt <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
On patches 1-5:
Reviewed-by: Daniel Vetter <[email protected]>
> ---
> drivers/gpu/drm/vc4/vc4_plane.c | 19 +++++++++----------
> 1 file changed, 9 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> index 423a23ed8fc2..2c0e25128dcd 100644
> --- a/drivers/gpu/drm/vc4/vc4_plane.c
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -85,40 +85,39 @@ static const struct hvs_format {
> u32 drm; /* DRM_FORMAT_* */
> u32 hvs; /* HVS_FORMAT_* */
> u32 pixel_order;
> - bool has_alpha;
> bool flip_cbcr;
> } hvs_formats[] = {
> {
> .drm = DRM_FORMAT_XRGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
> - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
> + .pixel_order = HVS_PIXEL_ORDER_ABGR,
> },
> {
> .drm = DRM_FORMAT_ARGB8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
> - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true,
> + .pixel_order = HVS_PIXEL_ORDER_ABGR,
> },
> {
> .drm = DRM_FORMAT_ABGR8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
> - .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = true,
> + .pixel_order = HVS_PIXEL_ORDER_ARGB,
> },
> {
> .drm = DRM_FORMAT_XBGR8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888,
> - .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = false,
> + .pixel_order = HVS_PIXEL_ORDER_ARGB,
> },
> {
> .drm = DRM_FORMAT_RGB565, .hvs = HVS_PIXEL_FORMAT_RGB565,
> - .pixel_order = HVS_PIXEL_ORDER_XRGB, .has_alpha = false,
> + .pixel_order = HVS_PIXEL_ORDER_XRGB,
> },
> {
> .drm = DRM_FORMAT_BGR565, .hvs = HVS_PIXEL_FORMAT_RGB565,
> - .pixel_order = HVS_PIXEL_ORDER_XBGR, .has_alpha = false,
> + .pixel_order = HVS_PIXEL_ORDER_XBGR,
> },
> {
> .drm = DRM_FORMAT_ARGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551,
> - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true,
> + .pixel_order = HVS_PIXEL_ORDER_ABGR,
> },
> {
> .drm = DRM_FORMAT_XRGB1555, .hvs = HVS_PIXEL_FORMAT_RGBA5551,
> - .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = false,
> + .pixel_order = HVS_PIXEL_ORDER_ABGR,
> },
> {
> .drm = DRM_FORMAT_YUV422,
> @@ -601,7 +600,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
> /* Position Word 2: Source Image Size, Alpha Mode */
> vc4_state->pos2_offset = vc4_state->dlist_count;
> vc4_dlist_write(vc4_state,
> - VC4_SET_FIELD(format->has_alpha ?
> + VC4_SET_FIELD(drm_format_has_alpha(format->drm) ?
> SCALER_POS2_ALPHA_MODE_PIPELINE :
> SCALER_POS2_ALPHA_MODE_FIXED,
> SCALER_POS2_ALPHA_MODE) |
> --
> git-series 0.9.1
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
Hi Maxime,
Thank you for the patch.
On Tuesday, 9 January 2018 12:56:27 EET Maxime Ripard wrote:
> Now that we have support for per-plane alpha in the core, let's use it.
>
> Cc: Laurent Pinchart <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
Reviewed-by: Laurent Pinchart <[email protected]>
> ---
> drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 +-
> drivers/gpu/drm/rcar-du/rcar_du_kms.c | 5 +---
> drivers/gpu/drm/rcar-du/rcar_du_plane.c | 15 +++------
> drivers/gpu/drm/rcar-du/rcar_du_plane.h | 2 +-
> drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 42 ++------------------------
> drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +-
> 6 files changed, 9 insertions(+), 58 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index f8cd79488ece..aff04adaae53
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -89,7 +89,6 @@ struct rcar_du_device {
> struct rcar_du_vsp vsps[RCAR_DU_MAX_VSPS];
>
> struct {
> - struct drm_property *alpha;
> struct drm_property *colorkey;
> } props;
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index 566d1a948c8f..e1b5a7b460cc
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -417,11 +417,6 @@ static int rcar_du_encoders_init(struct rcar_du_device
> *rcdu)
>
> static int rcar_du_properties_init(struct rcar_du_device *rcdu)
> {
> - rcdu->props.alpha =
> - drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255);
> - if (rcdu->props.alpha == NULL)
> - return -ENOMEM;
> -
> /*
> * The color key is expressed as an RGB888 triplet stored in a 32-bit
> * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0)
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index 61833cc1c699..5b34e8092c8b
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
> @@ -423,7 +423,7 @@ static void rcar_du_plane_setup_mode(struct
> rcar_du_group *rgrp, rcar_du_plane_write(rgrp, index, PnALPHAR,
> PnALPHAR_ABIT_0);
> else
> rcar_du_plane_write(rgrp, index, PnALPHAR,
> - PnALPHAR_ABIT_X | state->alpha);
> + PnALPHAR_ABIT_X | state->state.alpha);
>
> pnmr = PnMR_BM_MD | state->format->pnmr;
>
> @@ -667,11 +667,11 @@ static void rcar_du_plane_reset(struct drm_plane
> *plane)
>
> state->hwindex = -1;
> state->source = RCAR_DU_PLANE_MEMORY;
> - state->alpha = 255;
> state->colorkey = RCAR_DU_COLORKEY_NONE;
> state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
>
> plane->state = &state->state;
> + plane->state->alpha = 255;
> plane->state->plane = plane;
> }
>
> @@ -683,9 +683,7 @@ static int rcar_du_plane_atomic_set_property(struct
> drm_plane *plane, struct rcar_du_plane_state *rstate =
> to_rcar_plane_state(state); struct rcar_du_device *rcdu =
> to_rcar_plane(plane)->group->dev;
>
> - if (property == rcdu->props.alpha)
> - rstate->alpha = val;
> - else if (property == rcdu->props.colorkey)
> + if (property == rcdu->props.colorkey)
> rstate->colorkey = val;
> else
> return -EINVAL;
> @@ -701,9 +699,7 @@ static int rcar_du_plane_atomic_get_property(struct
> drm_plane *plane, container_of(state, const struct rcar_du_plane_state,
> state);
> struct rcar_du_device *rcdu = to_rcar_plane(plane)->group->dev;
>
> - if (property == rcdu->props.alpha)
> - *val = rstate->alpha;
> - else if (property == rcdu->props.colorkey)
> + if (property == rcdu->props.colorkey)
> *val = rstate->colorkey;
> else
> return -EINVAL;
> @@ -772,10 +768,9 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
> continue;
>
> drm_object_attach_property(&plane->plane.base,
> - rcdu->props.alpha, 255);
> - drm_object_attach_property(&plane->plane.base,
> rcdu->props.colorkey,
> RCAR_DU_COLORKEY_NONE);
> + drm_plane_create_alpha_property(&plane->plane, 255);
> drm_plane_create_zpos_property(&plane->plane, 1, 1, 7);
> }
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
> b/drivers/gpu/drm/rcar-du/rcar_du_plane.h index f62e09f195de..2dc793ebd1a2
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h
> @@ -50,7 +50,6 @@ static inline struct rcar_du_plane *to_rcar_plane(struct
> drm_plane *plane) * @state: base DRM plane state
> * @format: information about the pixel format used by the plane
> * @hwindex: 0-based hardware plane index, -1 means unused
> - * @alpha: value of the plane alpha property
> * @colorkey: value of the plane colorkey property
> */
> struct rcar_du_plane_state {
> @@ -60,7 +59,6 @@ struct rcar_du_plane_state {
> int hwindex;
> enum rcar_du_plane_source source;
>
> - unsigned int alpha;
> unsigned int colorkey;
> };
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index 2c96147bc444..ee85f6fdffad
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -54,6 +54,7 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
> };
> struct rcar_du_plane_state state = {
> .state = {
> + .alpha = 255,
> .crtc = &crtc->crtc,
> .crtc_x = 0,
> .crtc_y = 0,
> @@ -67,7 +68,6 @@ void rcar_du_vsp_enable(struct rcar_du_crtc *crtc)
> },
> .format = rcar_du_format_info(DRM_FORMAT_ARGB8888),
> .source = RCAR_DU_PLANE_VSPD1,
> - .alpha = 255,
> .colorkey = 0,
> };
>
> @@ -173,7 +173,7 @@ static void rcar_du_vsp_plane_setup(struct
> rcar_du_vsp_plane *plane) struct vsp1_du_atomic_config cfg = {
> .pixelformat = 0,
> .pitch = fb->pitches[0],
> - .alpha = state->alpha,
> + .alpha = state->state.alpha,
> .zpos = state->state.zpos,
> };
> unsigned int i;
> @@ -351,44 +351,13 @@ static void rcar_du_vsp_plane_reset(struct drm_plane
> *plane) if (state == NULL)
> return;
>
> - state->alpha = 255;
> + state->state.alpha = 255;
> state->state.zpos = plane->type == DRM_PLANE_TYPE_PRIMARY ? 0 : 1;
>
> plane->state = &state->state;
> plane->state->plane = plane;
> }
>
> -static int rcar_du_vsp_plane_atomic_set_property(struct drm_plane *plane,
> - struct drm_plane_state *state, struct drm_property *property,
> - uint64_t val)
> -{
> - struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
> - struct rcar_du_device *rcdu = to_rcar_vsp_plane(plane)->vsp->dev;
> -
> - if (property == rcdu->props.alpha)
> - rstate->alpha = val;
> - else
> - return -EINVAL;
> -
> - return 0;
> -}
> -
> -static int rcar_du_vsp_plane_atomic_get_property(struct drm_plane *plane,
> - const struct drm_plane_state *state, struct drm_property *property,
> - uint64_t *val)
> -{
> - const struct rcar_du_vsp_plane_state *rstate =
> - container_of(state, const struct rcar_du_vsp_plane_state, state);
> - struct rcar_du_device *rcdu = to_rcar_vsp_plane(plane)->vsp->dev;
> -
> - if (property == rcdu->props.alpha)
> - *val = rstate->alpha;
> - else
> - return -EINVAL;
> -
> - return 0;
> -}
> -
> static const struct drm_plane_funcs rcar_du_vsp_plane_funcs = {
> .update_plane = drm_atomic_helper_update_plane,
> .disable_plane = drm_atomic_helper_disable_plane,
> @@ -396,8 +365,6 @@ static const struct drm_plane_funcs
> rcar_du_vsp_plane_funcs = { .destroy = drm_plane_cleanup,
> .atomic_duplicate_state = rcar_du_vsp_plane_atomic_duplicate_state,
> .atomic_destroy_state = rcar_du_vsp_plane_atomic_destroy_state,
> - .atomic_set_property = rcar_du_vsp_plane_atomic_set_property,
> - .atomic_get_property = rcar_du_vsp_plane_atomic_get_property,
> };
>
> int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np,
> @@ -454,8 +421,7 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct
> device_node *np, if (type == DRM_PLANE_TYPE_PRIMARY)
> continue;
>
> - drm_object_attach_property(&plane->plane.base,
> - rcdu->props.alpha, 255);
> + drm_plane_create_alpha_property(&plane->plane, 255);
> drm_plane_create_zpos_property(&plane->plane, 1, 1,
> vsp->num_planes - 1);
> }
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h index f876c512163c..8b19914761e4
> 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> @@ -44,7 +44,6 @@ static inline struct rcar_du_vsp_plane
> *to_rcar_vsp_plane(struct drm_plane *p) * @state: base DRM plane state
> * @format: information about the pixel format used by the plane
> * @sg_tables: scatter-gather tables for the frame buffer memory
> - * @alpha: value of the plane alpha property
> * @zpos: value of the plane zpos property
> */
> struct rcar_du_vsp_plane_state {
> @@ -53,7 +52,6 @@ struct rcar_du_vsp_plane_state {
> const struct rcar_du_format_info *format;
> struct sg_table sg_tables[3];
>
> - unsigned int alpha;
> unsigned int zpos;
> };
--
Regards,
Laurent Pinchart
Hi Laurent,
On Tue, Jan 09, 2018 at 02:29:58PM +0200, Laurent Pinchart wrote:
> On Tuesday, 9 January 2018 12:56:20 EET Maxime Ripard wrote:
> > There's a bunch of drivers that duplicate the same function to know if a
> > particular format embeds an alpha component or not.
> >
> > Let's create a helper to avoid duplicating that logic.
> >
> > Cc: Boris Brezillon <[email protected]>
> > Cc: Eric Anholt <[email protected]>
> > Cc: Inki Dae <[email protected]>
> > Cc: Joonyoung Shim <[email protected]>
> > Cc: Kyungmin Park <[email protected]>
> > Cc: Laurent Pinchart <[email protected]>
> > Cc: Mark Yao <[email protected]>
> > Cc: Seung-Woo Kim <[email protected]>
> > Signed-off-by: Maxime Ripard <[email protected]>
> > ---
> > drivers/gpu/drm/drm_fourcc.c | 43 +++++++++++++++++++++++++++++++++++++-
> > include/drm/drm_fourcc.h | 1 +-
> > 2 files changed, 44 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> > index 9c0152df45ad..6e6227d6a46b 100644
> > --- a/drivers/gpu/drm/drm_fourcc.c
> > +++ b/drivers/gpu/drm/drm_fourcc.c
> > @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t
> > format, int plane) return height / info->vsub;
> > }
> > EXPORT_SYMBOL(drm_format_plane_height);
> > +
> > +/**
> > + * drm_format_has_alpha - get whether the format embeds an alpha component
> > + * @format: pixel format (DRM_FORMAT_*)
> > + *
> > + * Returns:
> > + * true if the format embeds an alpha component, false otherwise.
> > + */
> > +bool drm_format_has_alpha(uint32_t format)
> > +{
> > + switch (format) {
> > + case DRM_FORMAT_ARGB4444:
> > + case DRM_FORMAT_ABGR4444:
> > + case DRM_FORMAT_RGBA4444:
> > + case DRM_FORMAT_BGRA4444:
> > + case DRM_FORMAT_ARGB1555:
> > + case DRM_FORMAT_ABGR1555:
> > + case DRM_FORMAT_RGBA5551:
> > + case DRM_FORMAT_BGRA5551:
> > + case DRM_FORMAT_ARGB8888:
> > + case DRM_FORMAT_ABGR8888:
> > + case DRM_FORMAT_RGBA8888:
> > + case DRM_FORMAT_BGRA8888:
> > + case DRM_FORMAT_ARGB2101010:
> > + case DRM_FORMAT_ABGR2101010:
> > + case DRM_FORMAT_RGBA1010102:
> > + case DRM_FORMAT_BGRA1010102:
> > + case DRM_FORMAT_AYUV:
> > + case DRM_FORMAT_XRGB8888_A8:
> > + case DRM_FORMAT_XBGR8888_A8:
> > + case DRM_FORMAT_RGBX8888_A8:
> > + case DRM_FORMAT_BGRX8888_A8:
> > + case DRM_FORMAT_RGB888_A8:
> > + case DRM_FORMAT_BGR888_A8:
> > + case DRM_FORMAT_RGB565_A8:
> > + case DRM_FORMAT_BGR565_A8:
> > + return true;
> > +
> > + default:
> > + return false;
> > + }
> > +}
> > +EXPORT_SYMBOL(drm_format_has_alpha);
>
> How about adding the information to struct drm_format_info instead ?
> drm_format_has_alpha() could then be implemented as
>
> bool drm_format_has_alpha(uint32_t format)
> {
> const struct drm_format_info *info;
>
> info = drm_format_info(format);
> return info ? info->has_alpha : false;
> }
I considered it, and wasn't too sure about if adding more fields to
drm_format_info was ok. I can definitely do it that way.
> although drivers should really use the drm_framebuffer::format field directly
> in most cases, so the helper might not be needed at all.
The drivers converted in my serie shouldn't be too hard to convert to
use drm_format_info directly, so that can be removed as well.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
On Tue, Jan 09, 2018 at 01:32:41PM +0100, Daniel Vetter wrote:
> On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote:
> > Some drivers duplicate the logic to create a property to store a per-plane
> > alpha.
> >
> > Let's create a helper in order to move that to the core.
> >
> > Cc: Boris Brezillon <[email protected]>
> > Cc: Laurent Pinchart <[email protected]>
> > Signed-off-by: Maxime Ripard <[email protected]>
>
> Do we have userspace for this?
Wayland seems to be on its way to implement this, with ChromeOS using
it:
https://lists.freedesktop.org/archives/wayland-devel/2017-August/034741.html
and more specifically:
https://chromium.googlesource.com/chromium/src/+/master/third_party/wayland-protocols/unstable/alpha-compositing/alpha-compositing-unstable-v1.xml#118
> Is encoding a fixed 0-255 range really the best idea?
I don't really know, is there hardware or formats where there is more
than 255? Or did you mean less than that?
> I know other drivers have skimped on the rules here a bit ... But at least
> internally (i.e. within the drm_plane_state) we probably should restrict
> ourselves to u8. And this needs real docs (i.e. the full blend equation
> drivers are supposed to implement).
You mean straight vs premultiplied? Maybe we should implement this as
an additional property in read only depending on how the hardware
behaves?
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
Hi Laurent,
On Tue, Jan 09, 2018 at 02:34:47PM +0200, Laurent Pinchart wrote:
> > Some drivers duplicate the logic to create a property to store a per-plane
> > alpha.
> >
> > Let's create a helper in order to move that to the core.
> >
> > Cc: Boris Brezillon <[email protected]>
> > Cc: Laurent Pinchart <[email protected]>
> > Signed-off-by: Maxime Ripard <[email protected]>
> > ---
> > Documentation/gpu/kms-properties.csv | 2 +-
> > drivers/gpu/drm/drm_atomic.c | 4 ++++-
> > drivers/gpu/drm/drm_atomic_helper.c | 1 +-
> > drivers/gpu/drm/drm_blend.c | 32 +++++++++++++++++++++++++++++-
> > include/drm/drm_blend.h | 1 +-
> > include/drm/drm_plane.h | 6 +++++-
> > 6 files changed, 45 insertions(+), 1 deletion(-)
> >
> > diff --git a/Documentation/gpu/kms-properties.csv
> > b/Documentation/gpu/kms-properties.csv index 927b65e14219..a3c3969c1992
> > 100644
> > --- a/Documentation/gpu/kms-properties.csv
> > +++ b/Documentation/gpu/kms-properties.csv
> > @@ -99,5 +99,5 @@ radeon,DVI-I,“coherent”,RANGE,"Min=0, Max=1",Connector,TBD
> > ,,"""underscan vborder""",RANGE,"Min=0, Max=128",Connector,TBD
> > ,Audio,“audio”,ENUM,"{ ""off"", ""on"", ""auto"" }",Connector,TBD
> > ,FMT Dithering,“dither”,ENUM,"{ ""off"", ""on"" }",Connector,TBD
> > -rcar-du,Generic,"""alpha""",RANGE,"Min=0, Max=255",Plane,TBD
> > +,,"""alpha""",RANGE,"Min=0, Max=255",Plane,Opacity of the plane from
> > transparent (0) to opaque (255) ,,"""colorkey""",RANGE,"Min=0,
> > Max=0x01ffffff",Plane,TBD
>
> I think more documentation is needed. You should explain how the property
> operates and which formats it is applicable to. For instance you need to
> clarify what happens for format that contain an alpha component.
That's a very good point, and I'm not quite sure what should happen in
the first place :)
Should we forbid that configuration?
> > /**
> > + * drm_plane_create_alpha_property - create a new alpha property
> > + * @plane: drm plane
> > + * @alpha: initial value of alpha, from 0 (transparent) to 255 (opaque)
>
> Do you have a use case for initializing the alpha value to something else than
> fully opaque ?
I don't, but thought it might be useful. Maybe it isn't, in which case
I'm totally fine with it getting away.
> > + * This function initializes a generic, mutable, alpha property and
> > + * enables support for it in the DRM core.
> > + *
> > + * Drivers can then attach this property to their plane to enable
> > + * support for configurable plane alpha.
>
> The function attaches the property to the plane, is the
> documentation outdated ?
Yes, I'll fix it.
> > + * Returns:
> > + * 0 on success, negative error code on failure.
> > + */
> > +int drm_plane_create_alpha_property(struct drm_plane *plane, u8 alpha)
> > +{
> > + struct drm_property *prop;
> > +
> > + prop = drm_property_create_range(plane->dev, 0, "alpha", 0, 255);
>
> Do you think the 0-255 range will fit all use cases ?
This is kind of the same discussion we're having with Daniel, but are
there hardware or formats with an alpha component wider than 255?
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
On Tue, Jan 09, 2018 at 02:53:22PM +0100, Maxime Ripard wrote:
> On Tue, Jan 09, 2018 at 01:32:41PM +0100, Daniel Vetter wrote:
> > On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote:
> > > Some drivers duplicate the logic to create a property to store a per-plane
> > > alpha.
> > >
> > > Let's create a helper in order to move that to the core.
> > >
> > > Cc: Boris Brezillon <[email protected]>
> > > Cc: Laurent Pinchart <[email protected]>
> > > Signed-off-by: Maxime Ripard <[email protected]>
> >
> > Do we have userspace for this?
>
> Wayland seems to be on its way to implement this, with ChromeOS using
> it:
> https://lists.freedesktop.org/archives/wayland-devel/2017-August/034741.html
>
> and more specifically:
> https://chromium.googlesource.com/chromium/src/+/master/third_party/wayland-protocols/unstable/alpha-compositing/alpha-compositing-unstable-v1.xml#118
Yay, would be good to include these links in the patch description. Really
happy we're having a real standard now used by multiple people.
> > Is encoding a fixed 0-255 range really the best idea?
>
> I don't really know, is there hardware or formats where there is more
> than 255? Or did you mean less than that?
30bit I'd assume wants more alpha. In the past we've done some fixed-point
stuff (e.g. for LUT), using the 0.0-1.0 float range. Using that for the
blend equation docs is also what I recommend (and that we map from 0-255
to 0.0-1.0 logically). Ofc the hw might not do any of that ... I think
0.16 fixed point, stored in a u16 is probably best. That's what we're
doing for gamma tables already, and that way drivers can simply throw away
the lower bits.
> > I know other drivers have skimped on the rules here a bit ... But at least
> > internally (i.e. within the drm_plane_state) we probably should restrict
> > ourselves to u8. And this needs real docs (i.e. the full blend equation
> > drivers are supposed to implement).
>
> You mean straight vs premultiplied? Maybe we should implement this as
> an additional property in read only depending on how the hardware
> behaves?
No need for an additional property right now, but definitely document
whether you mean straight or pre-multiplied. Just writing down the blend
equation is probably best.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
Maxime Ripard <[email protected]> writes:
> Now that the core has a drm format helper to tell if a format embeds an
> alpha component in it, let's use it.
>
> Cc: Eric Anholt <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
On Tue, Jan 09, 2018 at 03:28:34PM +0100, Daniel Vetter wrote:
> On Tue, Jan 09, 2018 at 02:53:22PM +0100, Maxime Ripard wrote:
> > On Tue, Jan 09, 2018 at 01:32:41PM +0100, Daniel Vetter wrote:
> > > On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote:
> > > > Some drivers duplicate the logic to create a property to store a per-plane
> > > > alpha.
> > > >
> > > > Let's create a helper in order to move that to the core.
> > > >
> > > > Cc: Boris Brezillon <[email protected]>
> > > > Cc: Laurent Pinchart <[email protected]>
> > > > Signed-off-by: Maxime Ripard <[email protected]>
> > >
> > > Do we have userspace for this?
> >
> > Wayland seems to be on its way to implement this, with ChromeOS using
> > it:
> > https://lists.freedesktop.org/archives/wayland-devel/2017-August/034741.html
> >
> > and more specifically:
> > https://chromium.googlesource.com/chromium/src/+/master/third_party/wayland-protocols/unstable/alpha-compositing/alpha-compositing-unstable-v1.xml#118
>
> Yay, would be good to include these links in the patch description. Really
> happy we're having a real standard now used by multiple people.
I will.
> > > Is encoding a fixed 0-255 range really the best idea?
> >
> > I don't really know, is there hardware or formats where there is more
> > than 255? Or did you mean less than that?
>
> 30bit I'd assume wants more alpha. In the past we've done some fixed-point
> stuff (e.g. for LUT), using the 0.0-1.0 float range. Using that for the
> blend equation docs is also what I recommend (and that we map from 0-255
> to 0.0-1.0 logically). Ofc the hw might not do any of that ... I think
> 0.16 fixed point, stored in a u16 is probably best. That's what we're
> doing for gamma tables already, and that way drivers can simply throw away
> the lower bits.
But that would also break the two users of that property that won't be
able to move to the generic property (with the same name) without
breaking userspace. The point of that patch was to allow some code
consolidation, and that would mean failing to do so here :/
> > > I know other drivers have skimped on the rules here a bit ... But at least
> > > internally (i.e. within the drm_plane_state) we probably should restrict
> > > ourselves to u8. And this needs real docs (i.e. the full blend equation
> > > drivers are supposed to implement).
> >
> > You mean straight vs premultiplied? Maybe we should implement this as
> > an additional property in read only depending on how the hardware
> > behaves?
>
> No need for an additional property right now, but definitely document
> whether you mean straight or pre-multiplied. Just writing down the blend
> equation is probably best.
Ack.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
On Thu, Jan 11, 2018 at 4:58 PM, Maxime Ripard
<[email protected]> wrote:
> On Tue, Jan 09, 2018 at 03:28:34PM +0100, Daniel Vetter wrote:
>> On Tue, Jan 09, 2018 at 02:53:22PM +0100, Maxime Ripard wrote:
>> > On Tue, Jan 09, 2018 at 01:32:41PM +0100, Daniel Vetter wrote:
>> > > On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote:
>> > > > Some drivers duplicate the logic to create a property to store a per-plane
>> > > > alpha.
>> > > >
>> > > > Let's create a helper in order to move that to the core.
>> > > >
>> > > > Cc: Boris Brezillon <[email protected]>
>> > > > Cc: Laurent Pinchart <[email protected]>
>> > > > Signed-off-by: Maxime Ripard <[email protected]>
>> > >
>> > > Do we have userspace for this?
>> >
>> > Wayland seems to be on its way to implement this, with ChromeOS using
>> > it:
>> > https://lists.freedesktop.org/archives/wayland-devel/2017-August/034741.html
>> >
>> > and more specifically:
>> > https://chromium.googlesource.com/chromium/src/+/master/third_party/wayland-protocols/unstable/alpha-compositing/alpha-compositing-unstable-v1.xml#118
>>
>> Yay, would be good to include these links in the patch description. Really
>> happy we're having a real standard now used by multiple people.
>
> I will.
>
>> > > Is encoding a fixed 0-255 range really the best idea?
>> >
>> > I don't really know, is there hardware or formats where there is more
>> > than 255? Or did you mean less than that?
>>
>> 30bit I'd assume wants more alpha. In the past we've done some fixed-point
>> stuff (e.g. for LUT), using the 0.0-1.0 float range. Using that for the
>> blend equation docs is also what I recommend (and that we map from 0-255
>> to 0.0-1.0 logically). Ofc the hw might not do any of that ... I think
>> 0.16 fixed point, stored in a u16 is probably best. That's what we're
>> doing for gamma tables already, and that way drivers can simply throw away
>> the lower bits.
>
> But that would also break the two users of that property that won't be
> able to move to the generic property (with the same name) without
> breaking userspace. The point of that patch was to allow some code
> consolidation, and that would mean failing to do so here :/
Let me try to clarify:
- We'll keep the exact existing property semantics with the 0-255
range for the userspace visible property.
- But internally, in the decode value that we store into
drm_plane_state, we'll do the slightly more future proof thing with a
few more bits.
That gives us the option of exposing those bits in the future without
having to change all the drivers again (which we have to do for this
series here already anyway, since the decoded value moves into
drm_plane_state from driver subclasses).
Definitely not asking to break userspace here :-)
Cheers, Daniel
>> > > I know other drivers have skimped on the rules here a bit ... But at least
>> > > internally (i.e. within the drm_plane_state) we probably should restrict
>> > > ourselves to u8. And this needs real docs (i.e. the full blend equation
>> > > drivers are supposed to implement).
>> >
>> > You mean straight vs premultiplied? Maybe we should implement this as
>> > an additional property in read only depending on how the hardware
>> > behaves?
>>
>> No need for an additional property right now, but definitely document
>> whether you mean straight or pre-multiplied. Just writing down the blend
>> equation is probably best.
>
> Ack.
>
> Thanks!
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
>
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
Hi Daniel,
On Thursday, 11 January 2018 18:36:10 EET Daniel Vetter wrote:
> On Thu, Jan 11, 2018 at 4:58 PM, Maxime Ripard wrote:
> > On Tue, Jan 09, 2018 at 03:28:34PM +0100, Daniel Vetter wrote:
> >> On Tue, Jan 09, 2018 at 02:53:22PM +0100, Maxime Ripard wrote:
> >>> On Tue, Jan 09, 2018 at 01:32:41PM +0100, Daniel Vetter wrote:
> >>>> On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote:
> >>>>> Some drivers duplicate the logic to create a property to store a
> >>>>> per-plane alpha.
> >>>>>
> >>>>> Let's create a helper in order to move that to the core.
> >>>>>
> >>>>> Cc: Boris Brezillon <[email protected]>
> >>>>> Cc: Laurent Pinchart <[email protected]>
> >>>>> Signed-off-by: Maxime Ripard <[email protected]>
> >>>>
> >>>> Do we have userspace for this?
> >>>
> >>> Wayland seems to be on its way to implement this, with ChromeOS using
> >>> it:
> >>> https://lists.freedesktop.org/archives/wayland-devel/2017-August/034741
> >>> .html
> >>>
> >>> and more specifically:
> >>> https://chromium.googlesource.com/chromium/src/+/master/third_party/way
> >>> land-protocols/unstable/alpha-compositing/alpha-compositing-unstable-v1
> >>> .xml#118
> >>
> >> Yay, would be good to include these links in the patch description.
> >> Really happy we're having a real standard now used by multiple people.
> >
> > I will.
> >
> >> > > Is encoding a fixed 0-255 range really the best idea?
> >> >
> >> > I don't really know, is there hardware or formats where there is more
> >> > than 255? Or did you mean less than that?
> >>
> >> 30bit I'd assume wants more alpha. In the past we've done some
> >> fixed-point stuff (e.g. for LUT), using the 0.0-1.0 float range. Using
> >> that for the blend equation docs is also what I recommend (and that we
> >> map from 0-255 to 0.0-1.0 logically). Ofc the hw might not do any of that
> >> ... I think 0.16 fixed point, stored in a u16 is probably best. That's
> >> what we're doing for gamma tables already, and that way drivers can
> >> simply throw away the lower bits.
> >
> > But that would also break the two users of that property that won't be
> > able to move to the generic property (with the same name) without
> > breaking userspace. The point of that patch was to allow some code
> > consolidation, and that would mean failing to do so here :/
>
> Let me try to clarify:
> - We'll keep the exact existing property semantics with the 0-255
> range for the userspace visible property.
>
> - But internally, in the decode value that we store into
> drm_plane_state, we'll do the slightly more future proof thing with a
> few more bits.
>
> That gives us the option of exposing those bits in the future without
> having to change all the drivers again (which we have to do for this
> series here already anyway, since the decoded value moves into
> drm_plane_state from driver subclasses).
>
> Definitely not asking to break userspace here :-)
As the property range is available to userspace, we could allow drivers to
expose a driver-dependent number of bits for the alpha value without breaking
anything. We can even require new drivers to expose 16 bits regardless of the
number of bits that the hardware can handle, or we could keep that driver-
specific.
Please note, however, that U0.16 can only represent [0.0, 0.999984741...]
while we need [0.0, 1.0]. As all the hardware I know map the full range of
values ([0, 255] for 8-bit for instance) to [0.0, 1.0] I wouldn't pretend that
the 16-bit value exposed to userspace is U0.16.
> >>>> I know other drivers have skimped on the rules here a bit ... But at
> >>>> least internally (i.e. within the drm_plane_state) we probably should
> >>>> restrict ourselves to u8. And this needs real docs (i.e. the full blend
> >>>> equation drivers are supposed to implement).
> >>>
> >>> You mean straight vs premultiplied? Maybe we should implement this as
> >>> an additional property in read only depending on how the hardware
> >>> behaves?
> >>
> >> No need for an additional property right now, but definitely document
> >> whether you mean straight or pre-multiplied. Just writing down the blend
> >> equation is probably best.
--
Regards,
Laurent Pinchart
2018년 01월 09일 19:56에 Maxime Ripard 이(가) 쓴 글:
> Now that the core has a drm format helper to tell if a format embeds an
> alpha component in it, let's use it.
>
> Cc: Inki Dae <[email protected]>
> Cc: Joonyoung Shim <[email protected]>
> Cc: Kyungmin Park <[email protected]>
> Cc: Seung-Woo Kim <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
Acked-by: Inki Dae <[email protected]>
Thanks,
Inki Dae
> ---
> drivers/gpu/drm/exynos/exynos_mixer.c | 14 +-------------
> 1 file changed, 1 insertion(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
> index dc5d79465f9b..d7339a6d072c 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -179,18 +179,6 @@ static const u8 filter_cr_horiz_tap4[] = {
> 70, 59, 48, 37, 27, 19, 11, 5,
> };
>
> -static inline bool is_alpha_format(unsigned int pixel_format)
> -{
> - switch (pixel_format) {
> - case DRM_FORMAT_ARGB8888:
> - case DRM_FORMAT_ARGB1555:
> - case DRM_FORMAT_ARGB4444:
> - return true;
> - default:
> - return false;
> - }
> -}
> -
> static inline u32 vp_reg_read(struct mixer_context *ctx, u32 reg_id)
> {
> return readl(ctx->vp_regs + reg_id);
> @@ -625,7 +613,7 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
> mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr);
>
> mixer_cfg_layer(ctx, win, priority, true);
> - mixer_cfg_gfx_blend(ctx, win, is_alpha_format(fb->format->format));
> + mixer_cfg_gfx_blend(ctx, win, drm_format_has_alpha(fb->format->format));
>
> /* layer update mandatory for mixer 16.0.33.0 */
> if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
>
On Tue, Jan 09, 2018 at 02:28:33PM +0100, Maxime Ripard wrote:
> Hi Laurent,
>
> On Tue, Jan 09, 2018 at 02:29:58PM +0200, Laurent Pinchart wrote:
> > On Tuesday, 9 January 2018 12:56:20 EET Maxime Ripard wrote:
> > > There's a bunch of drivers that duplicate the same function to know if a
> > > particular format embeds an alpha component or not.
> > >
> > > Let's create a helper to avoid duplicating that logic.
> > >
> > > Cc: Boris Brezillon <[email protected]>
> > > Cc: Eric Anholt <[email protected]>
> > > Cc: Inki Dae <[email protected]>
> > > Cc: Joonyoung Shim <[email protected]>
> > > Cc: Kyungmin Park <[email protected]>
> > > Cc: Laurent Pinchart <[email protected]>
> > > Cc: Mark Yao <[email protected]>
> > > Cc: Seung-Woo Kim <[email protected]>
> > > Signed-off-by: Maxime Ripard <[email protected]>
> > > ---
> > > drivers/gpu/drm/drm_fourcc.c | 43 +++++++++++++++++++++++++++++++++++++-
> > > include/drm/drm_fourcc.h | 1 +-
> > > 2 files changed, 44 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> > > index 9c0152df45ad..6e6227d6a46b 100644
> > > --- a/drivers/gpu/drm/drm_fourcc.c
> > > +++ b/drivers/gpu/drm/drm_fourcc.c
> > > @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t
> > > format, int plane) return height / info->vsub;
> > > }
> > > EXPORT_SYMBOL(drm_format_plane_height);
> > > +
> > > +/**
> > > + * drm_format_has_alpha - get whether the format embeds an alpha component
> > > + * @format: pixel format (DRM_FORMAT_*)
> > > + *
> > > + * Returns:
> > > + * true if the format embeds an alpha component, false otherwise.
> > > + */
> > > +bool drm_format_has_alpha(uint32_t format)
> > > +{
> > > + switch (format) {
> > > + case DRM_FORMAT_ARGB4444:
> > > + case DRM_FORMAT_ABGR4444:
> > > + case DRM_FORMAT_RGBA4444:
> > > + case DRM_FORMAT_BGRA4444:
> > > + case DRM_FORMAT_ARGB1555:
> > > + case DRM_FORMAT_ABGR1555:
> > > + case DRM_FORMAT_RGBA5551:
> > > + case DRM_FORMAT_BGRA5551:
> > > + case DRM_FORMAT_ARGB8888:
> > > + case DRM_FORMAT_ABGR8888:
> > > + case DRM_FORMAT_RGBA8888:
> > > + case DRM_FORMAT_BGRA8888:
> > > + case DRM_FORMAT_ARGB2101010:
> > > + case DRM_FORMAT_ABGR2101010:
> > > + case DRM_FORMAT_RGBA1010102:
> > > + case DRM_FORMAT_BGRA1010102:
> > > + case DRM_FORMAT_AYUV:
> > > + case DRM_FORMAT_XRGB8888_A8:
> > > + case DRM_FORMAT_XBGR8888_A8:
> > > + case DRM_FORMAT_RGBX8888_A8:
> > > + case DRM_FORMAT_BGRX8888_A8:
> > > + case DRM_FORMAT_RGB888_A8:
> > > + case DRM_FORMAT_BGR888_A8:
> > > + case DRM_FORMAT_RGB565_A8:
> > > + case DRM_FORMAT_BGR565_A8:
> > > + return true;
> > > +
> > > + default:
> > > + return false;
> > > + }
> > > +}
> > > +EXPORT_SYMBOL(drm_format_has_alpha);
> >
> > How about adding the information to struct drm_format_info instead ?
> > drm_format_has_alpha() could then be implemented as
> >
> > bool drm_format_has_alpha(uint32_t format)
> > {
> > const struct drm_format_info *info;
> >
> > info = drm_format_info(format);
> > return info ? info->has_alpha : false;
> > }
>
> I considered it, and wasn't too sure about if adding more fields to
> drm_format_info was ok. I can definitely do it that way.
Are you going to send an updated patch with the change mentioned here.
Or should I update my patch (https://patchwork.kernel.org/patch/10161023/)
and change the type of '.alpha' to boolean to denote if the color
format has an alpha channel or not.
> > although drivers should really use the drm_framebuffer::format field directly
> > in most cases, so the helper might not be needed at all.
>
> The drivers converted in my serie shouldn't be too hard to convert to
> use drm_format_info directly, so that can be removed as well.
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
在 2018/1/9 18:56, Maxime Ripard 写道:
> Now that the core has a drm format helper to tell if a format embeds an
> alpha component in it, let's use it.
>
> Cc: Mark Yao <[email protected]>
> Signed-off-by: Maxime Ripard <[email protected]>
> ---
> drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 +------------
> 1 file changed, 1 insertion(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 19128b4dea54..cfc4d4909185 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -253,17 +253,6 @@ static bool is_yuv_support(uint32_t format)
> }
> }
>
> -static bool is_alpha_support(uint32_t format)
> -{
> - switch (format) {
> - case DRM_FORMAT_ARGB8888:
> - case DRM_FORMAT_ABGR8888:
> - return true;
> - default:
> - return false;
> - }
> -}
> -
> static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
> uint32_t dst, bool is_horizontal,
> int vsu_mode, int *vskiplines)
> @@ -790,7 +779,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
> rb_swap = has_rb_swapped(fb->format->format);
> VOP_WIN_SET(vop, win, rb_swap, rb_swap);
>
> - if (is_alpha_support(fb->format->format)) {
> + if (drm_format_has_alpha(fb->format->format)) {
> VOP_WIN_SET(vop, win, dst_alpha_ctl,
> DST_FACTOR_M0(ALPHA_SRC_INVERSE));
> val = SRC_ALPHA_EN(1) | SRC_COLOR_M0(ALPHA_SRC_PRE_MUL) |
>
remove dead email: Mark Yao <[email protected]>
Acked-by: Sandy huang <[email protected]>
On Tue, Jan 09, 2018 at 02:28:33PM +0100, Maxime Ripard wrote:
> Hi Laurent,
>
> On Tue, Jan 09, 2018 at 02:29:58PM +0200, Laurent Pinchart wrote:
> > On Tuesday, 9 January 2018 12:56:20 EET Maxime Ripard wrote:
> > > There's a bunch of drivers that duplicate the same function to know if a
> > > particular format embeds an alpha component or not.
> > >
> > > Let's create a helper to avoid duplicating that logic.
> > >
> > > Cc: Boris Brezillon <[email protected]>
> > > Cc: Eric Anholt <[email protected]>
> > > Cc: Inki Dae <[email protected]>
> > > Cc: Joonyoung Shim <[email protected]>
> > > Cc: Kyungmin Park <[email protected]>
> > > Cc: Laurent Pinchart <[email protected]>
> > > Cc: Mark Yao <[email protected]>
> > > Cc: Seung-Woo Kim <[email protected]>
> > > Signed-off-by: Maxime Ripard <[email protected]>
> > > ---
> > > drivers/gpu/drm/drm_fourcc.c | 43 +++++++++++++++++++++++++++++++++++++-
> > > include/drm/drm_fourcc.h | 1 +-
> > > 2 files changed, 44 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> > > index 9c0152df45ad..6e6227d6a46b 100644
> > > --- a/drivers/gpu/drm/drm_fourcc.c
> > > +++ b/drivers/gpu/drm/drm_fourcc.c
> > > @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t
> > > format, int plane) return height / info->vsub;
> > > }
> > > EXPORT_SYMBOL(drm_format_plane_height);
> > > +
> > > +/**
> > > + * drm_format_has_alpha - get whether the format embeds an alpha component
> > > + * @format: pixel format (DRM_FORMAT_*)
> > > + *
> > > + * Returns:
> > > + * true if the format embeds an alpha component, false otherwise.
> > > + */
> > > +bool drm_format_has_alpha(uint32_t format)
> > > +{
> > > + switch (format) {
> > > + case DRM_FORMAT_ARGB4444:
> > > + case DRM_FORMAT_ABGR4444:
> > > + case DRM_FORMAT_RGBA4444:
> > > + case DRM_FORMAT_BGRA4444:
> > > + case DRM_FORMAT_ARGB1555:
> > > + case DRM_FORMAT_ABGR1555:
> > > + case DRM_FORMAT_RGBA5551:
> > > + case DRM_FORMAT_BGRA5551:
> > > + case DRM_FORMAT_ARGB8888:
> > > + case DRM_FORMAT_ABGR8888:
> > > + case DRM_FORMAT_RGBA8888:
> > > + case DRM_FORMAT_BGRA8888:
> > > + case DRM_FORMAT_ARGB2101010:
> > > + case DRM_FORMAT_ABGR2101010:
> > > + case DRM_FORMAT_RGBA1010102:
> > > + case DRM_FORMAT_BGRA1010102:
> > > + case DRM_FORMAT_AYUV:
> > > + case DRM_FORMAT_XRGB8888_A8:
> > > + case DRM_FORMAT_XBGR8888_A8:
> > > + case DRM_FORMAT_RGBX8888_A8:
> > > + case DRM_FORMAT_BGRX8888_A8:
> > > + case DRM_FORMAT_RGB888_A8:
> > > + case DRM_FORMAT_BGR888_A8:
> > > + case DRM_FORMAT_RGB565_A8:
> > > + case DRM_FORMAT_BGR565_A8:
> > > + return true;
> > > +
> > > + default:
> > > + return false;
> > > + }
> > > +}
> > > +EXPORT_SYMBOL(drm_format_has_alpha);
> >
> > How about adding the information to struct drm_format_info instead ?
> > drm_format_has_alpha() could then be implemented as
> >
> > bool drm_format_has_alpha(uint32_t format)
> > {
> > const struct drm_format_info *info;
> >
> > info = drm_format_info(format);
> > return info ? info->has_alpha : false;
> > }
>
> I considered it, and wasn't too sure about if adding more fields to
> drm_format_info was ok. I can definitely do it that way.\
Are you going to send an updated patch with the change mentioned here.
Or should I update my patch (https://patchwork.kernel.org/patch/10161023/)
and change the type of '.alpha' to boolean to denote if the color
format has an alpha channel or not.
>
> > although drivers should really use the drm_framebuffer::format field directly
> > in most cases, so the helper might not be needed at all.
>
> The drivers converted in my serie shouldn't be too hard to convert to
> use drm_format_info directly, so that can be removed as well.
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
> _______________________________________________
> dri-devel mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
Hi Ayan,
On Mon, Jan 15, 2018 at 03:47:44PM +0000, Ayan Halder wrote:
> On Tue, Jan 09, 2018 at 02:28:33PM +0100, Maxime Ripard wrote:
> > On Tue, Jan 09, 2018 at 02:29:58PM +0200, Laurent Pinchart wrote:
> > > On Tuesday, 9 January 2018 12:56:20 EET Maxime Ripard wrote:
> > > > There's a bunch of drivers that duplicate the same function to know if a
> > > > particular format embeds an alpha component or not.
> > > >
> > > > Let's create a helper to avoid duplicating that logic.
> > > >
> > > > Cc: Boris Brezillon <[email protected]>
> > > > Cc: Eric Anholt <[email protected]>
> > > > Cc: Inki Dae <[email protected]>
> > > > Cc: Joonyoung Shim <[email protected]>
> > > > Cc: Kyungmin Park <[email protected]>
> > > > Cc: Laurent Pinchart <[email protected]>
> > > > Cc: Mark Yao <[email protected]>
> > > > Cc: Seung-Woo Kim <[email protected]>
> > > > Signed-off-by: Maxime Ripard <[email protected]>
> > > > ---
> > > > drivers/gpu/drm/drm_fourcc.c | 43 +++++++++++++++++++++++++++++++++++++-
> > > > include/drm/drm_fourcc.h | 1 +-
> > > > 2 files changed, 44 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> > > > index 9c0152df45ad..6e6227d6a46b 100644
> > > > --- a/drivers/gpu/drm/drm_fourcc.c
> > > > +++ b/drivers/gpu/drm/drm_fourcc.c
> > > > @@ -348,3 +348,46 @@ int drm_format_plane_height(int height, uint32_t
> > > > format, int plane) return height / info->vsub;
> > > > }
> > > > EXPORT_SYMBOL(drm_format_plane_height);
> > > > +
> > > > +/**
> > > > + * drm_format_has_alpha - get whether the format embeds an alpha component
> > > > + * @format: pixel format (DRM_FORMAT_*)
> > > > + *
> > > > + * Returns:
> > > > + * true if the format embeds an alpha component, false otherwise.
> > > > + */
> > > > +bool drm_format_has_alpha(uint32_t format)
> > > > +{
> > > > + switch (format) {
> > > > + case DRM_FORMAT_ARGB4444:
> > > > + case DRM_FORMAT_ABGR4444:
> > > > + case DRM_FORMAT_RGBA4444:
> > > > + case DRM_FORMAT_BGRA4444:
> > > > + case DRM_FORMAT_ARGB1555:
> > > > + case DRM_FORMAT_ABGR1555:
> > > > + case DRM_FORMAT_RGBA5551:
> > > > + case DRM_FORMAT_BGRA5551:
> > > > + case DRM_FORMAT_ARGB8888:
> > > > + case DRM_FORMAT_ABGR8888:
> > > > + case DRM_FORMAT_RGBA8888:
> > > > + case DRM_FORMAT_BGRA8888:
> > > > + case DRM_FORMAT_ARGB2101010:
> > > > + case DRM_FORMAT_ABGR2101010:
> > > > + case DRM_FORMAT_RGBA1010102:
> > > > + case DRM_FORMAT_BGRA1010102:
> > > > + case DRM_FORMAT_AYUV:
> > > > + case DRM_FORMAT_XRGB8888_A8:
> > > > + case DRM_FORMAT_XBGR8888_A8:
> > > > + case DRM_FORMAT_RGBX8888_A8:
> > > > + case DRM_FORMAT_BGRX8888_A8:
> > > > + case DRM_FORMAT_RGB888_A8:
> > > > + case DRM_FORMAT_BGR888_A8:
> > > > + case DRM_FORMAT_RGB565_A8:
> > > > + case DRM_FORMAT_BGR565_A8:
> > > > + return true;
> > > > +
> > > > + default:
> > > > + return false;
> > > > + }
> > > > +}
> > > > +EXPORT_SYMBOL(drm_format_has_alpha);
> > >
> > > How about adding the information to struct drm_format_info instead ?
> > > drm_format_has_alpha() could then be implemented as
> > >
> > > bool drm_format_has_alpha(uint32_t format)
> > > {
> > > const struct drm_format_info *info;
> > >
> > > info = drm_format_info(format);
> > > return info ? info->has_alpha : false;
> > > }
> >
> > I considered it, and wasn't too sure about if adding more fields to
> > drm_format_info was ok. I can definitely do it that way.
>
> Are you going to send an updated patch with the change mentioned here.
> Or should I update my patch (https://patchwork.kernel.org/patch/10161023/)
> and change the type of '.alpha' to boolean to denote if the color
> format has an alpha channel or not.
Yes, I already had those patches ready. I'm just waiting for the
discussion on the alpha property to settle before sending a v2.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
On Thu, Jan 11, 2018 at 08:34:58PM +0200, Laurent Pinchart wrote:
> Hi Daniel,
>
> On Thursday, 11 January 2018 18:36:10 EET Daniel Vetter wrote:
> > On Thu, Jan 11, 2018 at 4:58 PM, Maxime Ripard wrote:
> > > On Tue, Jan 09, 2018 at 03:28:34PM +0100, Daniel Vetter wrote:
> > >> On Tue, Jan 09, 2018 at 02:53:22PM +0100, Maxime Ripard wrote:
> > >>> On Tue, Jan 09, 2018 at 01:32:41PM +0100, Daniel Vetter wrote:
> > >>>> On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote:
> > >>>>> Some drivers duplicate the logic to create a property to store a
> > >>>>> per-plane alpha.
> > >>>>>
> > >>>>> Let's create a helper in order to move that to the core.
> > >>>>>
> > >>>>> Cc: Boris Brezillon <[email protected]>
> > >>>>> Cc: Laurent Pinchart <[email protected]>
> > >>>>> Signed-off-by: Maxime Ripard <[email protected]>
> > >>>>
> > >>>> Do we have userspace for this?
> > >>>
> > >>> Wayland seems to be on its way to implement this, with ChromeOS using
> > >>> it:
> > >>> https://lists.freedesktop.org/archives/wayland-devel/2017-August/034741
> > >>> .html
> > >>>
> > >>> and more specifically:
> > >>> https://chromium.googlesource.com/chromium/src/+/master/third_party/way
> > >>> land-protocols/unstable/alpha-compositing/alpha-compositing-unstable-v1
> > >>> .xml#118
> > >>
> > >> Yay, would be good to include these links in the patch description.
> > >> Really happy we're having a real standard now used by multiple people.
> > >
> > > I will.
> > >
> > >> > > Is encoding a fixed 0-255 range really the best idea?
> > >> >
> > >> > I don't really know, is there hardware or formats where there is more
> > >> > than 255? Or did you mean less than that?
> > >>
> > >> 30bit I'd assume wants more alpha. In the past we've done some
> > >> fixed-point stuff (e.g. for LUT), using the 0.0-1.0 float range. Using
> > >> that for the blend equation docs is also what I recommend (and that we
> > >> map from 0-255 to 0.0-1.0 logically). Ofc the hw might not do any of that
> > >> ... I think 0.16 fixed point, stored in a u16 is probably best. That's
> > >> what we're doing for gamma tables already, and that way drivers can
> > >> simply throw away the lower bits.
> > >
> > > But that would also break the two users of that property that won't be
> > > able to move to the generic property (with the same name) without
> > > breaking userspace. The point of that patch was to allow some code
> > > consolidation, and that would mean failing to do so here :/
> >
> > Let me try to clarify:
> > - We'll keep the exact existing property semantics with the 0-255
> > range for the userspace visible property.
> >
> > - But internally, in the decode value that we store into
> > drm_plane_state, we'll do the slightly more future proof thing with a
> > few more bits.
> >
> > That gives us the option of exposing those bits in the future without
> > having to change all the drivers again (which we have to do for this
> > series here already anyway, since the decoded value moves into
> > drm_plane_state from driver subclasses).
> >
> > Definitely not asking to break userspace here :-)
>
> As the property range is available to userspace, we could allow drivers to
> expose a driver-dependent number of bits for the alpha value without breaking
> anything. We can even require new drivers to expose 16 bits regardless of the
> number of bits that the hardware can handle, or we could keep that driver-
> specific.
>
> Please note, however, that U0.16 can only represent [0.0, 0.999984741...]
> while we need [0.0, 1.0]. As all the hardware I know map the full range of
> values ([0, 255] for 8-bit for instance) to [0.0, 1.0] I wouldn't pretend that
> the 16-bit value exposed to userspace is U0.16.
So this would involve not changing too much the current patch, but
instead extending the type from an u8 to an u16. Would that work for
you Daniel?
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
On Wed, Jan 17, 2018 at 10:20:24AM +0100, Maxime Ripard wrote:
> On Thu, Jan 11, 2018 at 08:34:58PM +0200, Laurent Pinchart wrote:
> > Hi Daniel,
> >
> > On Thursday, 11 January 2018 18:36:10 EET Daniel Vetter wrote:
> > > On Thu, Jan 11, 2018 at 4:58 PM, Maxime Ripard wrote:
> > > > On Tue, Jan 09, 2018 at 03:28:34PM +0100, Daniel Vetter wrote:
> > > >> On Tue, Jan 09, 2018 at 02:53:22PM +0100, Maxime Ripard wrote:
> > > >>> On Tue, Jan 09, 2018 at 01:32:41PM +0100, Daniel Vetter wrote:
> > > >>>> On Tue, Jan 09, 2018 at 11:56:25AM +0100, Maxime Ripard wrote:
> > > >>>>> Some drivers duplicate the logic to create a property to store a
> > > >>>>> per-plane alpha.
> > > >>>>>
> > > >>>>> Let's create a helper in order to move that to the core.
> > > >>>>>
> > > >>>>> Cc: Boris Brezillon <[email protected]>
> > > >>>>> Cc: Laurent Pinchart <[email protected]>
> > > >>>>> Signed-off-by: Maxime Ripard <[email protected]>
> > > >>>>
> > > >>>> Do we have userspace for this?
> > > >>>
> > > >>> Wayland seems to be on its way to implement this, with ChromeOS using
> > > >>> it:
> > > >>> https://lists.freedesktop.org/archives/wayland-devel/2017-August/034741
> > > >>> .html
> > > >>>
> > > >>> and more specifically:
> > > >>> https://chromium.googlesource.com/chromium/src/+/master/third_party/way
> > > >>> land-protocols/unstable/alpha-compositing/alpha-compositing-unstable-v1
> > > >>> .xml#118
> > > >>
> > > >> Yay, would be good to include these links in the patch description.
> > > >> Really happy we're having a real standard now used by multiple people.
> > > >
> > > > I will.
> > > >
> > > >> > > Is encoding a fixed 0-255 range really the best idea?
> > > >> >
> > > >> > I don't really know, is there hardware or formats where there is more
> > > >> > than 255? Or did you mean less than that?
> > > >>
> > > >> 30bit I'd assume wants more alpha. In the past we've done some
> > > >> fixed-point stuff (e.g. for LUT), using the 0.0-1.0 float range. Using
> > > >> that for the blend equation docs is also what I recommend (and that we
> > > >> map from 0-255 to 0.0-1.0 logically). Ofc the hw might not do any of that
> > > >> ... I think 0.16 fixed point, stored in a u16 is probably best. That's
> > > >> what we're doing for gamma tables already, and that way drivers can
> > > >> simply throw away the lower bits.
> > > >
> > > > But that would also break the two users of that property that won't be
> > > > able to move to the generic property (with the same name) without
> > > > breaking userspace. The point of that patch was to allow some code
> > > > consolidation, and that would mean failing to do so here :/
> > >
> > > Let me try to clarify:
> > > - We'll keep the exact existing property semantics with the 0-255
> > > range for the userspace visible property.
> > >
> > > - But internally, in the decode value that we store into
> > > drm_plane_state, we'll do the slightly more future proof thing with a
> > > few more bits.
> > >
> > > That gives us the option of exposing those bits in the future without
> > > having to change all the drivers again (which we have to do for this
> > > series here already anyway, since the decoded value moves into
> > > drm_plane_state from driver subclasses).
> > >
> > > Definitely not asking to break userspace here :-)
> >
> > As the property range is available to userspace, we could allow drivers to
> > expose a driver-dependent number of bits for the alpha value without breaking
> > anything. We can even require new drivers to expose 16 bits regardless of the
> > number of bits that the hardware can handle, or we could keep that driver-
> > specific.
> >
> > Please note, however, that U0.16 can only represent [0.0, 0.999984741...]
> > while we need [0.0, 1.0]. As all the hardware I know map the full range of
> > values ([0, 255] for 8-bit for instance) to [0.0, 1.0] I wouldn't pretend that
> > the 16-bit value exposed to userspace is U0.16.
>
> So this would involve not changing too much the current patch, but
> instead extending the type from an u8 to an u16. Would that work for
> you Daniel?
Yeah, Laurent's clarification is what I've meant ... And hopefully it's
enough future-proofing that we don't need to redo this all again.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch