summaryrefslogtreecommitdiff
path: root/uxa/uxa-render.c
diff options
context:
space:
mode:
Diffstat (limited to 'uxa/uxa-render.c')
-rw-r--r--uxa/uxa-render.c208
1 files changed, 205 insertions, 3 deletions
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index 51c12f17..878b0288 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -29,11 +29,24 @@
#include <stdlib.h>
#include "uxa-priv.h"
+#include "uxa-glamor.h"
#include <xorgVersion.h>
#ifdef RENDER
#include "mipict.h"
+/* Note: when using glamor we can not fail through to the ordinary UXA
+ * code paths, as glamor keeps an internal texture which will become
+ * inconsistent with the original bo. (The texture is replaced whenever
+ * the format changes, e.g. switching between xRGB and ARGB, for which mesa
+ * will allocate its own bo.)
+ *
+ * Ergo it is unsafe to fall through to the original backend operations if
+ * glamor is enabled.
+ *
+ * XXX This has some serious implications for mixing Render, DRI, scanout...
+ */
+
static void uxa_composite_fallback_pict_desc(PicturePtr pict, char *string,
int n)
{
@@ -986,6 +999,20 @@ uxa_solid_rects (CARD8 op,
if (!pixman_region_not_empty(dst->pCompositeClip))
return;
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_picture_prepare_access(dst, UXA_GLAMOR_ACCESS_RW);
+ ok = glamor_composite_rects_nf(op, dst, color,
+ num_rects, rects);
+ uxa_picture_finish_access(dst, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
if (dst->alphaMap)
goto fallback;
@@ -1530,6 +1557,30 @@ uxa_composite(CARD8 op,
RegionRec region;
int tx, ty;
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_picture_prepare_access(pDst, UXA_GLAMOR_ACCESS_RW);
+ uxa_picture_prepare_access(pSrc, UXA_GLAMOR_ACCESS_RO);
+ if (pMask)
+ uxa_picture_prepare_access(pMask, UXA_GLAMOR_ACCESS_RO);
+
+ ok = glamor_composite_nf(op,
+ pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst,
+ width, height);
+
+ if (pMask)
+ uxa_picture_finish_access(pMask, UXA_GLAMOR_ACCESS_RO);
+ uxa_picture_finish_access(pSrc, UXA_GLAMOR_ACCESS_RO);
+ uxa_picture_finish_access(pDst, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
if (uxa_screen->swappedOut || uxa_screen->force_fallback)
goto fallback;
@@ -1766,8 +1817,8 @@ uxa_create_alpha_picture(ScreenPtr pScreen,
static void
uxa_check_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
- int ntrap, xTrapezoid * traps)
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntrap, xTrapezoid * traps)
{
ScreenPtr screen = dst->pDrawable->pScreen;
@@ -1871,7 +1922,25 @@ uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
BoxRec bounds;
Bool direct;
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_picture_prepare_access(dst, UXA_GLAMOR_ACCESS_RW);
+ uxa_picture_prepare_access(src, UXA_GLAMOR_ACCESS_RO);
+ ok = glamor_trapezoids_nf(op,
+ src, dst, maskFormat, xSrc,
+ ySrc, ntrap, traps);
+ uxa_picture_finish_access(src, UXA_GLAMOR_ACCESS_RO);
+ uxa_picture_finish_access(dst, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
if (uxa_screen->swappedOut || uxa_screen->force_fallback) {
+fallback:
uxa_check_trapezoids(op, src, dst, maskFormat, xSrc, ySrc, ntrap, traps);
return;
}
@@ -1976,6 +2045,88 @@ uxa_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst,
}
}
+static void
+uxa_check_triangles(CARD8 op, PicturePtr src, PicturePtr dst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle *tri)
+{
+ ScreenPtr screen = dst->pDrawable->pScreen;
+
+ if (maskFormat) {
+ PixmapPtr scratch = NULL;
+ PicturePtr mask;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+ BoxRec bounds;
+ int width, height;
+ pixman_image_t *image;
+ pixman_format_code_t format;
+ int error;
+
+ xDst = pixman_fixed_to_int(tri[0].p1.x);
+ yDst = pixman_fixed_to_int(tri[0].p1.y);
+
+ miTriangleBounds (ntri, tri, &bounds);
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+
+ width = bounds.x2 - bounds.x1;
+ height = bounds.y2 - bounds.y1;
+
+ format = maskFormat->format |
+ (BitsPerPixel(maskFormat->depth) << 24);
+ image =
+ pixman_image_create_bits(format, width, height, NULL, 0);
+ if (!image)
+ return;
+
+ pixman_add_triangles(image,
+ -bounds.x1, -bounds.y1,
+ ntri, (pixman_triangle_t *)tri);
+
+ scratch = GetScratchPixmapHeader(screen, width, height,
+ PIXMAN_FORMAT_DEPTH(format),
+ PIXMAN_FORMAT_BPP(format),
+ pixman_image_get_stride(image),
+ pixman_image_get_data(image));
+ if (!scratch) {
+ pixman_image_unref(image);
+ return;
+ }
+
+ mask = CreatePicture(0, &scratch->drawable,
+ PictureMatchFormat(screen,
+ PIXMAN_FORMAT_DEPTH(format),
+ format),
+ 0, 0, serverClient, &error);
+ if (!mask) {
+ FreeScratchPixmapHeader(scratch);
+ pixman_image_unref(image);
+ return;
+ }
+
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture(op, src, mask, dst,
+ xRel, yRel,
+ 0, 0,
+ bounds.x1, bounds.y1,
+ width, height);
+ FreePicture(mask, 0);
+
+ FreeScratchPixmapHeader(scratch);
+ pixman_image_unref(image);
+ } else {
+ if (dst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat(screen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat(screen, 8, PICT_a8);
+
+ for (; ntri; ntri--, tri++)
+ uxa_check_triangles(op, src, dst, maskFormat, xSrc, ySrc, 1, tri);
+ }
+}
+
/**
* uxa_triangles is essentially a copy of miTriangles that uses
* uxa_create_alpha_picture instead of miCreateAlphaPicture.
@@ -1995,10 +2146,36 @@ uxa_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
int ntri, xTriangle * tris)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
PictureScreenPtr ps = GetPictureScreen(pScreen);
BoxRec bounds;
- Bool direct = op == PictOpAdd && miIsSolidAlpha(pSrc);
+ Bool direct;
+
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_picture_prepare_access(pDst, UXA_GLAMOR_ACCESS_RW);
+ uxa_picture_prepare_access(pSrc, UXA_GLAMOR_ACCESS_RO);
+ ok = glamor_triangles_nf(op,
+ pSrc, pDst, maskFormat, xSrc,
+ ySrc, ntri, tris);
+ uxa_picture_finish_access(pSrc, UXA_GLAMOR_ACCESS_RO);
+ uxa_picture_finish_access(pDst, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
+ if (uxa_screen->swappedOut || uxa_screen->force_fallback) {
+fallback:
+ uxa_check_triangles(op, pSrc, pDst, maskFormat,
+ xSrc, ySrc, ntri, tris);
+ return;
+ }
+ direct = op == PictOpAdd && miIsSolidAlpha(pSrc);
if (maskFormat || direct) {
miTriangleBounds(ntri, tris, &bounds);
@@ -2069,3 +2246,28 @@ uxa_triangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
tris);
}
}
+
+void
+uxa_add_traps(PicturePtr pPicture,
+ INT16 x_off, INT16 y_off, int ntrap, xTrap * traps)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+ uxa_screen_t *uxa_screen = uxa_get_screen(pScreen);
+
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_picture_prepare_access(pPicture, UXA_GLAMOR_ACCESS_RW);
+ ok = glamor_add_traps_nf(pPicture,
+ x_off, y_off, ntrap, traps);
+ uxa_picture_finish_access(pPicture, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
+fallback:
+ uxa_check_add_traps(pPicture, x_off, y_off, ntrap, traps);
+}