diff mbox

[Branch,~glcompbench-dev/glcompbench/trunk] Rev 57: Add double buffering support to the Xrender canvas.

Message ID 20110817141713.8884.33791.launchpad@ackee.canonical.com
State Accepted
Headers show

Commit Message

alexandros.frantzis@linaro.org Aug. 17, 2011, 2:17 p.m. UTC
------------------------------------------------------------
revno: 57
committer: Alexandros Frantzis <alexandros.frantzis@linaro.org>
branch nick: trunk
timestamp: Wed 2011-08-17 17:15:49 +0300
message:
  Add double buffering support to the Xrender canvas.
modified:
  src/composite-canvas-xrender.cc
  src/composite-canvas-xrender.h


--
lp:glcompbench
https://code.launchpad.net/~glcompbench-dev/glcompbench/trunk

You are subscribed to branch lp:glcompbench.
To unsubscribe from this branch go to https://code.launchpad.net/~glcompbench-dev/glcompbench/trunk/+edit-subscription
diff mbox

Patch

=== modified file 'src/composite-canvas-xrender.cc'
--- src/composite-canvas-xrender.cc	2011-08-03 17:13:02 +0000
+++ src/composite-canvas-xrender.cc	2011-08-17 14:15:49 +0000
@@ -30,8 +30,6 @@ 
 #include "options.h"
 #include "log.h"
 
-#include <sys/shm.h>
-
 CompositeCanvasXRender::~CompositeCanvasXRender()
 {
     release_resources();
@@ -56,14 +54,92 @@ 
 }
 
 bool
+CompositeCanvasXRender::have_xdbe()
+{
+    int major, minor;
+    bool have_xdbe = false;
+        
+    /* Check for the Xdbe extension */
+    if (XdbeQueryExtension(xdpy_, &major, &minor)) {
+        Log::debug("Xdbe extension version %d.%d\n", major, minor);
+        have_xdbe = true;
+    }
+    else {
+        Log::info("** Xdbe extension not supported. You may experience flickering.\n");
+    }
+
+    return have_xdbe;
+}
+
+bool
+CompositeCanvasXRender::ensure_xdbe_back_buffer()
+{
+    XdbeScreenVisualInfo *xdbe_screen_vis_info;
+    XWindowAttributes canvas_attr;
+    int num_screens = 1;
+    bool dbe_visual_found = false;
+
+    if (xdbe_back_buffer_)
+        return true;
+
+    if (!have_xdbe())
+        return false;
+
+    /* Check if the canvas visual supports double-buffering */
+    if (!XGetWindowAttributes(xdpy_, canvas_, &canvas_attr)) {
+        Log::error("XGetWindowAttributes failed!\n");
+        return false;
+    }
+
+    xdbe_screen_vis_info = XdbeGetVisualInfo(xdpy_, &canvas_, &num_screens);
+    if (!xdbe_screen_vis_info || num_screens == 0) {
+        Log::error("XdbeGetVisualInfo failed!\n");
+        return false;
+    }
+
+    for (int i = 0; i < xdbe_screen_vis_info[0].count; i++) {
+        XdbeVisualInfo *vis_info = &xdbe_screen_vis_info[0].visinfo[i];
+        if (vis_info->visual == XVisualIDFromVisual(canvas_attr.visual)) {
+            dbe_visual_found = true;
+            break;
+        }
+    }
+
+    XdbeFreeVisualInfo(xdbe_screen_vis_info);
+ 
+    if (!dbe_visual_found) {
+        Log::info("** The window visual does not support double buffering."
+                  " You may experience flickering!\n");
+        return false;
+    }
+
+    /* Allocate the back buffer */
+    xdbe_back_buffer_ = XdbeAllocateBackBufferName(xdpy_, canvas_,
+                                                   XdbeBackground);
+    if (!xdbe_back_buffer_) {
+        Log::error("XdbeAllocateBufferName failed!\n");
+        return false;
+    }
+
+    return true;
+}
+
+bool
 CompositeCanvasXRender::ensure_xrender_picture()
 {
+    Drawable drawable;
+
     if (xrender_picture_)
         return true;
 
     if (!have_xrender())
         return false;
 
+    if (!ensure_xdbe_back_buffer())
+        drawable = canvas_;
+    else
+        drawable = xdbe_back_buffer_;
+
     XWindowAttributes canvas_attr;
 
     if (!XGetWindowAttributes(xdpy_, canvas_, &canvas_attr)) {
@@ -81,7 +157,7 @@ 
         return false;
     }
 
-    xrender_picture_ = XRenderCreatePicture(xdpy_, canvas_, pict_format,
+    xrender_picture_ = XRenderCreatePicture(xdpy_, drawable, pict_format,
                                             0, NULL);
     if (!xrender_picture_) {
         Log::error("XRenderCreatePicture failed!\n");
@@ -132,7 +208,11 @@ 
     if (xrender_picture_)
         XRenderFreePicture(xdpy_, xrender_picture_);
 
+    if (xdbe_back_buffer_)
+        XdbeDeallocateBackBufferName(xdpy_, xdbe_back_buffer_);
+
     xrender_picture_ = 0;
+    xdbe_back_buffer_ = 0;
 }
 
 CompositeWindow *
@@ -144,6 +224,10 @@ 
 void
 CompositeCanvasXRender::update_screen()
 {
+    if (xdbe_back_buffer_) {
+        XdbeSwapInfo swap_info = {canvas_, XdbeBackground};
+        XdbeSwapBuffers(xdpy_, &swap_info, 1);
+    }
 }
 
 std::string

=== modified file 'src/composite-canvas-xrender.h'
--- src/composite-canvas-xrender.h	2011-08-03 17:13:02 +0000
+++ src/composite-canvas-xrender.h	2011-08-17 14:15:49 +0000
@@ -29,12 +29,14 @@ 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/extensions/Xrender.h>
+#include <X11/extensions/Xdbe.h>
 
 class CompositeCanvasXRender: public CompositeCanvas
 {
 public:
     CompositeCanvasXRender() :
-        CompositeCanvas("xrender"), xrender_picture_(0) {}
+        CompositeCanvas("xrender"), xrender_picture_(0), xdbe_back_buffer_(0)
+        {}
 
     virtual ~CompositeCanvasXRender();
 
@@ -50,10 +52,13 @@ 
     void reshape(int width, int height);
 
 private:
+    bool have_xdbe();
+    bool have_xrender();
+    bool ensure_xdbe_back_buffer();
     bool ensure_xrender_picture();
-    bool have_xrender();
 
     Picture xrender_picture_;
+    XdbeBackBuffer xdbe_back_buffer_;
 };
 
 #endif /* COMPOSITE_CANVAS_XRENDER_H_ */