Skip to content

Commit 44d1240

Browse files
mszyprowBenjamin-Gaignard
authored andcommitted
drm: add generic zpos property
version 8: - move drm_blend.o from drm-y to drm_kms_helper-y to avoid EXPORT_SYMBOL(drm_atomic_helper_normalize_zpos) - remove dead function declarations in drm_crtc.h version 7: - remove useless EXPORT_SYMBOL() - better z-order wording in Documentation version 6: - add zpos in gpu documentation file - merge Ville patch about zpos initial value and API improvement. I have split Ville patch between zpos core and drivers version 5: - remove zpos range check and comeback to 0 to N-1 normalization algorithm version 4: - make sure that normalized zpos value is stay in the defined property range and warn user if not This patch adds support for generic plane's zpos property property with well-defined semantics: - added zpos properties to plane and plane state structures - added helpers for normalizing zpos properties of given set of planes - well defined semantics: planes are sorted by zpos values and then plane id value if zpos equals Normalized zpos values are calculated automatically when generic muttable zpos property has been initialized. Drivers can simply use plane_state->normalized_zpos in their atomic_check and/or plane_update callbacks without any additional calls to DRM core. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Compare to Marek's original patch zpos property is now specific to each plane and no more to the core. Normalize function take care of the range of per plane defined range before set normalized_zpos. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Inki Dae <inki.dae@samsung.com> Cc: Daniel Vetter <daniel@ffwll.ch> Cc: Ville Syrjala <ville.syrjala@linux.intel.com> Cc: Joonyoung Shim <jy0922.shim@samsung.com> Cc: Seung-Woo Kim <sw0312.kim@samsung.com> Cc: Andrzej Hajda <a.hajda@samsung.com> Cc: Krzysztof Kozlowski <k.kozlowski@samsung.com> Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Cc: Tobias Jakobi <tjakobi@math.uni-bielefeld.de> Cc: Gustavo Padovan <gustavo@padovan.org> Cc: vincent.abriou@st.com Cc: fabien.dessenne@st.com Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
1 parent 62c2cd0 commit 44d1240

File tree

7 files changed

+275
-1
lines changed

7 files changed

+275
-1
lines changed

Documentation/gpu/kms-properties.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ DRM,Generic,“rotation”,BITMASK,"{ 0, ""rotate-0"" }, { 1, ""rotate-90"" }, {
1717
,,“CRTC_H”,RANGE,"Min=0, Max=UINT_MAX",Plane,Scanout CRTC (destination) height (atomic)
1818
,,“FB_ID”,OBJECT,DRM_MODE_OBJECT_FB,Plane,Scanout framebuffer (atomic)
1919
,,“CRTC_ID”,OBJECT,DRM_MODE_OBJECT_CRTC,Plane,CRTC that plane is attached to (atomic)
20+
,,“zpos”,RANGE,"Min=0, Max=UINT_MAX","Plane,Z-order of the plane.Planes with higher Z-order values are displayed on top, planes with identical Z-order values are display in an undefined order"
2021
,DVI-I,“subconnector”,ENUM,"{ “Unknown”, “DVI-D”, “DVI-A” }",Connector,TBD
2122
,,“select subconnector”,ENUM,"{ “Automatic”, “DVI-D”, “DVI-A” }",Connector,TBD
2223
,TV,“subconnector”,ENUM,"{ ""Unknown"", ""Composite"", ""SVIDEO"", ""Component"", ""SCART"" }",Connector,TBD

drivers/gpu/drm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
2424
drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
2525
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
2626
drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
27-
drm_simple_kms_helper.o
27+
drm_simple_kms_helper.o drm_blend.o
2828

2929
drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
3030
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o

drivers/gpu/drm/drm_atomic.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,8 @@ int drm_atomic_plane_set_property(struct drm_plane *plane,
711711
state->src_h = val;
712712
} else if (property == config->rotation_property) {
713713
state->rotation = val;
714+
} else if (property == plane->zpos_property) {
715+
state->zpos = val;
714716
} else if (plane->funcs->atomic_set_property) {
715717
return plane->funcs->atomic_set_property(plane, state,
716718
property, val);
@@ -767,6 +769,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
767769
*val = state->src_h;
768770
} else if (property == config->rotation_property) {
769771
*val = state->rotation;
772+
} else if (property == plane->zpos_property) {
773+
*val = state->zpos;
770774
} else if (plane->funcs->atomic_get_property) {
771775
return plane->funcs->atomic_get_property(plane, state, property, val);
772776
} else {

drivers/gpu/drm/drm_atomic_helper.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <drm/drm_atomic_helper.h>
3333
#include <linux/fence.h>
3434

35+
#include "drm_crtc_internal.h"
36+
3537
/**
3638
* DOC: overview
3739
*
@@ -592,6 +594,10 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
592594
struct drm_plane_state *plane_state;
593595
int i, ret = 0;
594596

597+
ret = drm_atomic_helper_normalize_zpos(dev, state);
598+
if (ret)
599+
return ret;
600+
595601
for_each_plane_in_state(state, plane, plane_state, i) {
596602
const struct drm_plane_helper_funcs *funcs;
597603

@@ -2955,6 +2961,7 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
29552961
state->planes_changed = false;
29562962
state->connectors_changed = false;
29572963
state->color_mgmt_changed = false;
2964+
state->zpos_changed = false;
29582965
state->event = NULL;
29592966
}
29602967
EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);

drivers/gpu/drm/drm_blend.c

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/*
2+
* Copyright (C) 2016 Samsung Electronics Co.Ltd
3+
* Authors:
4+
* Marek Szyprowski <m.szyprowski@samsung.com>
5+
*
6+
* DRM core plane blending related functions
7+
*
8+
* Permission to use, copy, modify, distribute, and sell this software and its
9+
* documentation for any purpose is hereby granted without fee, provided that
10+
* the above copyright notice appear in all copies and that both that copyright
11+
* notice and this permission notice appear in supporting documentation, and
12+
* that the name of the copyright holders not be used in advertising or
13+
* publicity pertaining to distribution of the software without specific,
14+
* written prior permission. The copyright holders make no representations
15+
* about the suitability of this software for any purpose. It is provided "as
16+
* is" without express or implied warranty.
17+
*
18+
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19+
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20+
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21+
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22+
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23+
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24+
* OF THIS SOFTWARE.
25+
*/
26+
#include <drm/drmP.h>
27+
#include <drm/drm_atomic.h>
28+
#include <drm/drm_crtc.h>
29+
#include <linux/export.h>
30+
#include <linux/slab.h>
31+
#include <linux/sort.h>
32+
33+
#include "drm_internal.h"
34+
35+
/**
36+
* drm_plane_create_zpos_property - create mutable zpos property
37+
* @plane: drm plane
38+
* @zpos: initial value of zpos property
39+
* @min: minimal possible value of zpos property
40+
* @max: maximal possible value of zpos property
41+
*
42+
* This function initializes generic mutable zpos property and enables support
43+
* for it in drm core. Drivers can then attach this property to planes to enable
44+
* support for configurable planes arrangement during blending operation.
45+
* Once mutable zpos property has been enabled, the DRM core will automatically
46+
* calculate drm_plane_state->normalized_zpos values. Usually min should be set
47+
* to 0 and max to maximal number of planes for given crtc - 1.
48+
*
49+
* If zpos of some planes cannot be changed (like fixed background or
50+
* cursor/topmost planes), driver should adjust min/max values and assign those
51+
* planes immutable zpos property with lower or higher values (for more
52+
* information, see drm_mode_create_zpos_immutable_property() function). In such
53+
* case driver should also assign proper initial zpos values for all planes in
54+
* its plane_reset() callback, so the planes will be always sorted properly.
55+
*
56+
* Returns:
57+
* Zero on success, negative errno on failure.
58+
*/
59+
int drm_plane_create_zpos_property(struct drm_plane *plane,
60+
unsigned int zpos,
61+
unsigned int min, unsigned int max)
62+
{
63+
struct drm_property *prop;
64+
65+
prop = drm_property_create_range(plane->dev, 0, "zpos", min, max);
66+
if (!prop)
67+
return -ENOMEM;
68+
69+
drm_object_attach_property(&plane->base, prop, zpos);
70+
71+
plane->zpos_property = prop;
72+
73+
if (plane->state) {
74+
plane->state->zpos = zpos;
75+
plane->state->normalized_zpos = zpos;
76+
}
77+
78+
return 0;
79+
}
80+
EXPORT_SYMBOL(drm_plane_create_zpos_property);
81+
82+
/**
83+
* drm_plane_create_zpos_immutable_property - create immuttable zpos property
84+
* @plane: drm plane
85+
* @zpos: value of zpos property
86+
*
87+
* This function initializes generic immutable zpos property and enables
88+
* support for it in drm core. Using this property driver lets userspace
89+
* to get the arrangement of the planes for blending operation and notifies
90+
* it that the hardware (or driver) doesn't support changing of the planes'
91+
* order.
92+
*
93+
* Returns:
94+
* Zero on success, negative errno on failure.
95+
*/
96+
int drm_plane_create_zpos_immutable_property(struct drm_plane *plane,
97+
unsigned int zpos)
98+
{
99+
struct drm_property *prop;
100+
101+
prop = drm_property_create_range(plane->dev, DRM_MODE_PROP_IMMUTABLE,
102+
"zpos", zpos, zpos);
103+
if (!prop)
104+
return -ENOMEM;
105+
106+
drm_object_attach_property(&plane->base, prop, zpos);
107+
108+
plane->zpos_property = prop;
109+
110+
if (plane->state) {
111+
plane->state->zpos = zpos;
112+
plane->state->normalized_zpos = zpos;
113+
}
114+
115+
return 0;
116+
}
117+
EXPORT_SYMBOL(drm_plane_create_zpos_immutable_property);
118+
119+
static int drm_atomic_state_zpos_cmp(const void *a, const void *b)
120+
{
121+
const struct drm_plane_state *sa = *(struct drm_plane_state **)a;
122+
const struct drm_plane_state *sb = *(struct drm_plane_state **)b;
123+
124+
if (sa->zpos != sb->zpos)
125+
return sa->zpos - sb->zpos;
126+
else
127+
return sa->plane->base.id - sb->plane->base.id;
128+
}
129+
130+
/**
131+
* drm_atomic_helper_crtc_normalize_zpos - calculate normalized zpos values
132+
* @crtc: crtc with planes, which have to be considered for normalization
133+
* @crtc_state: new atomic state to apply
134+
*
135+
* This function checks new states of all planes assigned to given crtc and
136+
* calculates normalized zpos value for them. Planes are compared first by their
137+
* zpos values, then by plane id (if zpos equals). Plane with lowest zpos value
138+
* is at the bottom. The plane_state->normalized_zpos is then filled with unique
139+
* values from 0 to number of active planes in crtc minus one.
140+
*
141+
* RETURNS
142+
* Zero for success or -errno
143+
*/
144+
static int drm_atomic_helper_crtc_normalize_zpos(struct drm_crtc *crtc,
145+
struct drm_crtc_state *crtc_state)
146+
{
147+
struct drm_atomic_state *state = crtc_state->state;
148+
struct drm_device *dev = crtc->dev;
149+
int total_planes = dev->mode_config.num_total_plane;
150+
struct drm_plane_state **states;
151+
struct drm_plane *plane;
152+
int i, n = 0;
153+
int ret = 0;
154+
155+
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
156+
crtc->base.id, crtc->name);
157+
158+
states = kmalloc_array(total_planes, sizeof(*states), GFP_TEMPORARY);
159+
if (!states)
160+
return -ENOMEM;
161+
162+
/*
163+
* Normalization process might create new states for planes which
164+
* normalized_zpos has to be recalculated.
165+
*/
166+
drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
167+
struct drm_plane_state *plane_state =
168+
drm_atomic_get_plane_state(state, plane);
169+
if (IS_ERR(plane_state)) {
170+
ret = PTR_ERR(plane_state);
171+
goto done;
172+
}
173+
states[n++] = plane_state;
174+
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] processing zpos value %d\n",
175+
plane->base.id, plane->name,
176+
plane_state->zpos);
177+
}
178+
179+
sort(states, n, sizeof(*states), drm_atomic_state_zpos_cmp, NULL);
180+
181+
for (i = 0; i < n; i++) {
182+
plane = states[i]->plane;
183+
184+
states[i]->normalized_zpos = i;
185+
DRM_DEBUG_ATOMIC("[PLANE:%d:%s] normalized zpos value %d\n",
186+
plane->base.id, plane->name, i);
187+
}
188+
crtc_state->zpos_changed = true;
189+
190+
done:
191+
kfree(states);
192+
return ret;
193+
}
194+
195+
/**
196+
* drm_atomic_helper_normalize_zpos - calculate normalized zpos values for all
197+
* crtcs
198+
* @dev: DRM device
199+
* @state: atomic state of DRM device
200+
*
201+
* This function calculates normalized zpos value for all modified planes in
202+
* the provided atomic state of DRM device. For more information, see
203+
* drm_atomic_helper_crtc_normalize_zpos() function.
204+
*
205+
* RETURNS
206+
* Zero for success or -errno
207+
*/
208+
int drm_atomic_helper_normalize_zpos(struct drm_device *dev,
209+
struct drm_atomic_state *state)
210+
{
211+
struct drm_crtc *crtc;
212+
struct drm_crtc_state *crtc_state;
213+
struct drm_plane *plane;
214+
struct drm_plane_state *plane_state;
215+
int i, ret = 0;
216+
217+
for_each_plane_in_state(state, plane, plane_state, i) {
218+
crtc = plane_state->crtc;
219+
if (!crtc)
220+
continue;
221+
if (plane->state->zpos != plane_state->zpos) {
222+
crtc_state =
223+
drm_atomic_get_existing_crtc_state(state, crtc);
224+
crtc_state->zpos_changed = true;
225+
}
226+
}
227+
228+
for_each_crtc_in_state(state, crtc, crtc_state, i) {
229+
if (crtc_state->plane_mask != crtc->state->plane_mask ||
230+
crtc_state->zpos_changed) {
231+
ret = drm_atomic_helper_crtc_normalize_zpos(crtc,
232+
crtc_state);
233+
if (ret)
234+
return ret;
235+
}
236+
}
237+
return 0;
238+
}

drivers/gpu/drm/drm_crtc_internal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
128128

129129
int drm_modeset_register_all(struct drm_device *dev);
130130
void drm_modeset_unregister_all(struct drm_device *dev);
131+
132+
/* drm_blend.c */
133+
int drm_atomic_helper_normalize_zpos(struct drm_device *dev,
134+
struct drm_atomic_state *state);

include/drm/drm_crtc.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ struct drm_plane_helper_funcs;
308308
* @mode_changed: crtc_state->mode or crtc_state->enable has been changed
309309
* @active_changed: crtc_state->active has been toggled.
310310
* @connectors_changed: connectors to this crtc have been updated
311+
* @zpos_changed: zpos values of planes on this crtc have been updated
311312
* @color_mgmt_changed: color management properties have changed (degamma or
312313
* gamma LUT or CSC matrix)
313314
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
@@ -344,6 +345,7 @@ struct drm_crtc_state {
344345
bool mode_changed : 1;
345346
bool active_changed : 1;
346347
bool connectors_changed : 1;
348+
bool zpos_changed : 1;
347349
bool color_mgmt_changed : 1;
348350

349351
/* attached planes bitmask:
@@ -1409,6 +1411,9 @@ struct drm_connector {
14091411
* @src_w: width of visible portion of plane (in 16.16)
14101412
* @src_h: height of visible portion of plane (in 16.16)
14111413
* @rotation: rotation of the plane
1414+
* @zpos: priority of the given plane on crtc (optional)
1415+
* @normalized_zpos: normalized value of zpos: unique, range from 0 to N-1
1416+
* where N is the number of active planes for given crtc
14121417
* @state: backpointer to global drm_atomic_state
14131418
*/
14141419
struct drm_plane_state {
@@ -1429,6 +1434,10 @@ struct drm_plane_state {
14291434
/* Plane rotation */
14301435
unsigned int rotation;
14311436

1437+
/* Plane zpos */
1438+
unsigned int zpos;
1439+
unsigned int normalized_zpos;
1440+
14321441
struct drm_atomic_state *state;
14331442
};
14341443

@@ -1688,6 +1697,7 @@ enum drm_plane_type {
16881697
* @properties: property tracking for this plane
16891698
* @type: type of plane (overlay, primary, cursor)
16901699
* @state: current atomic state for this plane
1700+
* @zpos_property: zpos property for this plane
16911701
* @helper_private: mid-layer private data
16921702
*/
16931703
struct drm_plane {
@@ -1732,6 +1742,8 @@ struct drm_plane {
17321742
const struct drm_plane_helper_funcs *helper_private;
17331743

17341744
struct drm_plane_state *state;
1745+
1746+
struct drm_property *zpos_property;
17351747
};
17361748

17371749
/**
@@ -2958,6 +2970,14 @@ extern void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
29582970
uint degamma_lut_size,
29592971
bool has_ctm,
29602972
uint gamma_lut_size);
2973+
2974+
int drm_plane_create_zpos_property(struct drm_plane *plane,
2975+
unsigned int zpos,
2976+
unsigned int min, unsigned int max);
2977+
2978+
int drm_plane_create_zpos_immutable_property(struct drm_plane *plane,
2979+
unsigned int zpos);
2980+
29612981
/* Helpers */
29622982
struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
29632983
uint32_t id, uint32_t type);

0 commit comments

Comments
 (0)