diff options
-rw-r--r-- | src/intel_uxa.c | 15 | ||||
-rw-r--r-- | uxa/uxa-accel.c | 137 | ||||
-rw-r--r-- | uxa/uxa-glamor.h | 16 | ||||
-rw-r--r-- | uxa/uxa-glyphs.c | 22 | ||||
-rw-r--r-- | uxa/uxa-priv.h | 8 | ||||
-rw-r--r-- | uxa/uxa-render.c | 208 | ||||
-rw-r--r-- | uxa/uxa.c | 4 |
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); +} @@ -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 |