diff --git a/12to11.conf b/12to11.conf
index cb7f974..220e48f 100644
--- a/12to11.conf
+++ b/12to11.conf
@@ -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
diff --git a/12to11.man b/12to11.man
index dd7c83b..2a4fb56 100644
--- a/12to11.man
+++ b/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
diff --git a/Imakefile b/Imakefile
index 59363eb..a6db4f9 100644
--- a/Imakefile
+++ b/Imakefile
@@ -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. */
diff --git a/compositor.h b/compositor.h
index 7916b37..b8ebee1 100644
--- a/compositor.h
+++ b/compositor.h
@@ -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);
diff --git a/fns.c b/fns.c
index ca3e44d..0fad5e7 100644
--- a/fns.c
+++ b/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)
diff --git a/frame_clock.c b/frame_clock.c
index 70e92e1..48933a5 100644
--- a/frame_clock.c
+++ b/frame_clock.c
@@ -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. */
diff --git a/picture_renderer.c b/picture_renderer.c
index b16cffd..8aafd29 100644
--- a/picture_renderer.c
+++ b/picture_renderer.c
@@ -26,6 +26,7 @@ along with 12to11. If not, see . */
#include
#include "compositor.h"
+#include "drm_modifiers.h"
#include
@@ -37,6 +38,7 @@ along with 12to11. If not, see . */
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);
diff --git a/subcompositor.c b/subcompositor.c
index 0d7e151..be55614 100644
--- a/subcompositor.c
+++ b/subcompositor.c
@@ -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)
{
diff --git a/svnignore.txt b/svnignore.txt
index 3d21340..905b3bd 100644
--- a/svnignore.txt
+++ b/svnignore.txt
@@ -13,3 +13,4 @@ Makefile
vgcore*
massif*
callgrind*
+drm_modifiers.h
diff --git a/transform.c b/transform.c
index a11493e..6e3b268 100644
--- a/transform.c
+++ b/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;
+ }
+}