summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@linux.intel.com>2011-11-15 19:26:27 +0800
committerZhigang Gong <zhigang.gong@linux.intel.com>2011-11-15 19:26:27 +0800
commit11164ab2d8d836076c71016e4771800db570b75d (patch)
treee82e41c098ce523a662ce4bea2b1afa3a2dcc9ee
parentb6203262a57ceeccf174a6810b5926dd506e11b0 (diff)
glamor: Address GLAMOR/UXA flushing problem.glamor
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@linux.intel.com>
-rw-r--r--src/intel_glamor.c13
-rw-r--r--src/intel_uxa.c8
-rw-r--r--uxa/uxa-accel.c30
-rw-r--r--uxa/uxa.h16
4 files changed, 58 insertions, 9 deletions
diff --git a/src/intel_glamor.c b/src/intel_glamor.c
index 80cde40a..0920c054 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 52020767..9fa01653 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 5b27aaa6..bd9e02bc 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 21e6f2a8..52304074 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;