2016-09-21 11:59:24 +03:00
/*
* Copyright ( c ) 2016 Intel Corporation
*
* Permission to use , copy , modify , distribute , and sell this software and its
* documentation for any purpose is hereby granted without fee , provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation , and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific ,
* written prior permission . The copyright holders make no representations
* about the suitability of this software for any purpose . It is provided " as
* is " without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS , IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL , INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE ,
* DATA OR PROFITS , WHETHER IN AN ACTION OF CONTRACT , NEGLIGENCE OR OTHER
* TORTIOUS ACTION , ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE .
*/
# ifndef __DRM_PLANE_H__
# define __DRM_PLANE_H__
# include <linux/list.h>
# include <linux/ctype.h>
# include <drm/drm_mode_object.h>
2018-02-19 23:28:23 +03:00
# include <drm/drm_color_mgmt.h>
2018-09-05 16:57:07 +03:00
# include <drm/drm_rect.h>
# include <drm/drm_modeset_lock.h>
2018-09-05 16:57:05 +03:00
# include <drm/drm_util.h>
2016-09-21 11:59:24 +03:00
struct drm_crtc ;
2016-11-05 18:08:09 +03:00
struct drm_printer ;
2017-03-23 00:50:41 +03:00
struct drm_modeset_acquire_ctx ;
2016-09-21 11:59:24 +03:00
2020-10-20 19:14:23 +03:00
enum drm_scaling_filter {
DRM_SCALING_FILTER_DEFAULT ,
DRM_SCALING_FILTER_NEAREST_NEIGHBOR ,
} ;
2016-09-21 11:59:24 +03:00
/**
* struct drm_plane_state - mutable plane state
2018-07-09 11:40:09 +03:00
*
* Please not that the destination coordinates @ crtc_x , @ crtc_y , @ crtc_h and
* @ crtc_w and the source coordinates @ src_x , @ src_y , @ src_h and @ src_w are the
* raw coordinates provided by userspace . Drivers should use
* drm_atomic_helper_check_plane_state ( ) and only use the derived rectangles in
* @ src and @ dst to program the hardware .
2016-09-21 11:59:24 +03:00
*/
struct drm_plane_state {
2018-07-09 11:40:09 +03:00
/** @plane: backpointer to the plane */
2016-09-21 11:59:24 +03:00
struct drm_plane * plane ;
2016-11-07 13:03:33 +03:00
/**
* @ crtc :
*
* Currently bound CRTC , NULL if disabled . Do not this write directly ,
* use drm_atomic_set_crtc_for_plane ( )
*/
struct drm_crtc * crtc ;
/**
* @ fb :
*
* Currently bound framebuffer . Do not write this directly , use
* drm_atomic_set_fb_for_plane ( )
*/
struct drm_framebuffer * fb ;
/**
* @ fence :
*
2018-04-05 18:44:46 +03:00
* Optional fence to wait for before scanning out @ fb . The core atomic
* code will set this when userspace is using explicit fencing . Do not
2019-06-03 17:28:48 +03:00
* write this field directly for a driver ' s implicit fence , use
2018-04-05 18:44:46 +03:00
* drm_atomic_set_fence_for_plane ( ) to ensure that an explicit fence is
* preserved .
*
* Drivers should store any implicit fence in this from their
2018-07-09 11:40:09 +03:00
* & drm_plane_helper_funcs . prepare_fb callback . See drm_gem_fb_prepare_fb ( )
2018-04-05 18:44:46 +03:00
* and drm_gem_fb_simple_display_pipe_prepare_fb ( ) for suitable helpers .
2016-11-07 13:03:33 +03:00
*/
2016-10-25 15:00:45 +03:00
struct dma_fence * fence ;
2016-09-21 11:59:24 +03:00
2016-11-07 13:03:33 +03:00
/**
* @ crtc_x :
*
* Left position of visible portion of plane on crtc , signed dest
* location allows it to be partially off screen .
*/
int32_t crtc_x ;
/**
* @ crtc_y :
*
* Upper position of visible portion of plane on crtc , signed dest
* location allows it to be partially off screen .
*/
int32_t crtc_y ;
2016-09-21 11:59:24 +03:00
2018-07-09 11:40:09 +03:00
/** @crtc_w: width of visible portion of plane on crtc */
/** @crtc_h: height of visible portion of plane on crtc */
2016-09-21 11:59:24 +03:00
uint32_t crtc_w , crtc_h ;
2018-07-09 11:40:09 +03:00
/**
* @ src_x : left position of visible portion of plane within plane ( in
* 16.16 fixed point ) .
*/
uint32_t src_x ;
/**
* @ src_y : upper position of visible portion of plane within plane ( in
* 16.16 fixed point ) .
*/
uint32_t src_y ;
/** @src_w: width of visible portion of plane (in 16.16) */
/** @src_h: height of visible portion of plane (in 16.16) */
2016-09-21 11:59:24 +03:00
uint32_t src_h , src_w ;
2018-07-09 11:40:09 +03:00
/**
* @ alpha :
* Opacity of the plane with 0 as completely transparent and 0xffff as
* completely opaque . See drm_plane_create_alpha_property ( ) for more
* details .
*/
2018-04-11 10:39:25 +03:00
u16 alpha ;
2018-08-31 18:09:25 +03:00
/**
* @ pixel_blend_mode :
* The alpha blending equation selection , describing how the pixels from
* the current plane are composited with the background . Value can be
* one of DRM_MODE_BLEND_ *
*/
2018-08-23 11:30:19 +03:00
uint16_t pixel_blend_mode ;
2018-04-11 10:39:25 +03:00
2018-07-09 11:40:09 +03:00
/**
* @ rotation :
* Rotation of the plane . See drm_plane_create_rotation_property ( ) for
* more details .
*/
2016-09-21 11:59:24 +03:00
unsigned int rotation ;
2018-07-09 11:40:09 +03:00
/**
* @ zpos :
* Priority of the given plane on crtc ( optional ) .
*
drm: two planes with the same zpos have undefined ordering
Currently the property docs don't specify whether it's okay for two planes to
have the same zpos value and what user-space should expect in this case.
The unspoken, legacy rule used in the past was to make user-space figure
out the zpos from object IDs. However some drivers break this rule,
that's why the ordering is documented as unspecified in case the zpos
property is missing. User-space should rely on the zpos property only.
There are some cases in which user-space might read identical zpos
values for different planes.
For instance, in case the property is mutable, user-space might set two
planes' zpos to the same value. This is necessary to support user-space
using the legacy DRM API where atomic commits are not possible:
user-space needs to update the planes' zpos one by one.
Because of this, user-space should handle multiple planes with the same
zpos.
While at it, remove the assumption that zpos is only for overlay planes.
Additionally, update the drm_plane_state.zpos docs to clarify that zpos
disambiguation via plane object IDs is a recommendation for drivers, not
something user-space can rely on. In other words, when user-space sets
the same zpos on two planes, drivers should rely on the plane object ID.
v2: clarify drm_plane_state.zpos docs (Daniel)
v3: zpos is for all planes (Marius, Daniel)
v4: completely reword the drm_plane_state.zpos docs to make it clear the
recommendation to use plane IDs is for drivers in case user-space uses
duplicate zpos values (Pekka)
v5: reword commit message (Pekka, James)
v6: remove mention of Arm GPUs having planes which can't overlap,
because this isn't uAPI yet (Daniel)
Signed-off-by: Simon Ser <contact@emersion.fr>
Reviewed-by: Pekka Paalanen <ppaalanen@gmail.com>
Cc: Marius Vlad <marius.vlad@collabora.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: James Qian Wang <james.qian.wang@arm.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/T5nHrvXH0GKOp6ONaFHk-j2cwEb4_4C_sBz9rNw8mmPACuut-DQqC74HMAFKZH3_Q15E8a3YnmKCxap-djKA71VVZv_T-tFxaB0he13O7yA=@emersion.fr
2019-10-09 18:10:49 +03:00
* User - space may set mutable zpos properties so that multiple active
* planes on the same CRTC have identical zpos values . This is a
* user - space bug , but drivers can solve the conflict by comparing the
* plane object IDs ; the plane with a higher ID is stacked on top of a
* plane with a lower ID .
2018-07-09 11:40:09 +03:00
*
* See drm_plane_create_zpos_property ( ) and
* drm_plane_create_zpos_immutable_property ( ) for more details .
*/
2016-09-21 11:59:24 +03:00
unsigned int zpos ;
2018-07-09 11:40:09 +03:00
/**
* @ normalized_zpos :
* Normalized value of zpos : unique , range from 0 to N - 1 where N is the
* number of active planes for given crtc . Note that the driver must set
* & drm_mode_config . normalize_zpos or call drm_atomic_normalize_zpos ( ) to
* update this before it can be trusted .
*/
2016-09-21 11:59:24 +03:00
unsigned int normalized_zpos ;
2018-02-19 23:28:23 +03:00
/**
* @ color_encoding :
*
* Color encoding for non RGB formats
*/
enum drm_color_encoding color_encoding ;
/**
* @ color_range :
*
* Color range for non RGB formats
*/
enum drm_color_range color_range ;
2018-05-24 05:04:08 +03:00
/**
* @ fb_damage_clips :
*
* Blob representing damage ( area in plane framebuffer that changed
* since last plane update ) as an array of & drm_mode_rect in framebuffer
* coodinates of the attached framebuffer . Note that unlike plane src ,
* damage clips are not in 16.16 fixed point .
*/
struct drm_property_blob * fb_damage_clips ;
2019-10-10 14:19:13 +03:00
/**
* @ src :
*
* source coordinates of the plane ( in 16.16 ) .
*
* When using drm_atomic_helper_check_plane_state ( ) ,
* the coordinates are clipped , but the driver may choose
* to use unclipped coordinates instead when the hardware
* performs the clipping automatically .
*/
/**
* @ dst :
*
* clipped destination coordinates of the plane .
*
* When using drm_atomic_helper_check_plane_state ( ) ,
* the coordinates are clipped , but the driver may choose
* to use unclipped coordinates instead when the hardware
* performs the clipping automatically .
*/
2016-09-21 11:59:24 +03:00
struct drm_rect src , dst ;
2016-11-07 13:03:33 +03:00
/**
* @ visible :
*
* Visibility of the plane . This can be false even if fb ! = NULL and
* crtc ! = NULL , due to clipping .
2016-09-21 11:59:24 +03:00
*/
bool visible ;
2020-10-20 19:14:23 +03:00
/**
* @ scaling_filter :
*
* Scaling filter to be applied
*/
enum drm_scaling_filter scaling_filter ;
2017-09-04 13:48:37 +03:00
/**
2017-09-04 13:48:38 +03:00
* @ commit : Tracks the pending commit to prevent use - after - free conditions ,
* and for async plane updates .
2017-09-04 13:48:37 +03:00
*
2017-09-04 13:48:38 +03:00
* May be NULL .
2017-09-04 13:48:37 +03:00
*/
struct drm_crtc_commit * commit ;
2018-07-09 11:40:09 +03:00
/** @state: backpointer to global drm_atomic_state */
2016-09-21 11:59:24 +03:00
struct drm_atomic_state * state ;
} ;
2016-11-05 18:08:08 +03:00
static inline struct drm_rect
drm_plane_state_src ( const struct drm_plane_state * state )
{
struct drm_rect src = {
. x1 = state - > src_x ,
. y1 = state - > src_y ,
. x2 = state - > src_x + state - > src_w ,
. y2 = state - > src_y + state - > src_h ,
} ;
return src ;
}
static inline struct drm_rect
drm_plane_state_dest ( const struct drm_plane_state * state )
{
struct drm_rect dest = {
. x1 = state - > crtc_x ,
. y1 = state - > crtc_y ,
. x2 = state - > crtc_x + state - > crtc_w ,
. y2 = state - > crtc_y + state - > crtc_h ,
} ;
return dest ;
}
2016-09-21 11:59:24 +03:00
/**
* struct drm_plane_funcs - driver plane control functions
*/
struct drm_plane_funcs {
/**
* @ update_plane :
*
* This is the legacy entry point to enable and configure the plane for
* the given CRTC and framebuffer . It is never called to disable the
* plane , i . e . the passed - in crtc and fb paramters are never NULL .
*
* The source rectangle in frame buffer memory coordinates is given by
* the src_x , src_y , src_w and src_h parameters ( as 16.16 fixed point
* values ) . Devices that don ' t support subpixel plane coordinates can
* ignore the fractional part .
*
* The destination rectangle in CRTC coordinates is given by the
* crtc_x , crtc_y , crtc_w and crtc_h parameters ( as integer values ) .
* Devices scale the source rectangle to the destination rectangle . If
* scaling is not supported , and the source rectangle size doesn ' t match
* the destination rectangle size , the driver must return a
* - < errorname > EINVAL < / errorname > error .
*
* Drivers implementing atomic modeset should use
* drm_atomic_helper_update_plane ( ) to implement this hook .
*
* RETURNS :
*
* 0 on success or a negative error code on failure .
*/
int ( * update_plane ) ( struct drm_plane * plane ,
struct drm_crtc * crtc , struct drm_framebuffer * fb ,
int crtc_x , int crtc_y ,
unsigned int crtc_w , unsigned int crtc_h ,
uint32_t src_x , uint32_t src_y ,
2017-03-23 00:50:41 +03:00
uint32_t src_w , uint32_t src_h ,
struct drm_modeset_acquire_ctx * ctx ) ;
2016-09-21 11:59:24 +03:00
/**
* @ disable_plane :
*
* This is the legacy entry point to disable the plane . The DRM core
* calls this method in response to a DRM_IOCTL_MODE_SETPLANE IOCTL call
* with the frame buffer ID set to 0. Disabled planes must not be
* processed by the CRTC .
*
* Drivers implementing atomic modeset should use
* drm_atomic_helper_disable_plane ( ) to implement this hook .
*
* RETURNS :
*
* 0 on success or a negative error code on failure .
*/
2017-03-23 00:50:43 +03:00
int ( * disable_plane ) ( struct drm_plane * plane ,
struct drm_modeset_acquire_ctx * ctx ) ;
2016-09-21 11:59:24 +03:00
/**
* @ destroy :
*
* Clean up plane resources . This is only called at driver unload time
* through drm_mode_config_cleanup ( ) since a plane cannot be hotplugged
* in DRM .
*/
void ( * destroy ) ( struct drm_plane * plane ) ;
/**
* @ reset :
*
* Reset plane hardware and software state to off . This function isn ' t
* called by the core directly , only through drm_mode_config_reset ( ) .
* It ' s not a helper hook only for historical reasons .
*
* Atomic drivers can use drm_atomic_helper_plane_reset ( ) to reset
* atomic state using this hook .
*/
void ( * reset ) ( struct drm_plane * plane ) ;
/**
* @ set_property :
*
* This is the legacy entry point to update a property attached to the
* plane .
*
* This callback is optional if the driver does not support any legacy
2017-07-25 15:02:04 +03:00
* driver - private properties . For atomic drivers it is not used because
* property handling is done entirely in the DRM core .
2016-09-21 11:59:24 +03:00
*
* RETURNS :
*
* 0 on success or a negative error code on failure .
*/
int ( * set_property ) ( struct drm_plane * plane ,
struct drm_property * property , uint64_t val ) ;
/**
* @ atomic_duplicate_state :
*
* Duplicate the current atomic state for this plane and return it .
2017-01-25 09:26:45 +03:00
* The core and helpers guarantee that any atomic state duplicated with
2016-09-21 11:59:24 +03:00
* this hook and still owned by the caller ( i . e . not transferred to the
2017-01-25 09:26:45 +03:00
* driver by calling & drm_mode_config_funcs . atomic_commit ) will be
* cleaned up by calling the @ atomic_destroy_state hook in this
* structure .
2016-09-21 11:59:24 +03:00
*
2018-05-25 04:25:55 +03:00
* This callback is mandatory for atomic drivers .
*
2016-12-29 23:48:26 +03:00
* Atomic drivers which don ' t subclass & struct drm_plane_state should use
2016-09-21 11:59:24 +03:00
* drm_atomic_helper_plane_duplicate_state ( ) . Drivers that subclass the
* state structure to extend it with driver - private state should use
* __drm_atomic_helper_plane_duplicate_state ( ) to make sure shared state is
* duplicated in a consistent fashion across drivers .
*
2017-01-25 09:26:45 +03:00
* It is an error to call this hook before & drm_plane . state has been
2016-09-21 11:59:24 +03:00
* initialized correctly .
*
* NOTE :
*
* If the duplicate state references refcounted resources this hook must
* acquire a reference for each of them . The driver must release these
* references again in @ atomic_destroy_state .
*
* RETURNS :
*
* Duplicated atomic state or NULL when the allocation failed .
*/
struct drm_plane_state * ( * atomic_duplicate_state ) ( struct drm_plane * plane ) ;
/**
* @ atomic_destroy_state :
*
* Destroy a state duplicated with @ atomic_duplicate_state and release
* or unreference all resources it references
2018-05-25 04:25:55 +03:00
*
* This callback is mandatory for atomic drivers .
2016-09-21 11:59:24 +03:00
*/
void ( * atomic_destroy_state ) ( struct drm_plane * plane ,
struct drm_plane_state * state ) ;
/**
* @ atomic_set_property :
*
* Decode a driver - private property value and store the decoded value
* into the passed - in state structure . Since the atomic core decodes all
* standardized properties ( even for extensions beyond the core set of
* properties which might not be implemented by all drivers ) this
* requires drivers to subclass the state structure .
*
* Such driver - private properties should really only be implemented for
* truly hardware / vendor specific state . Instead it is preferred to
* standardize atomic extension and decode the properties used to expose
* such an extension in the core .
*
* Do not call this function directly , use
* drm_atomic_plane_set_property ( ) instead .
*
* This callback is optional if the driver does not support any
* driver - private atomic properties .
*
* NOTE :
*
* This function is called in the state assembly phase of atomic
* modesets , which can be aborted for any reason ( including on
* userspace ' s request to just check whether a configuration would be
* possible ) . Drivers MUST NOT touch any persistent state ( hardware or
* software ) or data structures except the passed in @ state parameter .
*
* Also since userspace controls in which order properties are set this
* function must not do any input validation ( since the state update is
* incomplete and hence likely inconsistent ) . Instead any such input
* validation must be done in the various atomic_check callbacks .
*
* RETURNS :
*
* 0 if the property has been found , - EINVAL if the property isn ' t
* implemented by the driver ( which shouldn ' t ever happen , the core only
* asks for properties attached to this plane ) . No other validation is
* allowed by the driver . The core already checks that the property
* value is within the range ( integer , valid enum value , . . . ) the driver
* set when registering the property .
*/
int ( * atomic_set_property ) ( struct drm_plane * plane ,
struct drm_plane_state * state ,
struct drm_property * property ,
uint64_t val ) ;
/**
* @ atomic_get_property :
*
* Reads out the decoded driver - private property . This is used to
* implement the GETPLANE IOCTL .
*
* Do not call this function directly , use
* drm_atomic_plane_get_property ( ) instead .
*
* This callback is optional if the driver does not support any
* driver - private atomic properties .
*
* RETURNS :
*
* 0 on success , - EINVAL if the property isn ' t implemented by the
* driver ( which should never happen , the core only asks for
* properties attached to this plane ) .
*/
int ( * atomic_get_property ) ( struct drm_plane * plane ,
const struct drm_plane_state * state ,
struct drm_property * property ,
uint64_t * val ) ;
/**
* @ late_register :
*
* This optional hook can be used to register additional userspace
* interfaces attached to the plane like debugfs interfaces .
* It is called late in the driver load sequence from drm_dev_register ( ) .
* Everything added from this callback should be unregistered in
* the early_unregister callback .
*
* Returns :
*
* 0 on success , or a negative error code on failure .
*/
int ( * late_register ) ( struct drm_plane * plane ) ;
/**
* @ early_unregister :
*
* This optional hook should be used to unregister the additional
* userspace interfaces attached to the plane from
2017-01-25 09:26:55 +03:00
* @ late_register . It is called from drm_dev_unregister ( ) ,
2016-09-21 11:59:24 +03:00
* early in the driver unload sequence to disable userspace access
* before data structures are torndown .
*/
void ( * early_unregister ) ( struct drm_plane * plane ) ;
2016-11-05 18:08:09 +03:00
/**
* @ atomic_print_state :
*
2016-12-29 23:48:26 +03:00
* If driver subclasses & struct drm_plane_state , it should implement
2016-11-05 18:08:09 +03:00
* this optional hook for printing additional driver specific state .
*
* Do not call this directly , use drm_atomic_plane_print_state ( )
* instead .
*/
void ( * atomic_print_state ) ( struct drm_printer * p ,
const struct drm_plane_state * state ) ;
2017-07-24 06:46:38 +03:00
/**
* @ format_mod_supported :
*
* This optional hook is used for the DRM to determine if the given
* format / modifier combination is valid for the plane . This allows the
* DRM to generate the correct format bitmask ( which formats apply to
2018-03-17 01:04:33 +03:00
* which modifier ) , and to valdiate modifiers at atomic_check time .
*
* If not present , then any modifier in the plane ' s modifier
* list is allowed with any of the plane ' s formats .
2017-07-24 06:46:38 +03:00
*
* Returns :
*
* True if the given modifier is valid for that format on the plane .
* False otherwise .
*/
bool ( * format_mod_supported ) ( struct drm_plane * plane , uint32_t format ,
uint64_t modifier ) ;
2016-09-21 11:59:24 +03:00
} ;
2016-09-21 11:59:25 +03:00
/**
* enum drm_plane_type - uapi plane type enumeration
*
* For historical reasons not all planes are made the same . This enumeration is
* used to tell the different types of planes apart to implement the different
* uapi semantics for them . For userspace which is universal plane aware and
* which is using that atomic IOCTL there ' s no difference between these planes
* ( beyong what the driver and hardware can support of course ) .
*
* For compatibility with legacy userspace , only overlay planes are made
* available to userspace by default . Userspace clients may set the
* DRM_CLIENT_CAP_UNIVERSAL_PLANES client capability bit to indicate that they
* wish to receive a universal plane list containing all plane types . See also
* drm_for_each_legacy_plane ( ) .
2016-09-23 09:35:25 +03:00
*
* WARNING : The values of this enum is UABI since they ' re exposed in the " type "
* property .
2016-09-21 11:59:25 +03:00
*/
2016-09-21 11:59:24 +03:00
enum drm_plane_type {
2016-09-23 09:35:25 +03:00
/**
* @ DRM_PLANE_TYPE_OVERLAY :
*
* Overlay planes represent all non - primary , non - cursor planes . Some
* drivers refer to these types of planes as " sprites " internally .
*/
DRM_PLANE_TYPE_OVERLAY ,
2016-09-21 11:59:25 +03:00
/**
* @ DRM_PLANE_TYPE_PRIMARY :
*
* Primary planes represent a " main " plane for a CRTC . Primary planes
* are the planes operated upon by CRTC modesetting and flipping
2017-01-25 09:26:45 +03:00
* operations described in the & drm_crtc_funcs . page_flip and
* & drm_crtc_funcs . set_config hooks .
2016-09-21 11:59:25 +03:00
*/
2016-09-21 11:59:24 +03:00
DRM_PLANE_TYPE_PRIMARY ,
2016-09-21 11:59:25 +03:00
/**
* @ DRM_PLANE_TYPE_CURSOR :
*
* Cursor planes represent a " cursor " plane for a CRTC . Cursor planes
* are the planes operated upon by the DRM_IOCTL_MODE_CURSOR and
* DRM_IOCTL_MODE_CURSOR2 IOCTLs .
*/
2016-09-21 11:59:24 +03:00
DRM_PLANE_TYPE_CURSOR ,
} ;
/**
* struct drm_plane - central DRM plane control structure
2018-07-09 11:40:10 +03:00
*
* Planes represent the scanout hardware of a display block . They receive their
* input data from a & drm_framebuffer and feed it to a & drm_crtc . Planes control
* the color conversion , see ` Plane Composition Properties ` _ for more details ,
* and are also involved in the color conversion of input pixels , see ` Color
* Management Properties ` _ for details on that .
2016-09-21 11:59:24 +03:00
*/
struct drm_plane {
2018-07-09 11:40:10 +03:00
/** @dev: DRM device this plane belongs to */
2016-09-21 11:59:24 +03:00
struct drm_device * dev ;
2018-07-09 11:40:10 +03:00
/**
* @ head :
*
* List of all planes on @ dev , linked from & drm_mode_config . plane_list .
* Invariant over the lifetime of @ dev and therefore does not need
* locking .
*/
2016-09-21 11:59:24 +03:00
struct list_head head ;
2018-07-09 11:40:10 +03:00
/** @name: human readable name, can be overwritten by the driver */
2016-09-21 11:59:24 +03:00
char * name ;
/**
* @ mutex :
*
2017-01-25 09:26:45 +03:00
* Protects modeset plane state , together with the & drm_crtc . mutex of
* CRTC this plane is linked to ( when active , getting activated or
* getting disabled ) .
2017-03-28 18:53:48 +03:00
*
* For atomic drivers specifically this protects @ state .
2016-09-21 11:59:24 +03:00
*/
struct drm_modeset_lock mutex ;
2018-07-09 11:40:10 +03:00
/** @base: base mode object */
2016-09-21 11:59:24 +03:00
struct drm_mode_object base ;
2018-07-09 11:40:10 +03:00
/**
* @ possible_crtcs : pipes this plane can be bound to constructed from
* drm_crtc_mask ( )
*/
2016-09-21 11:59:24 +03:00
uint32_t possible_crtcs ;
2018-07-09 11:40:10 +03:00
/** @format_types: array of formats supported by this plane */
2016-09-21 11:59:24 +03:00
uint32_t * format_types ;
2018-07-09 11:40:10 +03:00
/** @format_count: Size of the array pointed at by @format_types. */
2016-09-21 11:59:24 +03:00
unsigned int format_count ;
2018-07-09 11:40:10 +03:00
/**
* @ format_default : driver hasn ' t supplied supported formats for the
* plane . Used by the drm_plane_init compatibility wrapper only .
*/
2016-09-21 11:59:24 +03:00
bool format_default ;
2018-07-09 11:40:10 +03:00
/** @modifiers: array of modifiers supported by this plane */
2017-07-24 06:46:38 +03:00
uint64_t * modifiers ;
2018-07-09 11:40:10 +03:00
/** @modifier_count: Size of the array pointed at by @modifier_count. */
2017-07-24 06:46:38 +03:00
unsigned int modifier_count ;
2017-11-08 23:30:07 +03:00
/**
2018-07-09 11:40:10 +03:00
* @ crtc :
*
* Currently bound CRTC , only meaningful for non - atomic drivers . For
* atomic drivers this is forced to be NULL , atomic drivers should
* instead check & drm_plane_state . crtc .
2017-11-08 23:30:07 +03:00
*/
2016-09-21 11:59:24 +03:00
struct drm_crtc * crtc ;
2017-11-08 23:30:07 +03:00
/**
2018-07-09 11:40:10 +03:00
* @ fb :
*
* Currently bound framebuffer , only meaningful for non - atomic drivers .
* For atomic drivers this is forced to be NULL , atomic drivers should
* instead check & drm_plane_state . fb .
2017-11-08 23:30:07 +03:00
*/
2016-09-21 11:59:24 +03:00
struct drm_framebuffer * fb ;
2018-07-09 11:40:10 +03:00
/**
* @ old_fb :
*
* Temporary tracking of the old fb while a modeset is ongoing . Only
* used by non - atomic drivers , forced to be NULL for atomic drivers .
*/
2016-09-21 11:59:24 +03:00
struct drm_framebuffer * old_fb ;
2018-07-09 11:40:10 +03:00
/** @funcs: plane control functions */
2016-09-21 11:59:24 +03:00
const struct drm_plane_funcs * funcs ;
2018-07-09 11:40:10 +03:00
/** @properties: property tracking for this plane */
2016-09-21 11:59:24 +03:00
struct drm_object_properties properties ;
2018-07-09 11:40:10 +03:00
/** @type: Type of plane, see &enum drm_plane_type for details. */
2016-09-21 11:59:24 +03:00
enum drm_plane_type type ;
/**
* @ index : Position inside the mode_config . list , can be used as an array
* index . It is invariant over the lifetime of the plane .
*/
unsigned index ;
2018-07-09 11:40:10 +03:00
/** @helper_private: mid-layer private data */
2016-09-21 11:59:24 +03:00
const struct drm_plane_helper_funcs * helper_private ;
2017-03-28 18:53:48 +03:00
/**
* @ state :
*
* Current atomic state for this plane .
*
* This is protected by @ mutex . Note that nonblocking atomic commits
* access the current plane state without taking locks . Either by going
* through the & struct drm_atomic_state pointers , see
2017-07-19 17:39:20 +03:00
* for_each_oldnew_plane_in_state ( ) , for_each_old_plane_in_state ( ) and
* for_each_new_plane_in_state ( ) . Or through careful ordering of atomic
* commit operations as implemented in the atomic helpers , see
* & struct drm_crtc_commit .
2017-03-28 18:53:48 +03:00
*/
2016-09-21 11:59:24 +03:00
struct drm_plane_state * state ;
2018-07-09 11:40:10 +03:00
/**
* @ alpha_property :
* Optional alpha property for this plane . See
* drm_plane_create_alpha_property ( ) .
*/
2018-04-11 10:39:25 +03:00
struct drm_property * alpha_property ;
2018-07-09 11:40:10 +03:00
/**
* @ zpos_property :
* Optional zpos property for this plane . See
* drm_plane_create_zpos_property ( ) .
*/
2016-09-21 11:59:24 +03:00
struct drm_property * zpos_property ;
2018-07-09 11:40:10 +03:00
/**
* @ rotation_property :
* Optional rotation property for this plane . See
* drm_plane_create_rotation_property ( ) .
*/
2016-09-26 19:30:48 +03:00
struct drm_property * rotation_property ;
2018-08-23 11:30:19 +03:00
/**
* @ blend_mode_property :
* Optional " pixel blend mode " enum property for this plane .
* Blend mode property represents the alpha blending equation selection ,
* describing how the pixels from the current plane are composited with
* the background .
*/
struct drm_property * blend_mode_property ;
2018-02-19 23:28:23 +03:00
/**
* @ color_encoding_property :
*
* Optional " COLOR_ENCODING " enum property for specifying
* color encoding for non RGB formats .
* See drm_plane_create_color_properties ( ) .
*/
struct drm_property * color_encoding_property ;
/**
* @ color_range_property :
*
* Optional " COLOR_RANGE " enum property for specifying
* color range for non RGB formats .
* See drm_plane_create_color_properties ( ) .
*/
struct drm_property * color_range_property ;
2020-10-20 19:14:23 +03:00
/**
* @ scaling_filter_property : property to apply a particular filter while
* scaling .
*/
struct drm_property * scaling_filter_property ;
2016-09-21 11:59:24 +03:00
} ;
# define obj_to_plane(x) container_of(x, struct drm_plane, base)
2017-07-24 06:46:38 +03:00
__printf ( 9 , 10 )
2016-09-21 11:59:24 +03:00
int drm_universal_plane_init ( struct drm_device * dev ,
struct drm_plane * plane ,
2016-12-02 16:45:35 +03:00
uint32_t possible_crtcs ,
2016-09-21 11:59:24 +03:00
const struct drm_plane_funcs * funcs ,
const uint32_t * formats ,
unsigned int format_count ,
2017-07-24 06:46:38 +03:00
const uint64_t * format_modifiers ,
2016-09-21 11:59:24 +03:00
enum drm_plane_type type ,
const char * name , . . . ) ;
2017-03-22 11:36:02 +03:00
int drm_plane_init ( struct drm_device * dev ,
struct drm_plane * plane ,
uint32_t possible_crtcs ,
const struct drm_plane_funcs * funcs ,
const uint32_t * formats , unsigned int format_count ,
bool is_primary ) ;
void drm_plane_cleanup ( struct drm_plane * plane ) ;
2016-09-21 11:59:24 +03:00
2020-12-10 18:38:30 +03:00
__printf ( 10 , 11 )
void * __drmm_universal_plane_alloc ( struct drm_device * dev ,
size_t size , size_t offset ,
uint32_t possible_crtcs ,
const struct drm_plane_funcs * funcs ,
const uint32_t * formats ,
unsigned int format_count ,
const uint64_t * format_modifiers ,
enum drm_plane_type plane_type ,
const char * name , . . . ) ;
/**
* drmm_universal_plane_alloc - Allocate and initialize an universal plane object
* @ dev : DRM device
* @ type : the type of the struct which contains struct & drm_plane
* @ member : the name of the & drm_plane within @ type
* @ possible_crtcs : bitmask of possible CRTCs
* @ funcs : callbacks for the new plane
* @ formats : array of supported formats ( DRM_FORMAT \ _ \ * )
* @ format_count : number of elements in @ formats
* @ format_modifiers : array of struct drm_format modifiers terminated by
* DRM_FORMAT_MOD_INVALID
* @ plane_type : type of plane ( overlay , primary , cursor )
* @ name : printf style format string for the plane name , or NULL for default name
*
* Allocates and initializes a plane object of type @ type . Cleanup is
* automatically handled through registering drm_plane_cleanup ( ) with
* drmm_add_action ( ) .
*
* The @ drm_plane_funcs . destroy hook must be NULL .
*
* Returns :
* Pointer to new plane , or ERR_PTR on failure .
*/
# define drmm_universal_plane_alloc(dev, type, member, possible_crtcs, funcs, formats, \
format_count , format_modifiers , plane_type , name , . . . ) \
( ( type * ) __drmm_universal_plane_alloc ( dev , sizeof ( type ) , \
offsetof ( type , member ) , \
possible_crtcs , funcs , formats , \
format_count , format_modifiers , \
plane_type , name , # # __VA_ARGS__ ) )
2016-09-21 11:59:24 +03:00
/**
* drm_plane_index - find the index of a registered plane
* @ plane : plane to find index for
*
* Given a registered plane , return the index of that plane within a DRM
* device ' s list of planes .
*/
2018-06-26 22:47:07 +03:00
static inline unsigned int drm_plane_index ( const struct drm_plane * plane )
2016-09-21 11:59:24 +03:00
{
return plane - > index ;
}
2018-06-26 22:47:07 +03:00
/**
* drm_plane_mask - find the mask of a registered plane
* @ plane : plane to find mask for
*/
static inline u32 drm_plane_mask ( const struct drm_plane * plane )
{
return 1 < < drm_plane_index ( plane ) ;
}
2017-03-22 11:36:02 +03:00
struct drm_plane * drm_plane_from_index ( struct drm_device * dev , int idx ) ;
void drm_plane_force_disable ( struct drm_plane * plane ) ;
2016-09-21 11:59:24 +03:00
int drm_mode_plane_set_obj_prop ( struct drm_plane * plane ,
struct drm_property * property ,
uint64_t value ) ;
/**
* drm_plane_find - find a & drm_plane
* @ dev : DRM device
2017-11-09 02:35:04 +03:00
* @ file_priv : drm file to check for lease against .
2016-09-21 11:59:24 +03:00
* @ id : plane id
*
* Returns the plane with @ id , NULL if it doesn ' t exist . Simple wrapper around
* drm_mode_object_find ( ) .
*/
static inline struct drm_plane * drm_plane_find ( struct drm_device * dev ,
2017-03-15 09:25:07 +03:00
struct drm_file * file_priv ,
2016-09-21 11:59:24 +03:00
uint32_t id )
{
struct drm_mode_object * mo ;
2017-03-15 09:25:07 +03:00
mo = drm_mode_object_find ( dev , file_priv , id , DRM_MODE_OBJECT_PLANE ) ;
2016-09-21 11:59:24 +03:00
return mo ? obj_to_plane ( mo ) : NULL ;
}
/**
* drm_for_each_plane_mask - iterate over planes specified by bitmask
* @ plane : the loop cursor
* @ dev : the DRM device
* @ plane_mask : bitmask of plane indices
*
* Iterate over all planes specified by bitmask .
*/
# define drm_for_each_plane_mask(plane, dev, plane_mask) \
list_for_each_entry ( ( plane ) , & ( dev ) - > mode_config . plane_list , head ) \
2018-06-26 22:47:07 +03:00
for_each_if ( ( plane_mask ) & drm_plane_mask ( plane ) )
2016-09-21 11:59:24 +03:00
2016-09-21 11:59:25 +03:00
/**
* drm_for_each_legacy_plane - iterate over all planes for legacy userspace
* @ plane : the loop cursor
* @ dev : the DRM device
*
* Iterate over all legacy planes of @ dev , excluding primary and cursor planes .
* This is useful for implementing userspace apis when userspace is not
2017-01-25 09:26:45 +03:00
* universal plane aware . See also & enum drm_plane_type .
2016-09-21 11:59:25 +03:00
*/
2016-09-21 11:59:24 +03:00
# define drm_for_each_legacy_plane(plane, dev) \
list_for_each_entry ( plane , & ( dev ) - > mode_config . plane_list , head ) \
for_each_if ( plane - > type = = DRM_PLANE_TYPE_OVERLAY )
2016-09-21 11:59:25 +03:00
/**
* drm_for_each_plane - iterate over all planes
* @ plane : the loop cursor
* @ dev : the DRM device
*
* Iterate over all planes of @ dev , include primary and cursor planes .
*/
2016-09-21 11:59:24 +03:00
# define drm_for_each_plane(plane, dev) \
list_for_each_entry ( plane , & ( dev ) - > mode_config . plane_list , head )
2018-10-29 21:34:52 +03:00
bool drm_any_plane_has_format ( struct drm_device * dev ,
u32 format , u64 modifier ) ;
2018-05-24 05:04:08 +03:00
/**
* drm_plane_get_damage_clips_count - Returns damage clips count .
* @ state : Plane state .
*
* Simple helper to get the number of & drm_mode_rect clips set by user - space
* during plane update .
*
* Return : Number of clips in plane fb_damage_clips blob property .
*/
static inline unsigned int
drm_plane_get_damage_clips_count ( const struct drm_plane_state * state )
{
return ( state & & state - > fb_damage_clips ) ?
state - > fb_damage_clips - > length / sizeof ( struct drm_mode_rect ) : 0 ;
}
/**
* drm_plane_get_damage_clips - Returns damage clips .
* @ state : Plane state .
*
2018-05-31 00:42:52 +03:00
* Note that this function returns uapi type & drm_mode_rect . Drivers might
* instead be interested in internal & drm_rect which can be obtained by calling
* drm_helper_get_plane_damage_clips ( ) .
2018-05-24 05:04:08 +03:00
*
* Return : Damage clips in plane fb_damage_clips blob property .
*/
static inline struct drm_mode_rect *
drm_plane_get_damage_clips ( const struct drm_plane_state * state )
{
return ( struct drm_mode_rect * ) ( ( state & & state - > fb_damage_clips ) ?
state - > fb_damage_clips - > data : NULL ) ;
}
2016-09-21 11:59:24 +03:00
2020-10-20 19:14:23 +03:00
int drm_plane_create_scaling_filter_property ( struct drm_plane * plane ,
unsigned int supported_filters ) ;
2016-09-21 11:59:24 +03:00
# endif