This commit introduces a new function in UXA layer need_flush which is used to let the UXA layer to notify the lower layer that some pixmap get modified by GLAMOR. And then the intel driver could know it need to flush front buffer latter. This commit also adds some necessary flushing pointis for UXA layer and glamor layer. Basicly, there are three scenarios: 1. Before calling into glamor layer, it needs to flush all the corresponding UXA batch comand buffer. 2. After calling the glamor rendering functions, it needs to flush the pending GL operations. 3. Before we map a pixmap's BO, we also need to flush all the pending GL operations. The scenario 2 could be eliminated when we fully change to glamor path. Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com> --- src/intel_glamor.c | 13 ++++++++++++- src/intel_uxa.c | 8 +++++++- uxa/uxa-accel.c | 30 ++++++++++++++++++++++++------ uxa/uxa.h | 16 +++++++++++++++- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/intel_glamor.c b/src/intel_glamor.c index 80cde40..0920c05 100644 --- a/src/intel_glamor.c +++ b/src/intel_glamor.c @@ -106,6 +106,16 @@ intel_glamor_destroy_pixmap(PixmapPtr pixmap) glamor_egl_destroy_textured_pixmap(pixmap); } +static void +intel_glamor_need_flush(DrawablePtr pDrawable) +{ + ScrnInfoPtr scrn = xf86Screens[pDrawable->pScreen->myNum]; + intel_screen_private * intel; + + intel = intel_get_screen_private(scrn); + intel->needs_flush = TRUE; +} + Bool intel_glamor_init(ScreenPtr screen) { @@ -113,7 +123,6 @@ intel_glamor_init(ScreenPtr screen) ScrnInfoPtr scrn = xf86Screens[screen->myNum]; intel_screen_private * intel; - if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed to initialize glamor\n"); @@ -130,6 +139,8 @@ intel_glamor_init(ScreenPtr screen) intel->uxa_driver->flags |= UXA_USE_GLAMOR; intel->uxa_flags = intel->uxa_driver->flags; + intel->uxa_driver->need_flush = intel_glamor_need_flush; + xf86DrvMsg(scrn->scrnIndex, X_INFO, "Use GLAMOR acceleration.\n"); return TRUE; diff --git a/src/intel_uxa.c b/src/intel_uxa.c index 5202076..9fa0165 100644 --- a/src/intel_uxa.c +++ b/src/intel_uxa.c @@ -705,8 +705,14 @@ static Bool intel_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access) int ret; if (!list_is_empty(&priv->batch) && - (access == UXA_ACCESS_RW || priv->batch_write)) + ((access == UXA_ACCESS_RW || access == UXA_GLAMOR_ACCESS_RW) + || priv->batch_write)) intel_batch_submit(scrn); + + if (access == UXA_GLAMOR_ACCESS_RW || access == UXA_GLAMOR_ACCESS_RO) + return TRUE; + + intel_glamor_block_handler(intel); if (priv->tiling || bo->size <= intel->max_gtt_map_size) ret = drm_intel_gem_bo_map_gtt(bo); diff --git a/uxa/uxa-accel.c b/uxa/uxa-accel.c index 5b27aaa..bd9e02b 100644 --- a/uxa/uxa-accel.c +++ b/uxa/uxa-accel.c @@ -56,11 +56,16 @@ uxa_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int n, int x1, x2, y; int off_x, off_y; - if ((uxa_screen->info->flags & UXA_GLAMOR_FLAGS) - && (glamor_fill_spans_nf(pDrawable, pGC, n, ppt, pwidth, fSorted))) - return; - else if(uxa_screen->info->flags & UXA_USE_GLAMOR_ONLY) - goto fallback; + if ((uxa_screen->info->flags & UXA_GLAMOR_FLAGS)) { + uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW); + if (glamor_fill_spans_nf(pDrawable, + pGC, n, ppt, pwidth, fSorted)) { + uxa_screen->info->need_flush(pDrawable); + glamor_block_handler(screen); + return; + } else if (uxa_screen->info->flags & UXA_USE_GLAMOR_ONLY) + goto fallback; + } if (uxa_screen->swappedOut || uxa_screen->force_fallback) goto fallback; @@ -685,9 +690,22 @@ uxa_poly_fill_rect(DrawablePtr pDrawable, int n; RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED); + if ((uxa_screen->info->flags & UXA_GLAMOR_FLAGS)) { + uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW); + if (glamor_poly_fill_rect_nf(pDrawable, + pGC, nrect, prect)) { + uxa_screen->info->need_flush(pDrawable); + glamor_block_handler(pDrawable->pScreen); + return; + } else if (uxa_screen->info->flags & UXA_USE_GLAMOR_ONLY) + goto fallback; + } + if ((uxa_screen->info->flags & UXA_GLAMOR_FLAGS) - && (glamor_poly_fill_rect_nf(pDrawable, pGC, nrect, prect))) + && (glamor_poly_fill_rect_nf(pDrawable, pGC, nrect, prect))) { + uxa_screen->info->need_flush(pDrawable); return; + } else if(uxa_screen->info->flags & UXA_USE_GLAMOR_ONLY) goto fallback; diff --git a/uxa/uxa.h b/uxa/uxa.h index 21e6f2a..5230407 100644 --- a/uxa/uxa.h +++ b/uxa/uxa.h @@ -45,7 +45,9 @@ typedef enum { UXA_ACCESS_RO, - UXA_ACCESS_RW + UXA_ACCESS_RW, + UXA_GLAMOR_ACCESS_RO, + UXA_GLAMOR_ACCESS_RW } uxa_access_t; /** @@ -530,6 +532,18 @@ typedef struct _UxaDriver { */ Bool(*pixmap_is_offscreen) (PixmapPtr pPix); + /** + * need_flush() is called after Glamor modify a textured pixmap. + * + * @param pDrawable the target drawable. + * + * + * need_flush is used to notify the underlying DDX layer that + * some pixmaps get dirty in glamor access. Thus a render cache + * flushing may be required, especially when the modified pixmap + * is the screen pixmap which is the front buffer. + */ + void (*need_flush) (DrawablePtr pDrawable); /** @} */ } uxa_driver_t; -- 1.7.4.4