From: Zhigang Gong <zhigang.gong at 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.gong at 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