[PATCH 2/2] randr: add provider object (v3.1)
Aaron Plattner
aplattner at nvidia.com
Wed Jun 27 08:31:33 PDT 2012
Thanks for writing this up. Comments below.
On 06/25/2012 04:19 AM, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> A provider object represents a GPU or virtual device that provides
> rendering or output services to the X server.
>
> This is the first rev of a protocol to enumerate providers
> devices, set their roles, and provide generic properties based
> on output properties for them
>
> v1.1: fix typo add missing define
>
> v2: rename nProperties back to nAtoms, makes server simpler to c-n-p,
> add missing Get request/reply
>
> v3: bring back configure property, no point in diverging from the
> output property code without good reason.
> also fix typo pointed out on irc by rei4dan.
>
> v3.1: drop cut-n-paste, increase RRNumberRequests
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> randr.h | 29 +++++-
> randrproto.h | 194 ++++++++++++++++++++++++++++++++++++++
> randrproto.txt | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 502 insertions(+), 4 deletions(-)
>
> diff --git a/randr.h b/randr.h
> index 04604aa..39c08e5 100644
> --- a/randr.h
> +++ b/randr.h
> @@ -44,7 +44,7 @@ typedef unsigned long XRandrModeFlags;
>
> #define RRNumberErrors 3
> #define RRNumberEvents 2
> -#define RRNumberRequests 32
> +#define RRNumberRequests 41
>
> #define X_RRQueryVersion 0
> /* we skip 1 to make old clients fail pretty immediately */
> @@ -92,12 +92,24 @@ typedef unsigned long XRandrModeFlags;
> #define RRTransformScaleDown (1L << 2)
> #define RRTransformProjective (1L << 3)
>
> +/* v1.5 */
> +#define X_RRGetProviders 32
> +#define X_RRGetProviderInfo 33
> +#define X_RRSetProviderRoles 34
> +#define X_RRListProviderProperties 35
> +#define X_RRQueryProviderProperty 36
> +#define X_RRConfigureProviderProperty 37
> +#define X_RRChangeProviderProperty 38
> +#define X_RRDeleteProviderProperty 39
> +#define X_RRGetProviderProperty 40
> +
> /* Event selection bits */
> #define RRScreenChangeNotifyMask (1L << 0)
> /* V1.2 additions */
> #define RRCrtcChangeNotifyMask (1L << 1)
> #define RROutputChangeNotifyMask (1L << 2)
> #define RROutputPropertyNotifyMask (1L << 3)
> +#define RRProviderPropertyNotifyMask (1L << 4)
Do we need a RRProviderChangeNotifyMask? Can providers dynamically
appear and disappear? I assume they can due to things like USB hotplug.
> /* Event codes */
> #define RRScreenChangeNotify 0
> @@ -107,7 +119,7 @@ typedef unsigned long XRandrModeFlags;
> #define RRNotify_CrtcChange 0
> #define RRNotify_OutputChange 1
> #define RRNotify_OutputProperty 2
> -
> +#define RRNotify_ProviderProperty 3
> /* used in the rotation field; rotation and reflection in 0.1 proto. */
> #define RR_Rotate_0 1
> #define RR_Rotate_90 2
> @@ -162,4 +174,17 @@ typedef unsigned long XRandrModeFlags;
> #define RR_PROPERTY_BORDER "Border"
> #define RR_PROPERTY_BORDER_DIMENSIONS "BorderDimensions"
>
> +#define RR_Provider_Flag_Dynamic 1
> +#define RR_Provider_Flag_MultiMaster 2
> +
> +#define RR_Role_Undefined 0
> +#define RR_Role_Master 1
> +#define RR_Role_Slave_Offload 2
> +#define RR_Role_Slave_Output 4
> +
> +/* abilities for the provider */
> +#define RR_Ability_None 0
> +#define RR_Ability_Offload_Slaves 1
> +#define RR_Ability_Output_Slaves 2
> +
> #endif /* _RANDR_H_ */
> diff --git a/randrproto.h b/randrproto.h
> index 3b98a9f..2570d44 100644
> --- a/randrproto.h
> +++ b/randrproto.h
> @@ -48,6 +48,7 @@
> #define RROutput CARD32
> #define RRMode CARD32
> #define RRCrtc CARD32
> +#define RRProvider CARD32
> #define RRModeFlags CARD32
>
> #define Rotation CARD16
> @@ -645,6 +646,182 @@ typedef struct {
> } xRRGetOutputPrimaryReply;
> #define sz_xRRGetOutputPrimaryReply 32
>
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + Window window B32;
> +} xRRGetProvidersReq;
> +#define sz_xRRGetProvidersReq 8
> +
> +typedef struct {
> + BYTE type;
> + CARD8 pad;
> + CARD16 sequenceNumber B16;
> + CARD32 length B32;
> + CARD16 nProviders;
> + CARD16 max_master;
> + Time timestamp B32;
> + CARD32 flags B32;
> + CARD32 pad2 B32;
> + CARD32 pad3 B32;
> + CARD32 pad4 B32;
> +} xRRGetProvidersReply;
> +#define sz_xRRGetProvidersReply 32
> +
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + RRProvider provider B32;
> + Time configTimestamp B32;
> +} xRRGetProviderInfoReq;
> +#define sz_xRRGetProviderInfoReq 12
> +
> +typedef struct {
> + BYTE type;
> + CARD8 status;
> + CARD16 sequenceNumber B16;
> + CARD32 length B32;
> + CARD32 current_role B32;
> + CARD32 allowed_roles B32;
> + CARD32 abilities B32;
> + CARD16 nCrtcs B16;
> + CARD16 nOutputs B16;
> + CARD16 nameLength B16;
> + CARD16 pad1 B16;
> + CARD32 pad2 B32;
> +} xRRGetProviderInfoReply;
> +#define sz_xRRGetProviderInfoReply 32
> +
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + CARD16 numProviders B16;
> + CARD16 pad1 B16;
> + Time configTimestamp B32;
> +} xRRSetProviderRolesReq;
> +#define sz_xRRSetProviderRolesReq 12
> +
> +
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + RRProvider provider B32;
> +} xRRListProviderPropertiesReq;
> +#define sz_xRRListProviderPropertiesReq 8
> +
> +typedef struct {
> + BYTE type;
> + CARD8 pad0;
> + CARD16 sequenceNumber B16;
> + CARD32 length B32;
> + CARD16 nAtoms B16;
> + CARD16 pad1 B16;
> + CARD32 pad2 B32;
> + CARD32 pad3 B32;
> + CARD32 pad4 B32;
> + CARD32 pad5 B32;
> + CARD32 pad6 B32;
> +} xRRListProviderPropertiesReply;
> +#define sz_xRRListProviderPropertiesReply 32
> +
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + RRProvider provider B32;
> + Atom property B32;
> +} xRRQueryProviderPropertyReq;
> +#define sz_xRRQueryProviderPropertyReq 12
> +
> +typedef struct {
> + BYTE type;
> + BYTE pad0;
> + CARD16 sequenceNumber B16;
> + CARD32 length B32;
> + BOOL pending;
> + BOOL range;
> + BOOL immutable;
> + BYTE pad1;
> + CARD32 pad2 B32;
> + CARD32 pad3 B32;
> + CARD32 pad4 B32;
> + CARD32 pad5 B32;
> + CARD32 pad6 B32;
> +} xRRQueryProviderPropertyReply;
> +#define sz_xRRQueryProviderPropertyReply 32
> +
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + RRProvider provider B32;
> + Atom property B32;
> + BOOL pending;
> + BOOL range;
> + CARD16 pad B16;
> +} xRRConfigureProviderPropertyReq;
> +#define sz_xRRConfigureProviderPropertyReq 16
> +
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + RRProvider provider B32;
> + Atom property B32;
> + Atom type B32;
> + CARD8 format;
> + CARD8 mode;
> + CARD16 pad;
> + CARD32 nUnits B32;
> +} xRRChangeProviderPropertyReq;
> +#define sz_xRRChangeProviderPropertyReq 24
> +
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + RRProvider provider B32;
> + Atom property B32;
> +} xRRDeleteProviderPropertyReq;
> +#define sz_xRRDeleteProviderPropertyReq 12
> +
> +typedef struct {
> + CARD8 reqType;
> + CARD8 randrReqType;
> + CARD16 length B16;
> + RRProvider provider B32;
> + Atom property B32;
> + Atom type B32;
> + CARD32 longOffset B32;
> + CARD32 longLength B32;
> +#ifdef __cplusplus
> + BOOL _delete;
> +#else
> + BOOL delete;
> +#endif
> + BOOL pending;
> + CARD16 pad1 B16;
> +} xRRGetProviderPropertyReq;
> +#define sz_xRRGetProviderPropertyReq 28
> +
> +typedef struct {
> + BYTE type;
> + CARD8 format;
> + CARD16 sequenceNumber B16;
> + CARD32 length B32;
> + Atom propertyType B32;
> + CARD32 bytesAfter B32;
> + CARD32 nItems B32;
> + CARD32 pad1 B32;
> + CARD32 pad2 B32;
> + CARD32 pad3 B32;
> +} xRRGetProviderPropertyReply;
> +#define sz_xRRGetProviderPropertyReply 32
> +
> /*
> * event
> */
> @@ -715,6 +892,22 @@ typedef struct {
> #define sz_xRROutputPropertyNotifyEvent 32
>
> typedef struct {
> + CARD8 type; /* always evBase + RRNotify */
> + CARD8 subCode; /* RRNotify_ProviderProperty */
> + CARD16 sequenceNumber B16;
> + Window window B32; /* window requesting notification */
> + RRProvider provider B32; /* affected output */
s/output/provider/
> + Atom atom B32; /* property name */
> + Time timestamp B32; /* time crtc was changed */
Time provider property was changed?
xRROutputPropertyNotifyEvent has a similar copy & paste error.
> + CARD8 state; /* NewValue or Deleted */
> + CARD8 pad1;
> + CARD16 pad2 B16;
> + CARD32 pad3 B32;
> + CARD32 pad4 B32;
> +} xRRProviderPropertyNotifyEvent;
> +#define sz_xRRProviderPropertyNotifyEvent 32
> +
> +typedef struct {
> CARD8 reqType;
> CARD8 randrReqType;
> CARD16 length B16;
> @@ -784,6 +977,7 @@ typedef struct {
> #undef RROutput
> #undef RRMode
> #undef RRCrtc
> +#undef RRProvider
> #undef Drawable
> #undef Window
> #undef Font
> diff --git a/randrproto.txt b/randrproto.txt
> index 7c297e2..1300086 100644
> --- a/randrproto.txt
> +++ b/randrproto.txt
> @@ -1,6 +1,6 @@
> The X Resize, Rotate and Reflect Extension
> - Version 1.3.1
> - 2009-10-5
> + Version 1.5.0
> + 2012-05-31
>
> Jim Gettys
> Jim.Gettys at hp.com
> @@ -129,6 +129,28 @@ Version 1.4 adds an optional Border property.
> for compensating for the overscan behavior of certain
> televisions.
>
> +1.5 Introduction to version 1.5 of the extension
> +
> +Version 1.5 adds a new object called a provider object. A provider object
> +represents a GPU or virtual device providing services to the X server.
> +Providers have a set of abilities and a set of possible roles.
> +
> +Provider objects are used to control multi-GPU systems. Provider roles can
> +be dynamically configured to provide support for:
> +
> + 1) Output slaving: plug in a USB device, but have its output rendered
> + using the main GPU. On some dual-GPU laptops, the second GPU isn't
> + connected to the LVDS panel, so we need to use the first GPU as an output
> + slave for the second GPU.
> +
> + 2) DRI2 offload - For dual-GPU laptops, allow DRI2 applications to be run
> + on the second GPU and display on the first GPU.
DRI2 seems like an implementation detail. RandR clients shouldn't need
to know how the server implements offloading.
> + 3) GPU switching - Allow switching between two GPUs as the main screen
> + renderer.
> +
> + 4) multiple GPU rendering - This replaces Xinerama.
> +
> 1.99 Acknowledgements
>
> Our thanks to the contributors to the design found on the xpert mailing
> @@ -307,6 +329,27 @@ REFRESH { rates: LISTofCARD16 }
>
> ❧❧❧❧❧❧❧❧❧❧❧
>
> +5.4. Protocol Types added in version 1.4 of the extension
> +
> + ❧❧❧❧❧❧❧❧❧❧❧
> +5.5. Protocol Types added in version 1.5 of the extension
> +
> +PROVIDER { XID }
> +
> +ABILITYMASK { Offload, Output }
> + Abilities that this device can work with.
> + Offload: This device as a master can work with offload slaves.
> + Output: This device as a master can work with output slaves.
> +
> +ROLEMASK { Master, Offload, Output }
> + List of roles a device can have.
> + Master: A primary display and primary renderer.
> + Offload: A DRI2 rendering offload device.
s/DRI2//?
> + Output: An output device that can accept a shadow
> + pixmap to display as its scanout buffer.
"Shadow" pixmaps are not defined anywhere as far as I can tell. Maybe
just remove the word from this description? What restrictions are there
on shadow pixmaps vs. normal pixmaps?
> + ❧❧❧❧❧❧❧❧❧❧❧
> +
> 6. Extension Initialization
>
> The name of this extension is "RANDR".
> @@ -1243,6 +1286,223 @@ dynamic changes in the display environment.
>
> ❧❧❧❧❧❧❧❧❧❧❧
>
> +7.3. Extension Requests added in version 1.4 of the extension.
> +
> + ❧❧❧❧❧❧❧❧❧❧❧
> +
> +7.4 Extension Requests added in version 1.5 of the extension.
> +
> +┌───
> + RRGetProviders
> + window : WINDOW
> + ▶
> + timestamp: TIMESTAMP
> + providers: LISTofPROVIDER
> +└───
> + Errors: Window
> +
> + RRGetPRoviders returns the list of providers connected to the screen
> + associated with 'window'.
> +
> + 'timestamp' indicates when the configuration was last set.
> +
> + 'providers' contains the list of PROVIDERs associated with the
> + screen.
> +
> +┌───
> + RRGetProviderInfo
> + provider: PROVIDER
> + ▶
> + abilities: ABILITYMASK
> + roles: ROLEMASK
> + current_role: ROLEMASK
> + name: STRING
> + crtcs: LISTofCRTC
> + outputs: LISTofOUTPUT
> +└───
> + Errors: Window
This seems surprising. Shouldn't this throw Provider errors?
> + RRGetProviderInfo return information about the specified provider.
> + The abilities the provider can support for other providers, and the
> + roles it can perform. The current_role the provider is operating
> + in. It also provides the list of crtcs and outputs that this
> + provider is responsible for.
> +
> + 'name' is a UTF-8 encoded strings to be presented to the user to
s/strings/string/
> + indicate the device or driver supplied name.
> +
> +┌───
> + RRSetProviderRoles
> + providers: LISTofPROVIDER
> + role: LISTofROLEMASK
> + ▶
> +└───
> + Errors: Window
Errors: Provider?
> + RRSetProviderRoles allows the roles of the multiple specified providers
> + to be changed.
> +
> +┌───
> + RRListProviderProperties
> + provider:PROVIDERS
> + ▶
> + atoms: LISTof ATOM
> +└───
> + Errors: Provider
Doesn't this need to be defined in section 4 and in the protocol by
bumping RRNumberErrors to 4 and adding a BadRRProvider = 3 define?
-- Aaron
> + This request returns the atoms of properties currently defined on
> + the provider.
> +
> +┌───
> + RRQueryProviderProperty
> + provider: PROVIDER
> + property: ATOM
> + ▶
> + pending: BOOL
> + range: BOOL
> + immutable: BOOL
> + valid-values: LISTofINT32
> +└───
> + Errors: Name, Atom, Provider
> +
> + If the specified property does not exist for the specified provider,
> + then a Name error is returned.
> +
> + If 'pending' is TRUE, changes made to property values with
> + RRChangeProviderProperty will be saved in the pending property value
> + and be automatically copied to the current value on the next
> + RRSetCrtcConfig request involving the named output. If 'pending' is
> + FALSE, changes are copied immediately.
> +
> + If 'range' is TRUE, then the valid-values list will contain
> + precisely two values indicating the minimum and maximum allowed
> + values. If 'range' is FALSE, then the valid-values list will contain
> + the list of possible values; attempts to set other values will
> + result in a Value error.
> +
> + If 'immutable' is TRUE, then the property configuration cannot be
> + changed by clients. Immutable properties are interpreted by the X
> + server.
> +
> +┌───
> + RRConfigureProviderProperty
> + provider: PROVIDER
> + property: ATOM
> + pending: BOOL
> + range: BOOL
> + valid-values: LISTofINT32
> +└───
> + Errors: Access, Name, Atom, Provider
> +
> + If the specified property is 'immutable', an Access error is
> + returned.
> +
> + Otherwise, the configuration of the specified property is changed to
> + the values provided in this request.
> +
> + If the specified property does not exist for the specified provider,
> + it is created with an empty value and None type.
> +
> +┌───
> + RRChangeProviderProperty
> + provider: PROVIDER
> + property, type: ATOM
> + format: {8, 16, 32}
> + mode: { Replace, Prepend, Append }
> + data: LISTofINT8 or LISTofINT16 or LISTofINT32
> +└───
> + Errors: Alloc, Atom, Match, Value, Provider
> +
> + This request alters the value of the property for the specified
> + provider. If the property is marked as a 'pending' property, only the
> + pending value of the property is changed. Otherwise, changes are
> + reflected in both the pending and current values of the property.
> + The type is uninterpreted by the server. The format specifies
> + whether the data should be viewed as a list of 8-bit, 16-bit, or
> + 32-bit quantities so that the server can correctly byte-swap as
> + necessary.
> +
> + If the mode is Replace, the previous property value is discarded.
> + If the mode is Prepend or Append, then the type and format must
> + match the existing property value (or a Match error results). If
> + the property is undefined, it is treated as defined with the correct
> + type and format with zero-length data.
> +
> + For Prepend, the data is tacked on to the beginning of the existing
> + data, and for Append, it is tacked on to the end of the existing data.
> +
> + This request generates a ProviderPropertyNotify
> +
> + The lifetime of a property is not tied to the storing client.
> + Properties remain until explicitly deleted, until the provider is
> + destroyed, or until server reset (see section 10).
> +
> + The maximum size of a property is server-dependent and may vary
> + dynamically.
> +┌───
> + RRDeleteProviderProperty
> + provider: Provider
> + property: ATOM
> +└───
> + Errors: Atom, Provider
> +
> + This request deletes the property from the specified window if the
> + property exists and generates a ProviderPropertyNotify event unless
> + the property does not exist.
> +
> +┌───
> + RRGetProviderProperty
> + provider: PROVIDER
> + property: ATOM
> + type: ATOM or AnyPropertyType
> + long-offset, long-length: CARD32
> + delete: BOOL
> + pending: BOOL
> + ▶
> + type: ATOM or None
> + format: {0, 8, 16, 32}
> + bytes-after: CARD32
> + value: LISTofINT8 or LISTofINT16 or LISTofINT32
> +└───
> + Errors: Atom, Value, Provider
> +
> + If the specified property does not exist for the specified provider,
> + then the return type is None, the format and bytes-after are zero,
> + and the value is empty. The delete argument is ignored in this
> + case.
> +
> + If the specified property exists but its type does not match the
> + specified type, then the return type is the actual type of the
> + property, the format is the actual format of the property (never
> + zero), the bytes-after is the length of the property in bytes (even
> + if the format is 16 or 32), and the value is empty. The delete
> + argument is ignored in this case.
> +
> + If the specified property exists and either AnyPropertyType is
> + specified or the specified type matches the actual type of the
> + property, then the return type is the actual type of the property,
> + the format is the actual format of the property (never zero), and
> + the bytes-after and value are as follows, given:
> +
> + N = actual length of the stored property in bytes
> + (even if the format is 16 or 32)
> + I = 4 × offset
> + T = N - I
> + L = MINIMUM(T, 4 × long-length)
> + A = N - (I + L)
> +
> + If 'pending' is true, and if the property holds a pending value,
> + then the value returned will be the pending value of the property
> + rather than the current value. The returned value starts at byte
> + index I in the property (indexing from 0), and its length in bytes
> + is L. However, it is a Value error if long-offset is given such
> + that L is negative. The value of bytes-after is A, giving the
> + number of trailing unread bytes in the stored property. If delete
> + is True and the bytes-after is zero, the property is also deleted
> + from the provider, and a RRProviderPropertyNotify event is generated.
> +
> +
> + ❧❧❧❧❧❧❧❧❧❧❧
> 8. Extension Events
>
> Clients MAY select for ConfigureNotify on the root window to be
> @@ -1379,6 +1639,25 @@ factors, such as re-cabling a monitor, etc.
> just at the time when a display manager or log in script might
> be changing the monitor size or configuration.
>
> +8.2 Events added in version 1.5 of the RandR extension
> +┌───
> + RRProviderPropertyNotify:
> + window: WINDOW window requesting notification
> + provider: PROVIDER providre affected by change
> + atom: ATOM affected property
> + time: TIMESTAMP time property was changed
> + state: { NewValue, Deleted } new property state
> +└───
> +
> + This event is reported to clients selecting RRProviderPropertyChange
> + on the window and is generated with state NewValue when a property
> + of the window is changed using RRChangeProviderProperty even when
> + adding zero-length data and when replacing all or part of a property
> + with identical data. It is generated with state Deleted when a
> + property of the window is deleted using either
> + RRDeleteProviderProperty or RRGetProviderProperty. The timestamp
> + indicates the server time when the property was changed.
> +
> ❧❧❧❧❧❧❧❧❧❧❧
>
> 9. Properties
> --
> 1.7.10.2
More information about the xorg-devel
mailing list