summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhigang Gong <zhigang.gong@linux.intel.com>2012-02-17 19:50:51 +0800
committerChris Wilson <chris@chris-wilson.co.uk>2012-02-21 08:42:12 +0000
commit1e0d702c3a77f6db3dfd55b8cafc5fca4d778751 (patch)
tree85c057ffeb6cc33cd14a6e5895d102016bf74ac6
parentce7a57994d662f340b9457a2750e4385e7d669cd (diff)
uxa/glamor/dri: Enable the pageflip support on glamor.
To support easy buffer exchange at glamor layer, glamor added a new API glamor_egl_exchange_buffers() to exchange two pixmaps' EGL image and fbos and textures without recreating any of them. But this simple method's requirement is that there are two pixmaps. A exceptional case is: If we are using triple buffer when do page flipping, we will have an extra back_buffer which doesn't have a pixmap attached to it. Then each time we set that buffer to a pixmap, we will have to call the create_egl_textured_pixmap to create the corresponding EGL image and fbo and texture for it. This is not efficient. To fix this issue, this commit introduces a new back_pixmap to intel structure to hold the back buffer and corresponding glamor resources. Then we will just need to do the light weight buffer exchanging at both DDX and glamor layer. As the new back pixmap is similar to the screen pixmap and need to be handled carefully when close screen. As the glamor data structure is a per screen data, and will be released at its close screen method. The glamor's close screen method must cleanup the screen pixmap and back pixmap's glamor resources. screen pixmap is easy to get, but there is no good way to store the back pixmap. So the glamor add a new API glamor_egl_create_textured_screen_ext function to pass the back pixmap's pointer to glamor layer. This commit make us depend on glamor commit: 4e58c4f. And we increased the required glamor version from 0.3.0 to 0.3.1 Signed-off-by: Zhigang Gong <zhigang.gong@linux.intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--configure.ac2
-rw-r--r--src/intel.h1
-rw-r--r--src/intel_display.c7
-rw-r--r--src/intel_dri.c73
-rw-r--r--src/intel_driver.c5
-rw-r--r--src/intel_glamor.c19
-rw-r--r--src/intel_glamor.h3
7 files changed, 97 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac
index 785392ac..1e77faf2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,7 +158,7 @@ AC_ARG_ENABLE(glamor,
AC_MSG_RESULT([$GLAMOR])
AM_CONDITIONAL(GLAMOR, test x$GLAMOR != xno)
if test "x$GLAMOR" != "xno"; then
- PKG_CHECK_MODULES(LIBGLAMOR, [glamor >= 0.3.0])
+ PKG_CHECK_MODULES(LIBGLAMOR, [glamor >= 0.3.1])
PKG_CHECK_MODULES(LIBGLAMOR_EGL, [glamor-egl])
AC_DEFINE(USE_GLAMOR, 1, [Enable glamor acceleration])
fi
diff --git a/src/intel.h b/src/intel.h
index 355aaaf0..e5f8bc8b 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -166,6 +166,7 @@ typedef struct intel_screen_private {
void *modes;
drm_intel_bo *front_buffer, *back_buffer;
+ PixmapPtr back_pixmap;
unsigned int back_name;
long front_pitch, front_tiling;
void *shadow_buffer;
diff --git a/src/intel_display.c b/src/intel_display.c
index d525ffab..11d0e2be 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -1369,6 +1369,7 @@ intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
int i, old_width, old_height, old_pitch;
unsigned long pitch;
uint32_t tiling;
+ ScreenPtr screen;
if (scrn->virtualX == width && scrn->virtualY == height)
return TRUE;
@@ -1382,6 +1383,12 @@ intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
old_fb_id = mode->fb_id;
old_front = intel->front_buffer;
+ if (intel->back_pixmap) {
+ screen = intel->back_pixmap->drawable.pScreen;
+ screen->DestroyPixmap(intel->back_pixmap);
+ intel->back_pixmap = NULL;
+ }
+
if (intel->back_buffer) {
drm_intel_bo_unreference(intel->back_buffer);
intel->back_buffer = NULL;
diff --git a/src/intel_dri.c b/src/intel_dri.c
index 98ae2308..2a0102d0 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -66,6 +66,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "dri2.h"
#include "intel_glamor.h"
+#include "uxa.h"
typedef struct {
int refcnt;
@@ -836,7 +837,7 @@ i830_dri2_del_frame_event(DrawablePtr drawable, DRI2FrameEventPtr info)
}
static struct intel_pixmap *
-intel_exchange_pixmap_buffers(PixmapPtr front, PixmapPtr back)
+intel_exchange_pixmap_buffers(struct intel_screen_private *intel, PixmapPtr front, PixmapPtr back)
{
struct intel_pixmap *new_front, *new_back;
@@ -847,6 +848,7 @@ intel_exchange_pixmap_buffers(PixmapPtr front, PixmapPtr back)
new_front->busy = 1;
new_back->busy = -1;
+ intel_glamor_exchange_buffers(intel, front, back);
return new_front;
}
@@ -866,13 +868,46 @@ I830DRI2ExchangeBuffers(struct intel_screen_private *intel, DRI2BufferPtr front,
back->name = tmp;
/* Swap pixmap bos */
- new_front = intel_exchange_pixmap_buffers(front_priv->pixmap,
+ new_front = intel_exchange_pixmap_buffers(intel,
+ front_priv->pixmap,
back_priv->pixmap);
dri_bo_unreference (intel->front_buffer);
intel->front_buffer = new_front->bo;
dri_bo_reference (intel->front_buffer);
}
+static PixmapPtr
+intel_glamor_create_back_pixmap(ScreenPtr screen,
+ PixmapPtr front_pixmap,
+ drm_intel_bo *back_bo)
+{
+ PixmapPtr back_pixmap;
+
+ back_pixmap = screen->CreatePixmap(screen,
+ 0,
+ 0,
+ front_pixmap->drawable.depth,
+ 0);
+ if (back_pixmap == NULL)
+ return NULL;
+
+ screen->ModifyPixmapHeader(back_pixmap,
+ front_pixmap->drawable.width,
+ front_pixmap->drawable.height,
+ 0, 0,
+ front_pixmap->devKind,
+ 0);
+ intel_set_pixmap_bo(back_pixmap, back_bo);
+ if (!intel_glamor_create_textured_pixmap(back_pixmap)) {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "Failed to create textured back pixmap.\n");
+ screen->DestroyPixmap(back_pixmap);
+ return NULL;
+ }
+ return back_pixmap;
+}
+
/*
* Our internal swap routine takes care of actually exchanging, blitting, or
* flipping buffers as necessary.
@@ -904,6 +939,10 @@ I830DRI2ScheduleFlip(struct intel_screen_private *intel,
}
if (intel->back_buffer == NULL) {
+ I830DRI2BufferPrivatePtr priv;
+ PixmapPtr front_pixmap, back_pixmap;
+ ScreenPtr screen;
+
new_back = drm_intel_bo_alloc(intel->bufmgr, "front buffer",
intel->front_buffer->size, 0);
if (new_back == NULL)
@@ -920,6 +959,21 @@ I830DRI2ScheduleFlip(struct intel_screen_private *intel,
drm_intel_bo_disable_reuse(new_back);
dri_bo_flink(new_back, &intel->back_name);
+
+ if ((intel->uxa_flags & UXA_USE_GLAMOR)) {
+ screen = draw->pScreen;
+ priv = info->front->driverPrivate;
+ front_pixmap = priv->pixmap;
+
+ back_pixmap = intel_glamor_create_back_pixmap(screen,
+ front_pixmap,
+ new_back);
+ if (back_pixmap == NULL) {
+ drm_intel_bo_unreference(new_back);
+ return FALSE;
+ }
+ intel->back_pixmap = back_pixmap;
+ }
} else {
new_back = intel->back_buffer;
intel->back_buffer = NULL;
@@ -933,12 +987,17 @@ I830DRI2ScheduleFlip(struct intel_screen_private *intel,
info->type = DRI2_SWAP_CHAIN;
intel->pending_flip[info->pipe] = info;
- /* Exchange the current front-buffer with the fresh bo */
- intel->back_buffer = intel->front_buffer;
- drm_intel_bo_reference(intel->back_buffer);
-
priv = info->front->driverPrivate;
- intel_set_pixmap_bo(priv->pixmap, new_back);
+
+ /* Exchange the current front-buffer with the fresh bo */
+ if (!(intel->uxa_flags & UXA_USE_GLAMOR)) {
+ intel->back_buffer = intel->front_buffer;
+ drm_intel_bo_reference(intel->back_buffer);
+ intel_set_pixmap_bo(priv->pixmap, new_back);
+ }
+ else
+ intel_exchange_pixmap_buffers(intel, priv->pixmap,
+ intel->back_pixmap);
tmp_name = info->front->name;
info->front->name = intel->back_name;
diff --git a/src/intel_driver.c b/src/intel_driver.c
index d66a8fdb..b3871f49 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -1210,6 +1210,11 @@ static Bool I830CloseScreen(int scrnIndex, ScreenPtr screen)
intel->uxa_driver = NULL;
}
+ if (intel->back_pixmap) {
+ screen->DestroyPixmap(intel->back_pixmap);
+ intel->back_pixmap = NULL;
+ }
+
if (intel->back_buffer) {
drm_intel_bo_unreference(intel->back_buffer);
intel->back_buffer = NULL;
diff --git a/src/intel_glamor.c b/src/intel_glamor.c
index c468d34f..a8681575 100644
--- a/src/intel_glamor.c
+++ b/src/intel_glamor.c
@@ -40,6 +40,16 @@
#include "intel_glamor.h"
#include "uxa.h"
+void
+intel_glamor_exchange_buffers(struct intel_screen_private *intel,
+ PixmapPtr src,
+ PixmapPtr dst)
+{
+ if (!(intel->uxa_flags & UXA_USE_GLAMOR))
+ return;
+ glamor_egl_exchange_buffers(src, dst);
+}
+
Bool
intel_glamor_create_screen_resources(ScreenPtr screen)
{
@@ -52,9 +62,10 @@ intel_glamor_create_screen_resources(ScreenPtr screen)
if (!glamor_glyphs_init(screen))
return FALSE;
- if (!glamor_egl_create_textured_screen(screen,
- intel->front_buffer->handle,
- intel->front_pitch))
+ if (!glamor_egl_create_textured_screen_ext(screen,
+ intel->front_buffer->handle,
+ intel->front_pitch,
+ &intel->back_pixmap))
return FALSE;
return TRUE;
@@ -70,7 +81,7 @@ intel_glamor_pre_init(ScrnInfoPtr scrn)
/* Load glamor module */
if ((glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME))) {
version = xf86GetModuleVersion(glamor_module);
- if (version < MODULE_VERSION_NUMERIC(0,3,0)) {
+ if (version < MODULE_VERSION_NUMERIC(0,3,1)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Incompatible glamor version, required >= 0.3.0.\n");
} else {
diff --git a/src/intel_glamor.h b/src/intel_glamor.h
index 30651328..46692bc8 100644
--- a/src/intel_glamor.h
+++ b/src/intel_glamor.h
@@ -44,7 +44,7 @@ Bool intel_glamor_create_textured_pixmap(PixmapPtr pixmap);
void intel_glamor_destroy_pixmap(PixmapPtr pixmap);
PixmapPtr intel_glamor_create_pixmap(ScreenPtr screen, int w, int h,
int depth, unsigned int usage);
-
+void intel_glamor_exchange_buffers(struct intel_screen_private *intel, PixmapPtr src, PixmapPtr dst);
#else
static inline Bool intel_glamor_pre_init(ScrnInfoPtr scrn) { return TRUE; }
@@ -61,6 +61,7 @@ static inline void intel_glamor_destroy_pixmap(PixmapPtr pixmap) { }
static inline PixmapPtr intel_glamor_create_pixmap(ScreenPtr screen, int w, int h,
int depth, unsigned int usage) { return NULL; }
+static inline void intel_glamor_exchange_buffers(struct intel_screen_private *intel, PixmapPtr src, PixmapPtr dst) {}
#endif
#endif /* INTEL_GLAMOR_H */