From: Zhigang Gong <zhigang.g...@linux.intel.com>

As create glamor pixmap by default will get much better performance
by using the textured-drm pixmap, this commit is to make that the
default behaviour when configure to use glamor.

A side effect is that for those glamor pixmaps, they don't have a
valid BO attached to it and thus it fails to get a DRI drawable. This
commit also fixes that problem by copy the fixup_shadow mechanism. I
tested this with mutter, and it seems work fine.

The performance gain to apply this patch is about 20% to 40% with
different workload.

Signed-off-by: Zhigang Gong <zhigang.g...@linux.intel.com>
---
 src/intel_dri.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 src/intel_uxa.c |    6 ++++
 2 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/src/intel_dri.c b/src/intel_dri.c
index df3338f..c9444c9 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -66,6 +66,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "dri2.h"
 
+#include "intel_glamor.h"
+
 typedef struct {
        int refcnt;
        PixmapPtr pixmap;
@@ -125,6 +127,52 @@ static PixmapPtr get_front_buffer(DrawablePtr drawable)
        return pixmap;
 }
 
+static PixmapPtr fixup_glamor(DrawablePtr drawable, PixmapPtr pixmap)
+{
+       ScreenPtr screen = drawable->pScreen;
+       PixmapPtr old = get_drawable_pixmap(drawable);
+       struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
+       GCPtr gc;
+
+       /* With a glamor pixmap, 2D pixmaps are created in texture
+        * and without a static BO attached to it. To support DRI,
+        * we need to create a new textured-drm pixmap and
+        * need to copy the original content to this new textured-drm
+        * pixmap, and then convert the old pixmap to a coherent
+        * textured-drm pixmap which has a valid BO attached to it
+        * and also has a valid texture, thus both glamor and DRI2
+        * can access it.
+        *
+        */
+
+       /* Copy the current contents of the pixmap to the bo. */
+       gc = GetScratchGC(drawable->depth, screen);
+       if (gc) {
+               ValidateGC(&pixmap->drawable, gc);
+               gc->ops->CopyArea(drawable, &pixmap->drawable,
+                                 gc,
+                                 0, 0,
+                                 drawable->width,
+                                 drawable->height,
+                                 0, 0);
+               FreeScratchGC(gc);
+       }
+
+       intel_set_pixmap_private(pixmap, NULL);
+       screen->DestroyPixmap(pixmap);
+
+       /* And redirect the pixmap to the new bo (for 3D). */
+       intel_set_pixmap_private(old, priv);
+       old->refcnt++;
+
+       if (!intel_glamor_create_textured_pixmap(old)) {
+               FatalError("Failed to get DRI drawable for glamor pixmap.\n");
+       }
+
+       intel_get_screen_private(xf86Screens[screen->myNum])->needs_flush = 
TRUE;
+       return old;
+}
+
 static PixmapPtr fixup_shadow(DrawablePtr drawable, PixmapPtr pixmap)
 {
        ScreenPtr screen = drawable->pScreen;
@@ -203,6 +251,7 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int 
*attachments,
        I830DRI2BufferPrivatePtr privates;
        PixmapPtr pixmap, pDepthPixmap;
        int i;
+       int is_glamor_pixmap;
 
        buffers = calloc(count, sizeof *buffers);
        if (buffers == NULL)
@@ -222,7 +271,10 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int 
*attachments,
                        pixmap = pDepthPixmap;
                        pixmap->refcnt++;
                }
-               if (pixmap == NULL) {
+
+               is_glamor_pixmap = pixmap && (intel_get_pixmap_private(pixmap) 
== NULL);
+
+               if (pixmap == NULL || is_glamor_pixmap) {
                        unsigned int hint = INTEL_CREATE_PIXMAP_DRI2;
 
                        if (intel->tiling & INTEL_TILING_3D) {
@@ -255,8 +307,12 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int 
*attachments,
                                goto unwind;
                        }
 
-                       if (attachment == DRI2BufferFrontLeft)
-                               pixmap = fixup_shadow(drawable, pixmap);
+                       if (attachment == DRI2BufferFrontLeft) {
+                               if (!is_glamor_pixmap)
+                                       pixmap = fixup_shadow(drawable, pixmap);
+                               else
+                                       pixmap = fixup_glamor(drawable, pixmap);
+                       }
                }
 
                if (attachments[i] == DRI2BufferDepth)
@@ -317,6 +373,7 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int 
attachment,
        DRI2Buffer2Ptr buffer;
        I830DRI2BufferPrivatePtr privates;
        PixmapPtr pixmap;
+       int is_glamor_pixmap;
 
        buffer = calloc(1, sizeof *buffer);
        if (buffer == NULL)
@@ -330,7 +387,9 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int 
attachment,
        pixmap = NULL;
        if (attachment == DRI2BufferFrontLeft)
                pixmap = get_front_buffer(drawable);
-       if (pixmap == NULL) {
+
+       is_glamor_pixmap = pixmap && (intel_get_pixmap_private(pixmap) == NULL);
+       if (pixmap == NULL || is_glamor_pixmap) {
                unsigned int hint = INTEL_CREATE_PIXMAP_DRI2;
                int pixmap_width = drawable->width;
                int pixmap_height = drawable->height;
@@ -400,9 +459,12 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int 
attachment,
                        free(buffer);
                        return NULL;
                }
-
-               if (attachment == DRI2BufferFrontLeft)
-                       pixmap = fixup_shadow(drawable, pixmap);
+               if (attachment == DRI2BufferFrontLeft) {
+                       if (!is_glamor_pixmap)
+                               pixmap = fixup_shadow(drawable, pixmap);
+                       else
+                               pixmap = fixup_glamor(drawable, pixmap);
+               }
        }
 
        buffer->attachment = attachment;
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 9d74554..f04a2ef 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -1026,6 +1026,12 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, 
int depth,
        struct intel_pixmap *priv;
        PixmapPtr pixmap, new_pixmap = NULL;
 
+       if (!(usage & INTEL_CREATE_PIXMAP_DRI2)) {
+               pixmap = intel_glamor_create_pixmap(screen, w, h, depth, usage);
+               if (pixmap)
+                       return pixmap;
+       }
+
        if (w > 32767 || h > 32767)
                return NullPixmap;
 
-- 
1.7.4.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to