forked from 12to11/12to11
Allow the user to manually specify format modifiers
* 12to11.conf (DRMFOURCCH): New variable. * 12to11.man: Document new resource. * Imakefile (GENHEADERS): Add drm_modifiers.h.:(drm_modifiers.h): New target. (cleandir): Clean up. * compositor.h: Update prototypes. * fns.c (TransformBox): Move to transform.c. * frame_clock.c (PostEndFrame): Use 200 us, since 100 us is not always enough. * picture_renderer.c (struct _DrmModifierName): New structure. (known_modifiers): New array. (AddAdditionalModifier, ParseAdditionalModifiers) (InitAdditionalModifiers): New functions. (InitRenderFuncs): Call them. (ApplyInverseTransform): Accept buffer width and height instead of PictureBuffer. Move to transform.c. (MaybeApplyTransform): Adjust calls. (FindSupportedModifiers, InitDrmFormats): Stop adding the linear format by default, and let the user specify it instead. * subcompositor.c (InvertTransform): Move to transform.c. * svnignore.txt: Add new generated header. * transform.c (ApplyInverseTransform, TransformBox) (InvertTransform): Move some functions here as they will be used in the EGL backend.
This commit is contained in:
parent
8e4391f941
commit
0b5d44537b
10 changed files with 381 additions and 177 deletions
|
@ -10,6 +10,7 @@
|
||||||
XCBLIB = -lX11-xcb
|
XCBLIB = -lX11-xcb
|
||||||
PIXMAN = -lpixman-1
|
PIXMAN = -lpixman-1
|
||||||
DRM = -ldrm
|
DRM = -ldrm
|
||||||
|
DRMFOURCCH = $(INCROOT)/drm/drm_fourcc.h
|
||||||
DRMINCLUDES = -I$(INCROOT)/drm
|
DRMINCLUDES = -I$(INCROOT)/drm
|
||||||
PIXMANINCLUDES = -I$(INCROOT)/pixman-1
|
PIXMANINCLUDES = -I$(INCROOT)/pixman-1
|
||||||
XPRESENTLIB = -lXpresent
|
XPRESENTLIB = -lXpresent
|
||||||
|
|
17
12to11.man
17
12to11.man
|
@ -160,6 +160,23 @@ the first process exits.
|
||||||
The number of seconds the protocol translator waits between
|
The number of seconds the protocol translator waits between
|
||||||
invocations of the command specified in \fBidleIntervalCommand\fP.
|
invocations of the command specified in \fBidleIntervalCommand\fP.
|
||||||
Defaults to 60.
|
Defaults to 60.
|
||||||
|
.TP
|
||||||
|
.B additionalModifiersOfScreen\fP\fINUMBER\fP (class \fBAdditionalModifiers\fP)
|
||||||
|
A comma-separated list of additional DRM modifiers that can be applied
|
||||||
|
to each format. These modifiers must be specified by their names
|
||||||
|
inside the `drm_fourcc.h' system header, and should be used if your X
|
||||||
|
graphics driver fails to report which modifiers are available.
|
||||||
|
\fINUMBER\fP should be replaced with the number of the screen on which
|
||||||
|
the protocol translator is running.
|
||||||
|
|
||||||
|
On 9th Generation Intel systems, for example, you may want to set this
|
||||||
|
to:
|
||||||
|
.IP
|
||||||
|
.in +4
|
||||||
|
.EX
|
||||||
|
\fB12to11.AdditionalModifiers: I915_FORMAT_MOD_X_TILED,DRM_FORMAT_MOD_LINEAR\fP
|
||||||
|
.EE
|
||||||
|
.in
|
||||||
.IP
|
.IP
|
||||||
.SH ENVIRONMENT
|
.SH ENVIRONMENT
|
||||||
Several environment variables exist that modify the behavior of the
|
Several environment variables exist that modify the behavior of the
|
||||||
|
|
|
@ -39,7 +39,7 @@ OBJS = 12to11.o run.o alloc.o fns.o output.o compositor.o \
|
||||||
time.o relative_pointer.o keyboard_shortcuts_inhibit.o \
|
time.o relative_pointer.o keyboard_shortcuts_inhibit.o \
|
||||||
idle_inhibit.o process.o fence_ring.o
|
idle_inhibit.o process.o fence_ring.o
|
||||||
|
|
||||||
GENHEADERS = transfer_atoms.h
|
GENHEADERS = transfer_atoms.h drm_modifiers.h
|
||||||
|
|
||||||
#ifdef HaveEglSupport
|
#ifdef HaveEglSupport
|
||||||
|
|
||||||
|
@ -98,6 +98,9 @@ transfer_atoms.h: short_types.txt mime0.awk mime1.awk mime2.awk mime3.awk \
|
||||||
awk -f mime3.awk short_types.txt >> $@
|
awk -f mime3.awk short_types.txt >> $@
|
||||||
awk -f mime4.awk short_types.txt >> $@
|
awk -f mime4.awk short_types.txt >> $@
|
||||||
|
|
||||||
|
drm_modifiers.h: modifiers.awk $(DRMFOURCCH)
|
||||||
|
awk -f modifiers.awk $(DRMFOURCCH) > $@
|
||||||
|
|
||||||
/* Now, define generated files. */
|
/* Now, define generated files. */
|
||||||
|
|
||||||
#define ScannerTarget(name) @@\
|
#define ScannerTarget(name) @@\
|
||||||
|
@ -134,8 +137,7 @@ $(OBJS): $(GENHEADERS)
|
||||||
depend:: $(GENHEADERS) $(SRCS)
|
depend:: $(GENHEADERS) $(SRCS)
|
||||||
|
|
||||||
cleandir::
|
cleandir::
|
||||||
$(RM) $(GENHEADERS) $(GENSRCS) transfer_atoms.h short_types.txt \
|
$(RM) $(GENHEADERS) $(GENSRCS) short_types.txt 12to11.tar.gz
|
||||||
12to11.tar.gz
|
|
||||||
|
|
||||||
/* Undefine _BSD_SOURCE and _SVID_SOURCE, since both are deprecated
|
/* Undefine _BSD_SOURCE and _SVID_SOURCE, since both are deprecated
|
||||||
and are also superseeded by _GNU_SOURCE. */
|
and are also superseeded by _GNU_SOURCE. */
|
||||||
|
|
|
@ -1695,6 +1695,11 @@ extern void MatrixExport (Matrix *, XTransform *);
|
||||||
extern void MatrixRotate (Matrix *, float, float, float);
|
extern void MatrixRotate (Matrix *, float, float, float);
|
||||||
extern void MatrixMirrorHorizontal (Matrix *, float);
|
extern void MatrixMirrorHorizontal (Matrix *, float);
|
||||||
|
|
||||||
|
extern void ApplyInverseTransform (int, int, Matrix *,
|
||||||
|
BufferTransform, Bool);
|
||||||
|
extern void TransformBox (pixman_box32_t *, BufferTransform, int, int);
|
||||||
|
extern BufferTransform InvertTransform (BufferTransform);
|
||||||
|
|
||||||
/* Defined in wp_viewporter.c. */
|
/* Defined in wp_viewporter.c. */
|
||||||
|
|
||||||
extern void XLInitWpViewporter (void);
|
extern void XLInitWpViewporter (void);
|
||||||
|
|
65
fns.c
65
fns.c
|
@ -403,71 +403,6 @@ XLExtendRegion (pixman_region32_t *dst, pixman_region32_t *src,
|
||||||
XLFree (dst_rects);
|
XLFree (dst_rects);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
TransformBox (pixman_box32_t *box, BufferTransform transform,
|
|
||||||
int width, int height)
|
|
||||||
{
|
|
||||||
pixman_box32_t work;
|
|
||||||
|
|
||||||
switch (transform)
|
|
||||||
{
|
|
||||||
case Normal:
|
|
||||||
work = *box;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CounterClockwise90:
|
|
||||||
work.x1 = height - box->y2;
|
|
||||||
work.y1 = box->x1;
|
|
||||||
work.x2 = height - box->y1;
|
|
||||||
work.y2 = box->x2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CounterClockwise180:
|
|
||||||
work.x1 = width - box->x2;
|
|
||||||
work.y1 = height - box->y2;
|
|
||||||
work.x2 = width - box->x1;
|
|
||||||
work.y2 = height - box->y1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CounterClockwise270:
|
|
||||||
work.x1 = box->y1;
|
|
||||||
work.y1 = width - box->x2;
|
|
||||||
work.x2 = box->y2;
|
|
||||||
work.y2 = width - box->x1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Flipped:
|
|
||||||
work.x1 = width - box->x2;
|
|
||||||
work.y1 = box->y1;
|
|
||||||
work.x2 = width - box->x1;
|
|
||||||
work.y2 = box->y2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Flipped90:
|
|
||||||
work.x1 = box->y1;
|
|
||||||
work.y1 = box->x1;
|
|
||||||
work.x2 = box->y2;
|
|
||||||
work.y2 = box->x2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Flipped180:
|
|
||||||
work.x1 = box->x1;
|
|
||||||
work.y1 = height - box->y2;
|
|
||||||
work.x2 = box->x2;
|
|
||||||
work.y2 = height - box->y1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Flipped270:
|
|
||||||
work.x1 = height - box->y2;
|
|
||||||
work.y1 = width - box->x2;
|
|
||||||
work.x2 = height - box->y1;
|
|
||||||
work.y2 = width - box->x1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*box = work;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
XLTransformRegion (pixman_region32_t *dst, pixman_region32_t *src,
|
XLTransformRegion (pixman_region32_t *dst, pixman_region32_t *src,
|
||||||
BufferTransform transform, int width, int height)
|
BufferTransform transform, int width, int height)
|
||||||
|
|
|
@ -353,9 +353,9 @@ PostEndFrame (FrameClock *clock)
|
||||||
/* The vertical blanking period itself can't actually be computed
|
/* The vertical blanking period itself can't actually be computed
|
||||||
based on available data. However, frame_delay must be inside the
|
based on available data. However, frame_delay must be inside the
|
||||||
vertical blanking period for it to make any sense, so use it to
|
vertical blanking period for it to make any sense, so use it to
|
||||||
compute the deadline instead. Add about 100 us to the frame
|
compute the deadline instead. Add about 200 us to the frame
|
||||||
delay to compensate for the roundtrip time. */
|
delay to compensate for the roundtrip time. */
|
||||||
target -= clock->frame_delay - 100;
|
target -= clock->frame_delay - 200;
|
||||||
|
|
||||||
/* Add the remainder of now if it was probably truncated by the
|
/* Add the remainder of now if it was probably truncated by the
|
||||||
compositor. */
|
compositor. */
|
||||||
|
|
|
@ -26,6 +26,7 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
|
||||||
#include "compositor.h"
|
#include "compositor.h"
|
||||||
|
#include "drm_modifiers.h"
|
||||||
|
|
||||||
#include <xcb/dri3.h>
|
#include <xcb/dri3.h>
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
typedef struct _DrmFormatInfo DrmFormatInfo;
|
typedef struct _DrmFormatInfo DrmFormatInfo;
|
||||||
typedef struct _DmaBufRecord DmaBufRecord;
|
typedef struct _DmaBufRecord DmaBufRecord;
|
||||||
|
typedef struct _DrmModifierName DrmModifierName;
|
||||||
|
|
||||||
typedef struct _PictureBuffer PictureBuffer;
|
typedef struct _PictureBuffer PictureBuffer;
|
||||||
typedef struct _PictureTarget PictureTarget;
|
typedef struct _PictureTarget PictureTarget;
|
||||||
|
@ -46,6 +48,15 @@ typedef struct _BufferActivityRecord BufferActivityRecord;
|
||||||
typedef struct _IdleCallback IdleCallback;
|
typedef struct _IdleCallback IdleCallback;
|
||||||
typedef struct _PresentCompletionCallback PresentCompletionCallback;
|
typedef struct _PresentCompletionCallback PresentCompletionCallback;
|
||||||
|
|
||||||
|
struct _DrmModifierName
|
||||||
|
{
|
||||||
|
/* The modifier name. */
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
/* The modifier code. */
|
||||||
|
uint64_t modifier;
|
||||||
|
};
|
||||||
|
|
||||||
/* Structure describing an expected PresentIdleNotify from the X
|
/* Structure describing an expected PresentIdleNotify from the X
|
||||||
server. */
|
server. */
|
||||||
|
|
||||||
|
@ -277,6 +288,12 @@ struct _DmaBufRecord
|
||||||
short width, height;
|
short width, height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Number of format modifiers specified by the user. */
|
||||||
|
static int num_specified_modifiers;
|
||||||
|
|
||||||
|
/* Array of user-specified format modifiers. */
|
||||||
|
static uint64_t *user_specified_modifiers;
|
||||||
|
|
||||||
/* Hash table mapping between presentation windows and targets. */
|
/* Hash table mapping between presentation windows and targets. */
|
||||||
static XLAssocTable *xid_table;
|
static XLAssocTable *xid_table;
|
||||||
|
|
||||||
|
@ -360,6 +377,13 @@ static DrmFormatInfo all_formats[] =
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Array of all known DRM modifier names. */
|
||||||
|
static DrmModifierName known_modifiers[] =
|
||||||
|
{
|
||||||
|
/* Generated from drm_fourcc.h. */
|
||||||
|
DrmModifiersList
|
||||||
|
};
|
||||||
|
|
||||||
/* DRM formats reported to the caller. */
|
/* DRM formats reported to the caller. */
|
||||||
static DrmFormat *drm_formats;
|
static DrmFormat *drm_formats;
|
||||||
|
|
||||||
|
@ -741,6 +765,112 @@ InitSynchronizedPresentation (void)
|
||||||
use_direct_presentation = True;
|
use_direct_presentation = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
AddAdditionalModifier (const char *name)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < ArrayElements (known_modifiers) - 1; ++i)
|
||||||
|
{
|
||||||
|
if (!strcmp (known_modifiers[i].name, name))
|
||||||
|
{
|
||||||
|
/* The modifier was found. See if it already exists. */
|
||||||
|
for (j = 0; j < num_specified_modifiers; ++j)
|
||||||
|
{
|
||||||
|
if (user_specified_modifiers[j]
|
||||||
|
== known_modifiers[i].modifier)
|
||||||
|
/* The modifier was already specified. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, increment num_specified_modifiers. */
|
||||||
|
num_specified_modifiers++;
|
||||||
|
|
||||||
|
/* Make user_specified_modifiers big enough. */
|
||||||
|
user_specified_modifiers
|
||||||
|
= XLRealloc (user_specified_modifiers,
|
||||||
|
num_specified_modifiers
|
||||||
|
* sizeof *user_specified_modifiers);
|
||||||
|
|
||||||
|
/* And add the modifier. */
|
||||||
|
user_specified_modifiers[num_specified_modifiers - 1]
|
||||||
|
= known_modifiers[i].modifier;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (stderr, "Unknown buffer format modifier: %s\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ParseAdditionalModifiers (const char *string)
|
||||||
|
{
|
||||||
|
const char *end, *sep;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
|
end = string + strlen (string);
|
||||||
|
|
||||||
|
while (string < end)
|
||||||
|
{
|
||||||
|
/* Find the next comma. */
|
||||||
|
sep = strchr (string, ',');
|
||||||
|
|
||||||
|
if (!sep)
|
||||||
|
sep = end;
|
||||||
|
|
||||||
|
/* Copy the text between string and sep into buffer. */
|
||||||
|
buffer = alloca (sep - string + 1);
|
||||||
|
memcpy (buffer, string, sep - string);
|
||||||
|
buffer[sep - string] = '\0';
|
||||||
|
|
||||||
|
/* Add this modifier. */
|
||||||
|
AddAdditionalModifier (buffer);
|
||||||
|
|
||||||
|
string = sep + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
InitAdditionalModifiers (void)
|
||||||
|
{
|
||||||
|
XrmDatabase rdb;
|
||||||
|
XrmName namelist[3];
|
||||||
|
XrmClass classlist[3];
|
||||||
|
XrmValue value;
|
||||||
|
XrmRepresentation type;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
rdb = XrmGetDatabase (compositor.display);
|
||||||
|
|
||||||
|
if (!rdb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!asprintf (&name, "additionalModifiersOfScreen%d",
|
||||||
|
DefaultScreen (compositor.display)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
namelist[1] = XrmStringToQuark (name);
|
||||||
|
free (name);
|
||||||
|
|
||||||
|
namelist[0] = app_quark;
|
||||||
|
namelist[2] = NULLQUARK;
|
||||||
|
|
||||||
|
classlist[1] = XrmStringToQuark ("AdditionalModifiers");
|
||||||
|
classlist[0] = resource_quark;
|
||||||
|
classlist[2] = NULLQUARK;
|
||||||
|
|
||||||
|
/* Enable the use of direct presentation if
|
||||||
|
*.UseDirectPresentation.*.useDirectPresentation is true. This is
|
||||||
|
still incomplete, as the features necessary for it to play nice
|
||||||
|
with frame synchronization have not yet been implemented in the X
|
||||||
|
server. */
|
||||||
|
|
||||||
|
if (XrmQGetResource (rdb, namelist, classlist,
|
||||||
|
&type, &value)
|
||||||
|
&& type == QString)
|
||||||
|
ParseAdditionalModifiers ((const char *) value.addr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Forward declaration. */
|
/* Forward declaration. */
|
||||||
static void AddRenderFlag (int);
|
static void AddRenderFlag (int);
|
||||||
|
|
||||||
|
@ -769,6 +899,9 @@ InitRenderFuncs (void)
|
||||||
presentation. */
|
presentation. */
|
||||||
InitSynchronizedPresentation ();
|
InitSynchronizedPresentation ();
|
||||||
|
|
||||||
|
/* Find out what additional modifiers the user wants. */
|
||||||
|
InitAdditionalModifiers ();
|
||||||
|
|
||||||
if (use_direct_presentation)
|
if (use_direct_presentation)
|
||||||
AddRenderFlag (SupportsDirectPresent);
|
AddRenderFlag (SupportsDirectPresent);
|
||||||
|
|
||||||
|
@ -1166,82 +1299,6 @@ CompareStretch (DrawParams *params, DrawParams *other)
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ApplyInverseTransform (PictureBuffer *buffer, Matrix *matrix,
|
|
||||||
BufferTransform transform)
|
|
||||||
{
|
|
||||||
float width, height;
|
|
||||||
|
|
||||||
/* Note that the transform is applied in reverse, meaning that a
|
|
||||||
counterclockwise rotation is done clockwise, etc, as TRANSFORM
|
|
||||||
transforms destination coordinates to source ones. */
|
|
||||||
|
|
||||||
width = buffer->width;
|
|
||||||
height = buffer->height;
|
|
||||||
|
|
||||||
switch (transform)
|
|
||||||
{
|
|
||||||
case Normal:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CounterClockwise90:
|
|
||||||
/* Apply clockwise 270 degree rotation around the origin. */
|
|
||||||
MatrixRotate (matrix, M_PI * 1.5, 0, 0);
|
|
||||||
|
|
||||||
/* Translate y by the width. */
|
|
||||||
MatrixTranslate (matrix, 0, -width);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CounterClockwise180:
|
|
||||||
/* Apply clockwise 180 degree rotation around the center. */
|
|
||||||
MatrixRotate (matrix, M_PI, width / 2.0f, height / 2.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CounterClockwise270:
|
|
||||||
/* Apply clockwise 90 degree rotation around the origin. */
|
|
||||||
MatrixRotate (matrix, M_PI * 0.5, 0, 0);
|
|
||||||
|
|
||||||
/* Translate by the height. */
|
|
||||||
MatrixTranslate (matrix, -height, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Flipped:
|
|
||||||
/* Apply horizontal flip. */
|
|
||||||
MatrixMirrorHorizontal (matrix, width);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Flipped90:
|
|
||||||
/* Apply horizontal flip. */
|
|
||||||
MatrixMirrorHorizontal (matrix, width);
|
|
||||||
|
|
||||||
/* Apply clockwise 90 degree rotation around the origin. */
|
|
||||||
MatrixRotate (matrix, M_PI * 0.5, 0, 0);
|
|
||||||
|
|
||||||
/* Translate by the height. */
|
|
||||||
MatrixTranslate (matrix, -height, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Flipped180:
|
|
||||||
/* Apply horizontal flip. */
|
|
||||||
MatrixMirrorHorizontal (matrix, width);
|
|
||||||
|
|
||||||
/* Apply clockwise 180 degree rotation around the center. */
|
|
||||||
MatrixRotate (matrix, M_PI, width / 2.0f, height / 2.0f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Flipped270:
|
|
||||||
/* Apply horizontal flip. */
|
|
||||||
MatrixMirrorHorizontal (matrix, width);
|
|
||||||
|
|
||||||
/* Apply clockwise 270 degree rotation around the origin. */
|
|
||||||
MatrixRotate (matrix, M_PI * 1.5, 0, 0);
|
|
||||||
|
|
||||||
/* Translate y by the width. */
|
|
||||||
MatrixTranslate (matrix, 0, -width);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MaybeApplyTransform (PictureBuffer *buffer, DrawParams *params)
|
MaybeApplyTransform (PictureBuffer *buffer, DrawParams *params)
|
||||||
{
|
{
|
||||||
|
@ -1268,8 +1325,9 @@ MaybeApplyTransform (PictureBuffer *buffer, DrawParams *params)
|
||||||
MatrixIdentity (&ftransform);
|
MatrixIdentity (&ftransform);
|
||||||
|
|
||||||
if (params->flags & TransformSet)
|
if (params->flags & TransformSet)
|
||||||
ApplyInverseTransform (buffer, &ftransform,
|
ApplyInverseTransform (buffer->width, buffer->height,
|
||||||
params->transform);
|
&ftransform, params->transform,
|
||||||
|
False);
|
||||||
|
|
||||||
/* Note that these must be applied in the right order. First,
|
/* Note that these must be applied in the right order. First,
|
||||||
the scale is applied. Then, the offset, and finally the
|
the scale is applied. Then, the offset, and finally the
|
||||||
|
@ -1796,8 +1854,9 @@ FindSupportedModifiers (int *pair_count_return)
|
||||||
|
|
||||||
/* pair_count is the number of format-modifier pairs that
|
/* pair_count is the number of format-modifier pairs that
|
||||||
will be returned. First, add one for each implicit
|
will be returned. First, add one for each implicit
|
||||||
modifier, and another one for the linear modifier. */
|
modifier, and another one for each manually specified
|
||||||
pair_count += 2;
|
modifier. */
|
||||||
|
pair_count += 1 + num_specified_modifiers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1844,7 +1903,7 @@ FindSupportedModifiers (int *pair_count_return)
|
||||||
static void
|
static void
|
||||||
InitDrmFormats (void)
|
InitDrmFormats (void)
|
||||||
{
|
{
|
||||||
int pair_count, i, j, n;
|
int pair_count, i, j, n, k;
|
||||||
|
|
||||||
/* First, look up which formats are supported. */
|
/* First, look up which formats are supported. */
|
||||||
if (!FindSupportedFormats ())
|
if (!FindSupportedFormats ())
|
||||||
|
@ -1872,24 +1931,35 @@ InitDrmFormats (void)
|
||||||
drm_formats[n].drm_modifier = DRM_FORMAT_MOD_INVALID;
|
drm_formats[n].drm_modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
/* Check n < pair_count. */
|
/* And add all of the user-specified modifiers. */
|
||||||
XLAssert (n < pair_count);
|
for (j = 0; j < num_specified_modifiers; ++j)
|
||||||
|
{
|
||||||
|
/* Assert that n < pair_count. */
|
||||||
|
XLAssert (n < pair_count);
|
||||||
|
|
||||||
/* And the linear modifier. */
|
drm_formats[n].drm_format = all_formats[i].format_code;
|
||||||
drm_formats[n].drm_format = all_formats[i].format_code;
|
drm_formats[n].drm_modifier = user_specified_modifiers[j];
|
||||||
drm_formats[n].drm_modifier = DRM_FORMAT_MOD_LINEAR;
|
n++;
|
||||||
n++;
|
}
|
||||||
|
|
||||||
/* Now add every supported explicit modifier. */
|
/* Now add every supported explicit modifier. */
|
||||||
for (j = 0; j < all_formats[i].n_supported_modifiers; ++i)
|
for (j = 0; j < all_formats[i].n_supported_modifiers; ++i)
|
||||||
{
|
{
|
||||||
|
/* Ignore previously specified modifiers. */
|
||||||
|
|
||||||
if ((all_formats[i].supported_modifiers[j]
|
if ((all_formats[i].supported_modifiers[j]
|
||||||
== DRM_FORMAT_MOD_INVALID)
|
== DRM_FORMAT_MOD_INVALID))
|
||||||
|| (all_formats[i].supported_modifiers[j]
|
|
||||||
== DRM_FORMAT_MOD_LINEAR))
|
|
||||||
/* Ignore previously specified modifiers. */
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* Ignore user-specified modifiers. */
|
||||||
|
|
||||||
|
for (k = 0; k < num_specified_modifiers; ++k)
|
||||||
|
{
|
||||||
|
if (user_specified_modifiers[k]
|
||||||
|
== all_formats[i].supported_modifiers[j])
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check n < pair_count. */
|
/* Check n < pair_count. */
|
||||||
XLAssert (n < pair_count);
|
XLAssert (n < pair_count);
|
||||||
|
|
||||||
|
|
|
@ -1632,22 +1632,6 @@ GetContentScale (int scale)
|
||||||
return -scale + 1;
|
return -scale + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BufferTransform
|
|
||||||
InvertTransform (BufferTransform transform)
|
|
||||||
{
|
|
||||||
switch (transform)
|
|
||||||
{
|
|
||||||
case CounterClockwise270:
|
|
||||||
return CounterClockwise90;
|
|
||||||
|
|
||||||
case CounterClockwise90:
|
|
||||||
return CounterClockwise270;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return transform;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
BufferWidthAfterTransform (View *view)
|
BufferWidthAfterTransform (View *view)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,3 +13,4 @@ Makefile
|
||||||
vgcore*
|
vgcore*
|
||||||
massif*
|
massif*
|
||||||
callgrind*
|
callgrind*
|
||||||
|
drm_modifiers.h
|
||||||
|
|
189
transform.c
189
transform.c
|
@ -227,3 +227,192 @@ MatrixExport (Matrix *transform, XTransform *xtransform)
|
||||||
|
|
||||||
#undef Export
|
#undef Export
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Various routines shared between renderers. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ApplyInverseTransform (int buffer_width, int buffer_height, Matrix *matrix,
|
||||||
|
BufferTransform transform, Bool cartesian)
|
||||||
|
{
|
||||||
|
float width, height;
|
||||||
|
|
||||||
|
/* Note that the transform is applied in reverse, meaning that a
|
||||||
|
counterclockwise rotation is done clockwise, etc, as TRANSFORM
|
||||||
|
transforms destination coordinates to source ones. CARTESIAN
|
||||||
|
specifies whether or not an actual cartesian coordinate system is
|
||||||
|
being used. */
|
||||||
|
|
||||||
|
width = buffer_width;
|
||||||
|
height = buffer_height;
|
||||||
|
|
||||||
|
switch (transform)
|
||||||
|
{
|
||||||
|
case Normal:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CounterClockwise90:
|
||||||
|
|
||||||
|
if (!cartesian)
|
||||||
|
{
|
||||||
|
/* Apply clockwise 270 degree rotation around the
|
||||||
|
origin. */
|
||||||
|
MatrixRotate (matrix, M_PI * 1.5, 0, 0);
|
||||||
|
|
||||||
|
/* Translate y by the width. */
|
||||||
|
MatrixTranslate (matrix, 0, -width);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Apply clockwise 270 degree rotation around the
|
||||||
|
origin. */
|
||||||
|
MatrixRotate (matrix, M_PI * 0.5, 0, 1);
|
||||||
|
|
||||||
|
/* Translate by the width. */
|
||||||
|
MatrixTranslate (matrix, 0, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CounterClockwise180:
|
||||||
|
/* Apply clockwise 180 degree rotation around the center. */
|
||||||
|
MatrixRotate (matrix, M_PI, width / 2.0f, height / 2.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CounterClockwise270:
|
||||||
|
|
||||||
|
if (!cartesian)
|
||||||
|
{
|
||||||
|
/* Apply clockwise 90 degree rotation around the origin. */
|
||||||
|
MatrixRotate (matrix, M_PI * 0.5, 0, 0);
|
||||||
|
|
||||||
|
/* Translate by the height. */
|
||||||
|
MatrixTranslate (matrix, -height, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Apply clockwise 90 degree rotation around the origin. */
|
||||||
|
MatrixRotate (matrix, M_PI * 1.5, 0, 1);
|
||||||
|
|
||||||
|
/* Translate by the height. */
|
||||||
|
MatrixTranslate (matrix, -height, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Flipped:
|
||||||
|
/* Apply horizontal flip. */
|
||||||
|
MatrixMirrorHorizontal (matrix, width);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Flipped90:
|
||||||
|
/* Apply horizontal flip. */
|
||||||
|
MatrixMirrorHorizontal (matrix, width);
|
||||||
|
|
||||||
|
/* Apply clockwise 90 degree rotation around the origin. */
|
||||||
|
MatrixRotate (matrix, M_PI * 0.5, 0, 0);
|
||||||
|
|
||||||
|
/* Translate by the height. */
|
||||||
|
MatrixTranslate (matrix, -height, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Flipped180:
|
||||||
|
/* Apply horizontal flip. */
|
||||||
|
MatrixMirrorHorizontal (matrix, width);
|
||||||
|
|
||||||
|
/* Apply clockwise 180 degree rotation around the center. */
|
||||||
|
MatrixRotate (matrix, M_PI, width / 2.0f, height / 2.0f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Flipped270:
|
||||||
|
/* Apply horizontal flip. */
|
||||||
|
MatrixMirrorHorizontal (matrix, width);
|
||||||
|
|
||||||
|
/* Apply clockwise 270 degree rotation around the origin. */
|
||||||
|
MatrixRotate (matrix, M_PI * 1.5, 0, 0);
|
||||||
|
|
||||||
|
/* Translate y by the width. */
|
||||||
|
MatrixTranslate (matrix, 0, -width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TransformBox (pixman_box32_t *box, BufferTransform transform,
|
||||||
|
int width, int height)
|
||||||
|
{
|
||||||
|
pixman_box32_t work;
|
||||||
|
|
||||||
|
switch (transform)
|
||||||
|
{
|
||||||
|
case Normal:
|
||||||
|
work = *box;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CounterClockwise90:
|
||||||
|
work.x1 = height - box->y2;
|
||||||
|
work.y1 = box->x1;
|
||||||
|
work.x2 = height - box->y1;
|
||||||
|
work.y2 = box->x2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CounterClockwise180:
|
||||||
|
work.x1 = width - box->x2;
|
||||||
|
work.y1 = height - box->y2;
|
||||||
|
work.x2 = width - box->x1;
|
||||||
|
work.y2 = height - box->y1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CounterClockwise270:
|
||||||
|
work.x1 = box->y1;
|
||||||
|
work.y1 = width - box->x2;
|
||||||
|
work.x2 = box->y2;
|
||||||
|
work.y2 = width - box->x1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Flipped:
|
||||||
|
work.x1 = width - box->x2;
|
||||||
|
work.y1 = box->y1;
|
||||||
|
work.x2 = width - box->x1;
|
||||||
|
work.y2 = box->y2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Flipped90:
|
||||||
|
work.x1 = box->y1;
|
||||||
|
work.y1 = box->x1;
|
||||||
|
work.x2 = box->y2;
|
||||||
|
work.y2 = box->x2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Flipped180:
|
||||||
|
work.x1 = box->x1;
|
||||||
|
work.y1 = height - box->y2;
|
||||||
|
work.x2 = box->x2;
|
||||||
|
work.y2 = height - box->y1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Flipped270:
|
||||||
|
work.x1 = height - box->y2;
|
||||||
|
work.y1 = width - box->x2;
|
||||||
|
work.x2 = height - box->y1;
|
||||||
|
work.y2 = width - box->x1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*box = work;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferTransform
|
||||||
|
InvertTransform (BufferTransform transform)
|
||||||
|
{
|
||||||
|
switch (transform)
|
||||||
|
{
|
||||||
|
case CounterClockwise270:
|
||||||
|
return CounterClockwise90;
|
||||||
|
|
||||||
|
case CounterClockwise90:
|
||||||
|
return CounterClockwise270;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue