summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/intel_uxa.c15
-rw-r--r--uxa/uxa-accel.c137
-rw-r--r--uxa/uxa-glamor.h16
-rw-r--r--uxa/uxa-glyphs.c22
-rw-r--r--uxa/uxa-priv.h8
-rw-r--r--uxa/uxa-render.c208
-rw-r--r--uxa/uxa.c4
7 files changed, 385 insertions, 25 deletions
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index e4a52706..f24f39f5 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -1108,6 +1108,10 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
list_del(&priv->in_flight);
screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
intel_set_pixmap_private(pixmap, priv);
+
+ if (!intel_glamor_create_textured_pixmap(pixmap))
+ intel_set_pixmap_bo(pixmap, NULL);
+
return pixmap;
}
}
@@ -1145,8 +1149,15 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
list_init(&priv->batch);
list_init(&priv->flush);
intel_set_pixmap_private(pixmap, priv);
-
- intel_glamor_create_textured_pixmap(pixmap);
+ /* Create textured pixmap failed means glamor fail to create
+ * a texture from the BO for some reasons, and then glamor
+ * create a new texture attached to the pixmap, and all the
+ * consequent rendering operations on this pixmap will never
+ * fallback to UXA path, so we don't need to hold the useless
+ * BO if it is the case.
+ */
+ if (!intel_glamor_create_textured_pixmap(pixmap))
+ intel_set_pixmap_bo(pixmap, NULL);
}
return pixmap;
diff --git a/uxa/uxa-accel.c b/uxa/uxa-accel.c
index e4afd137..67712d2d 100644
--- a/uxa/uxa-accel.c
+++ b/uxa/uxa-accel.c
@@ -52,14 +52,17 @@ uxa_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int n,
int off_x, off_y;
if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
- if (glamor_fill_spans_nf(pDrawable,
- pGC, n, ppt, pwidth, fSorted)) {
- uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
- return;
- }
- uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RO);
- goto fallback;
+ ok = glamor_fill_spans_nf(pDrawable,
+ pGC, n, ppt, pwidth, fSorted);
+ uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
}
if (uxa_screen->swappedOut || uxa_screen->force_fallback)
@@ -207,10 +210,29 @@ static void
uxa_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int w, int h, int leftPad, int format, char *bits)
{
+ uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen);
+
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+ ok = glamor_put_image_nf(pDrawable,
+ pGC, depth, x, y, w, h,
+ leftPad, format, bits);
+ uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
if (!uxa_do_put_image(pDrawable, pGC, depth, x, y, w, h, format, bits,
- PixmapBytePad(w, pDrawable->depth)))
+ PixmapBytePad(w, pDrawable->depth))) {
+fallback:
uxa_check_put_image(pDrawable, pGC, depth, x, y, w, h, leftPad,
format, bits);
+ }
}
static Bool inline
@@ -352,6 +374,24 @@ uxa_copy_n_to_n(DrawablePtr pSrcDrawable,
int dst_off_x, dst_off_y;
PixmapPtr pSrcPixmap, pDstPixmap;
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_prepare_access(pSrcDrawable, UXA_GLAMOR_ACCESS_RO);
+ uxa_prepare_access(pDstDrawable, UXA_GLAMOR_ACCESS_RW);
+ ok = glamor_copy_n_to_n_nf(pSrcDrawable, pDstDrawable,
+ pGC, pbox, nbox, dx, dy,
+ reverse, upsidedown, bitplane,
+ closure);
+ uxa_finish_access(pDstDrawable, UXA_GLAMOR_ACCESS_RW);
+ uxa_finish_access(pSrcDrawable, UXA_GLAMOR_ACCESS_RO);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
if (uxa_screen->swappedOut || uxa_screen->force_fallback)
goto fallback;
@@ -682,14 +722,16 @@ uxa_poly_fill_rect(DrawablePtr pDrawable,
RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
- if (glamor_poly_fill_rect_nf(pDrawable,
- pGC, nrect, prect)) {
- uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
- return;
- }
- uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RO);
- goto fallback;
+ ok = glamor_poly_fill_rect_nf(pDrawable, pGC, nrect, prect);
+ uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
}
/* Compute intersection of rects and clip region */
@@ -795,9 +837,60 @@ out:
REGION_DESTROY(pScreen, pReg);
}
+void
+uxa_get_spans(DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt, int *pwidth, int nspans, char *pdstStart)
+{
+ ScreenPtr screen = pDrawable->pScreen;
+ uxa_screen_t *uxa_screen = uxa_get_screen(screen);
+
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+ ok = glamor_get_spans_nf(pDrawable, wMax, ppt,
+ pwidth, nspans, pdstStart);
+ uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
+fallback:
+ uxa_check_get_spans(pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+}
+
+static void
+uxa_set_spans(DrawablePtr pDrawable, GCPtr gc, char *src,
+ DDXPointPtr points, int *widths, int n, int sorted)
+{
+ ScreenPtr screen = pDrawable->pScreen;
+ uxa_screen_t *uxa_screen = uxa_get_screen(screen);
+
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ int ok;
+
+ uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+ ok = glamor_set_spans_nf(pDrawable, gc, src,
+ points, widths, n, sorted);
+ uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
+fallback:
+ uxa_check_set_spans(pDrawable, gc, src, points, widths, n, sorted);
+}
+
const GCOps uxa_ops = {
uxa_fill_spans,
- uxa_check_set_spans,
+ uxa_set_spans,
uxa_put_image,
uxa_copy_area,
uxa_check_copy_plane,
@@ -1002,6 +1095,18 @@ uxa_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
Box.x2 = Box.x1 + w;
Box.y2 = Box.y1 + h;
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
+ uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+ ok = glamor_get_image_nf(pDrawable, x, y, w, h,
+ format, planeMask, d);
+ uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
+
+ if (!ok)
+ goto fallback;
+
+ return;
+ }
+
if (uxa_screen->swappedOut || uxa_screen->force_fallback)
goto fallback;
diff --git a/uxa/uxa-glamor.h b/uxa/uxa-glamor.h
index 2c230987..71a9c292 100644
--- a/uxa/uxa-glamor.h
+++ b/uxa/uxa-glamor.h
@@ -37,8 +37,20 @@
#ifdef USE_GLAMOR
#include "glamor.h"
#else
-#define glamor_fill_spans_nf(...) FALSE
-#define glamor_poly_fill_rect_nf(...) FALSE
+#define glamor_fill_spans_nf(...) FALSE
+#define glamor_poly_fill_rect_nf(...) FALSE
+#define glamor_put_image_nf(...) FALSE
+#define glamor_copy_n_to_n_nf(...) FALSE
+#define glamor_get_spans_nf(...) FALSE
+#define glamor_set_spans_nf(...) FALSE
+#define glamor_get_image_nf(...) FALSE
+#define glamor_glyphs_nf(...) FALSE
+#define glamor_glyph_unrealize(...) ;
+#define glamor_composite_nf(...) FALSE
+#define glamor_composite_rects_nf(...) FALSE
+#define glamor_trapezoids_nf(...) FALSE
+#define glamor_triangles_nf(...) FALSE
+#define glamor_add_traps_nf(...) FALSE
#endif
#endif /* UXA_GLAMOR_H */
diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c
index 6c9ea0d6..0091dc23 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -65,6 +65,7 @@
#include <stdlib.h>
#include "uxa-priv.h"
+#include "uxa-glamor.h"
#include "../src/common.h"
#include "mipict.h"
@@ -304,6 +305,7 @@ uxa_glyph_unrealize(ScreenPtr screen,
GlyphPtr glyph)
{
struct uxa_glyph *priv;
+ uxa_screen_t *uxa_screen = uxa_get_screen(screen);
/* Use Lookup in case we have not attached to this glyph. */
priv = dixLookupPrivate(&glyph->devPrivates, &uxa_glyph_key);
@@ -314,6 +316,9 @@ uxa_glyph_unrealize(ScreenPtr screen,
uxa_glyph_set_private(glyph, NULL);
free(priv);
+
+ if (uxa_screen->info->flags & UXA_USE_GLAMOR)
+ glamor_glyph_unrealize(screen, glyph);
}
/* Cut and paste from render/glyph.c - probably should export it instead */
@@ -1062,6 +1067,23 @@ uxa_glyphs(CARD8 op,
int width, height, ret;
PicturePtr localDst = pDst;
+ 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_glyphs_nf(op,
+ pSrc, pDst, maskFormat,
+ xSrc, ySrc, nlist, list, glyphs);
+ 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->info->prepare_composite ||
uxa_screen->swappedOut ||
uxa_screen->force_fallback ||
diff --git a/uxa/uxa-priv.h b/uxa/uxa-priv.h
index a455f25d..d6d857f1 100644
--- a/uxa/uxa-priv.h
+++ b/uxa/uxa-priv.h
@@ -292,6 +292,14 @@ void
uxa_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d);
+void
+uxa_get_spans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
+ int *pwidth, int nspans, char *pdstStart);
+
+void
+uxa_add_traps(PicturePtr pPicture,
+ INT16 x_off, INT16 y_off, int ntrap, xTrap * traps);
+
extern const GCOps uxa_ops;
#ifdef RENDER
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);
+}
diff --git a/uxa/uxa.c b/uxa/uxa.c
index 5a3c0bef..5b3d7097 100644
--- a/uxa/uxa.c
+++ b/uxa/uxa.c
@@ -521,7 +521,7 @@ Bool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver)
screen->GetImage = uxa_get_image;
uxa_screen->SavedGetSpans = screen->GetSpans;
- screen->GetSpans = uxa_check_get_spans;
+ screen->GetSpans = uxa_get_spans;
uxa_screen->SavedCopyWindow = screen->CopyWindow;
screen->CopyWindow = uxa_copy_window;
@@ -559,7 +559,7 @@ Bool uxa_driver_init(ScreenPtr screen, uxa_driver_t * uxa_driver)
ps->Trapezoids = uxa_trapezoids;
uxa_screen->SavedAddTraps = ps->AddTraps;
- ps->AddTraps = uxa_check_add_traps;
+ ps->AddTraps = uxa_add_traps;
}
}
#endif