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
|
||||
PIXMAN = -lpixman-1
|
||||
DRM = -ldrm
|
||||
DRMFOURCCH = $(INCROOT)/drm/drm_fourcc.h
|
||||
DRMINCLUDES = -I$(INCROOT)/drm
|
||||
PIXMANINCLUDES = -I$(INCROOT)/pixman-1
|
||||
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
|
||||
invocations of the command specified in \fBidleIntervalCommand\fP.
|
||||
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
|
||||
.SH ENVIRONMENT
|
||||
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 \
|
||||
idle_inhibit.o process.o fence_ring.o
|
||||
|
||||
GENHEADERS = transfer_atoms.h
|
||||
GENHEADERS = transfer_atoms.h drm_modifiers.h
|
||||
|
||||
#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 mime4.awk short_types.txt >> $@
|
||||
|
||||
drm_modifiers.h: modifiers.awk $(DRMFOURCCH)
|
||||
awk -f modifiers.awk $(DRMFOURCCH) > $@
|
||||
|
||||
/* Now, define generated files. */
|
||||
|
||||
#define ScannerTarget(name) @@\
|
||||
|
@ -134,8 +137,7 @@ $(OBJS): $(GENHEADERS)
|
|||
depend:: $(GENHEADERS) $(SRCS)
|
||||
|
||||
cleandir::
|
||||
$(RM) $(GENHEADERS) $(GENSRCS) transfer_atoms.h short_types.txt \
|
||||
12to11.tar.gz
|
||||
$(RM) $(GENHEADERS) $(GENSRCS) short_types.txt 12to11.tar.gz
|
||||
|
||||
/* Undefine _BSD_SOURCE and _SVID_SOURCE, since both are deprecated
|
||||
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 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. */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
XLTransformRegion (pixman_region32_t *dst, pixman_region32_t *src,
|
||||
BufferTransform transform, int width, int height)
|
||||
|
|
|
@ -353,9 +353,9 @@ PostEndFrame (FrameClock *clock)
|
|||
/* The vertical blanking period itself can't actually be computed
|
||||
based on available data. However, frame_delay must be inside the
|
||||
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. */
|
||||
target -= clock->frame_delay - 100;
|
||||
target -= clock->frame_delay - 200;
|
||||
|
||||
/* Add the remainder of now if it was probably truncated by the
|
||||
compositor. */
|
||||
|
|
|
@ -26,6 +26,7 @@ along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <drm_fourcc.h>
|
||||
|
||||
#include "compositor.h"
|
||||
#include "drm_modifiers.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 _DmaBufRecord DmaBufRecord;
|
||||
typedef struct _DrmModifierName DrmModifierName;
|
||||
|
||||
typedef struct _PictureBuffer PictureBuffer;
|
||||
typedef struct _PictureTarget PictureTarget;
|
||||
|
@ -46,6 +48,15 @@ typedef struct _BufferActivityRecord BufferActivityRecord;
|
|||
typedef struct _IdleCallback IdleCallback;
|
||||
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
|
||||
server. */
|
||||
|
||||
|
@ -277,6 +288,12 @@ struct _DmaBufRecord
|
|||
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. */
|
||||
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. */
|
||||
static DrmFormat *drm_formats;
|
||||
|
||||
|
@ -741,6 +765,112 @@ InitSynchronizedPresentation (void)
|
|||
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. */
|
||||
static void AddRenderFlag (int);
|
||||
|
||||
|
@ -769,6 +899,9 @@ InitRenderFuncs (void)
|
|||
presentation. */
|
||||
InitSynchronizedPresentation ();
|
||||
|
||||
/* Find out what additional modifiers the user wants. */
|
||||
InitAdditionalModifiers ();
|
||||
|
||||
if (use_direct_presentation)
|
||||
AddRenderFlag (SupportsDirectPresent);
|
||||
|
||||
|
@ -1166,82 +1299,6 @@ CompareStretch (DrawParams *params, DrawParams *other)
|
|||
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
|
||||
MaybeApplyTransform (PictureBuffer *buffer, DrawParams *params)
|
||||
{
|
||||
|
@ -1268,8 +1325,9 @@ MaybeApplyTransform (PictureBuffer *buffer, DrawParams *params)
|
|||
MatrixIdentity (&ftransform);
|
||||
|
||||
if (params->flags & TransformSet)
|
||||
ApplyInverseTransform (buffer, &ftransform,
|
||||
params->transform);
|
||||
ApplyInverseTransform (buffer->width, buffer->height,
|
||||
&ftransform, params->transform,
|
||||
False);
|
||||
|
||||
/* Note that these must be applied in the right order. First,
|
||||
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
|
||||
will be returned. First, add one for each implicit
|
||||
modifier, and another one for the linear modifier. */
|
||||
pair_count += 2;
|
||||
modifier, and another one for each manually specified
|
||||
modifier. */
|
||||
pair_count += 1 + num_specified_modifiers;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1844,7 +1903,7 @@ FindSupportedModifiers (int *pair_count_return)
|
|||
static void
|
||||
InitDrmFormats (void)
|
||||
{
|
||||
int pair_count, i, j, n;
|
||||
int pair_count, i, j, n, k;
|
||||
|
||||
/* First, look up which formats are supported. */
|
||||
if (!FindSupportedFormats ())
|
||||
|
@ -1872,24 +1931,35 @@ InitDrmFormats (void)
|
|||
drm_formats[n].drm_modifier = DRM_FORMAT_MOD_INVALID;
|
||||
n++;
|
||||
|
||||
/* Check n < pair_count. */
|
||||
XLAssert (n < pair_count);
|
||||
/* And add all of the user-specified modifiers. */
|
||||
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_modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
n++;
|
||||
drm_formats[n].drm_format = all_formats[i].format_code;
|
||||
drm_formats[n].drm_modifier = user_specified_modifiers[j];
|
||||
n++;
|
||||
}
|
||||
|
||||
/* Now add every supported explicit modifier. */
|
||||
for (j = 0; j < all_formats[i].n_supported_modifiers; ++i)
|
||||
{
|
||||
/* Ignore previously specified modifiers. */
|
||||
|
||||
if ((all_formats[i].supported_modifiers[j]
|
||||
== DRM_FORMAT_MOD_INVALID)
|
||||
|| (all_formats[i].supported_modifiers[j]
|
||||
== DRM_FORMAT_MOD_LINEAR))
|
||||
/* Ignore previously specified modifiers. */
|
||||
== DRM_FORMAT_MOD_INVALID))
|
||||
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. */
|
||||
XLAssert (n < pair_count);
|
||||
|
||||
|
|
|
@ -1632,22 +1632,6 @@ GetContentScale (int scale)
|
|||
return -scale + 1;
|
||||
}
|
||||
|
||||
static BufferTransform
|
||||
InvertTransform (BufferTransform transform)
|
||||
{
|
||||
switch (transform)
|
||||
{
|
||||
case CounterClockwise270:
|
||||
return CounterClockwise90;
|
||||
|
||||
case CounterClockwise90:
|
||||
return CounterClockwise270;
|
||||
|
||||
default:
|
||||
return transform;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
BufferWidthAfterTransform (View *view)
|
||||
{
|
||||
|
|
|
@ -13,3 +13,4 @@ Makefile
|
|||
vgcore*
|
||||
massif*
|
||||
callgrind*
|
||||
drm_modifiers.h
|
||||
|
|
189
transform.c
189
transform.c
|
@ -227,3 +227,192 @@ MatrixExport (Matrix *transform, XTransform *xtransform)
|
|||
|
||||
#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