gnash-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-dev] Cairo backend cleanup


From: Timothy Lee
Subject: [Gnash-dev] Cairo backend cleanup
Date: Sat, 09 Dec 2006 10:17:34 +0800
User-agent: Thunderbird 1.5.0.7 (X11/20060916)

Dear all,

I've done some cleanup on the Cairo backend. The 1st patch fixes configure.ac to detect the Cairo library when the Cairo backend is enabled (and also when GTK GUI is being used).

The 2nd patch makes the following changes to the Cairo backend:

   * Removes Xlib-specifiic header and test code.
   * Fixes viewport clipping problem.
   * Removes offscreen buffer and renders directly through Cairo.  This
     opens the possibility of using OpenGL/Glitz acceleration in Cairo
     by calling set_handle() with different types of handles.
   * An added benefit of this change is that the bitmap created by the
     SDL glue now becomes the direct target of Cairo's rendering,
     without the redundant offscreen buffer in-between.

The 3rd patch modifies the GTK glue to work with the updated backend:

   * The GTK glue now manages an offscreen bitmap for the backend to
     render on.
   * Window resizes now causes the offscreen bitmap to be resized as well.

Regards,
Timothy
diff -p -u -b -r1.223 configure.ac
--- configure.ac        1 Dec 2006 15:38:18 -0000       1.223
+++ configure.ac        9 Dec 2006 01:42:10 -0000
@@ -572,9 +572,6 @@ if test x"$ghelp" = x"yes" ; then
                AC_MSG_WARN([You need to install scrollkeeper for gnome help])
        fi
 fi
-
-dnl Using GTK always needs Cairo, even with OpenGL
-       GNASH_PKG_FIND(cairo, [cairo.h], [cairo render library], cairo_status)
 fi
 AM_CONDITIONAL(GHELP, [test x$ghelp = xyes])
 AM_CONDITIONAL(HAVE_AGG, [test x${ac_cv_path_agg_lib} != x])
@@ -673,6 +670,11 @@ if test x$renderer = xagg; then
 GNASH_PATH_AGG
 fi
 
+if test x$renderer = xcairo -o x$gui = xgtk; then
+  dnl Cairo renderer and GTK gui always need Cairo
+  GNASH_PKG_FIND(cairo, [cairo.h], [cairo render library], cairo_status)
+fi
+
 GNASH_DOCBOOK
 AM_CONDITIONAL(DOCBOOK, test x$docbook = xyes)
 
diff -p -u -b -r1.18 render_handler_cairo.cpp
--- backend/render_handler_cairo.cpp    5 Dec 2006 14:26:09 -0000       1.18
+++ backend/render_handler_cairo.cpp    9 Dec 2006 02:12:19 -0000
@@ -7,8 +7,6 @@
 
 
 #include <cairo/cairo.h>
-#include <cairo/cairo-xlib.h>
-//#include "gnash.h"
 #include "render_handler.h"
 #include "render_handler_tri.h"
 #include "types.h"
@@ -18,15 +16,13 @@
 #include "tu_config.h"
 #include "log.h"
 
-//using namespace gnash;
 
 namespace gnash {
 namespace renderer {
 namespace cairo {
 
-static cairo_t* g_cr_win = 0;
+static cairo_t* g_cr_output = 0;
 static cairo_t* g_cr = 0;
-Window g_cairo_xwin = 0;
 
 // bitmap_info_cairo declaration
 class bitmap_info_cairo : public gnash::bitmap_info
@@ -55,7 +51,6 @@ class render_handler_cairo : public gnas
 {
 public:
     // Some renderer state.
-    cairo_t*         m_cr_offscreen;
     cairo_t*         m_cr_mask;
     int              m_view_width;
     int              m_view_height;
@@ -102,7 +97,6 @@ public:
        // Push our style into cairo.
        void apply(/*const matrix& current_matrix*/) const
        {
-//         GNASH_REPORT_FUNCTION;
            assert(m_mode != INVALID);
            
            if (m_mode == COLOR)
@@ -282,7 +276,7 @@ public:
 
     // Constructor
     render_handler_cairo() :
-       m_cr_offscreen(0), m_cr_mask(0), m_view_width(0), m_view_height(0)
+       m_cr_mask(0), m_view_width(0), m_view_height(0)
     {
     }
 
@@ -290,8 +284,6 @@ public:
     ~render_handler_cairo()
     {
        if (m_cr_mask)  cairo_destroy(m_cr_mask);
-       if (m_cr_offscreen)  cairo_destroy(m_cr_offscreen);
-       if (g_cr == m_cr_offscreen)  g_cr = 0;
     }
 
     void       begin_display(
@@ -312,86 +304,35 @@ public:
        // coordinates of the movie that correspond to the viewport
        // bounds.
        {
-//         GNASH_REPORT_FUNCTION;
+           assert(g_cr_output);
+           g_cr = g_cr_output;
+
            m_display_width  = fabsf(x1 - x0);
            m_display_height = fabsf(y1 - y0);
            m_view_width  = viewport_width;
            m_view_height = viewport_height;
 
-           // Destroy offscreen surface if size is different
-           if (m_cr_offscreen)
-           {
-               if (m_view_width != viewport_width ||
-                   m_view_height != viewport_height)
-               {
-                   cairo_destroy(m_cr_offscreen);
-                   m_cr_offscreen = 0;
-               }
-           }
-
-           // Create offscreen surface if necessary
-           if (!m_cr_offscreen)
-           {
-               cairo_surface_t* offscreen = cairo_image_surface_create(
-                   CAIRO_FORMAT_RGB24, viewport_width, viewport_height);
-               m_cr_offscreen = cairo_create(offscreen);
-               cairo_surface_destroy(offscreen);
-               g_cr = m_cr_offscreen;
-           }
-
            cairo_identity_matrix(g_cr);
+           cairo_rectangle(g_cr, x0, y0, m_display_width, m_display_height);
+           cairo_clip(g_cr);
            cairo_scale(g_cr, viewport_width / m_display_width,
                viewport_height / m_display_height);
            cairo_translate(g_cr, x0, y0);
 
-           cairo_rectangle(g_cr, x0, y0, m_display_width, m_display_height);
-           cairo_clip(g_cr);
-
            // Clear the background, if background color has alpha > 0.
            if (background_color.m_a > 0)
                {
                    // Draw a big quad.
                    apply_color(background_color);
-                   cairo_rectangle(g_cr, x0, y0, x1, y1);
+                   cairo_rectangle(g_cr, x0, y0, x1 - x0, y1 - y0);
                    cairo_fill(g_cr);
                }
        }
 
 
     void       end_display()
-       // Clean up after rendering a frame.  Client program is still
-       // responsible for calling glSwapBuffers() or whatever.
+       // Clean up after rendering a frame.
        {
-//         GNASH_REPORT_FUNCTION;
-#if 0
-           // This creates a new window for output, which may be useful for
-           // debugging purposes, but we ordinarily want to use an existing 
one.
-
-           if (!g_cr_win)
-           {
-               Display* xdisp = XOpenDisplay(0);
-               Screen*  screen = XDefaultScreenOfDisplay(xdisp);
-               Visual*  visual = DefaultVisual(xdisp, DefaultScreen(xdisp));
-               int      screen_num = XScreenNumberOfScreen(screen);
-               Window   xwin = XCreateWindow(xdisp,
-                   RootWindow(xdisp, screen_num),
-                   0, 0, m_view_width, m_view_height, 0,
-                   CopyFromParent, CopyFromParent, CopyFromParent, 0, 0);
-               XMapWindow(xdisp, xwin);
-               XRaiseWindow(xdisp, xwin);
-               XSync(xdisp, False);
-               cairo_surface_t* surface = cairo_xlib_surface_create(
-                   xdisp, xwin, visual, m_view_width, m_view_height);
-               g_cr_win = cairo_create(surface);
-           }
-#endif
-
-           assert(g_cr_win);
-
-           // Blit offscreen image onto output window 
-           cairo_surface_t* offscreen = cairo_get_target(m_cr_offscreen);
-           cairo_set_source_surface(g_cr_win, offscreen, 0, 0);
-           cairo_paint(g_cr_win);
        }
 
 
@@ -476,7 +417,6 @@ public:
 
     void       draw_mesh_strip(const void* coords, int vertex_count)
        {
-//         GNASH_REPORT_FUNCTION;
            // Set up current style.
            m_current_styles[LEFT_STYLE].apply();
 
@@ -519,7 +459,6 @@ public:
     void       draw_line_strip(const void* coords, int vertex_count)
        // Draw the line strip formed by the sequence of points.
        {
-//         GNASH_REPORT_FUNCTION;
            // Set up current style.
            m_current_styles[LINE_STYLE].apply();
 
@@ -549,7 +488,6 @@ public:
        //
        // Intended for textured glyph rendering.
        {
-//         GNASH_REPORT_FUNCTION;
             gnash::bitmap_info* nonconst_binfo = 
const_cast<gnash::bitmap_info*>(binfo);
            bitmap_info_cairo* bi = 
dynamic_cast<bitmap_info_cairo*>(nonconst_binfo);
            assert(bi);
@@ -591,7 +529,6 @@ public:
        
     void begin_submit_mask()
        {
-//         GNASH_REPORT_FUNCTION;
            if (m_cr_mask)  cairo_destroy(m_cr_mask);
            cairo_surface_t* mask = cairo_image_surface_create(
                CAIRO_FORMAT_A8, m_view_width, m_view_height);
@@ -604,8 +541,8 @@ public:
        
     void end_submit_mask()
        {            
-           // Finished the mask.  Now draw to offscreen buffer
-           g_cr = m_cr_offscreen;
+           // Finished with the mask.  Now draw to output
+           g_cr = g_cr_output;
        }
        
     void disable_mask()
@@ -615,7 +552,9 @@ public:
            {
                cairo_destroy(m_cr_mask);
                m_cr_mask = 0;
-               g_cr = m_cr_offscreen;
+
+               // Prepare to draw to output
+               g_cr = g_cr_output;
            }
        }
        
@@ -637,7 +576,6 @@ public:
 bitmap_info_cairo::bitmap_info_cairo()
 // Make a placeholder bitmap_info.  Must be filled in later before using.
 {
-//    GNASH_REPORT_FUNCTION;
     m_buffer = 0;
     m_image = 0;
     m_original_width = 0;
@@ -649,7 +587,6 @@ bitmap_info_cairo::bitmap_info_cairo(int
 // Initialize this bitmap_info to an alpha image
 // containing the specified data (1 byte per texel).
 {
-//    GNASH_REPORT_FUNCTION;
     assert(width > 0);
     assert(height > 0);
     assert(data);
@@ -673,7 +610,6 @@ bitmap_info_cairo::bitmap_info_cairo(int
 bitmap_info_cairo::bitmap_info_cairo(image::rgb* im)
 // Version of the constructor that takes an RGB image.
 {
-//    GNASH_REPORT_FUNCTION;
     assert(im);
 
     // Allocate output buffer
@@ -706,7 +642,6 @@ bitmap_info_cairo::bitmap_info_cairo(ima
 bitmap_info_cairo::bitmap_info_cairo(image::rgba* im)
 // Version of the constructor that takes an image with alpha.
 {
-//    GNASH_REPORT_FUNCTION;
     assert(im);
 
     // Allocate output buffer
@@ -739,8 +674,6 @@ DSOEXPORT render_handler*
 create_handler()
 // Factory.
 {
-       //    GNASH_REPORT_FUNCTION;
-       //g_cr_win = (cairo_t*) cairohandle;
        return new render_handler_cairo();
 }
 
@@ -748,8 +681,7 @@ DSOEXPORT void
 set_handle(cairo_t* handle)
 {
        assert(handle);
-       assert(!g_cr_win);
-       g_cr_win = handle;
+    g_cr_output = handle;
 }
 
 
diff -p -u -b -r1.7 gtk_glue_cairo.cpp
--- gui/gtk_glue_cairo.cpp      29 Oct 2006 18:34:10 -0000      1.7
+++ gui/gtk_glue_cairo.cpp      9 Dec 2006 02:12:31 -0000
@@ -30,11 +30,15 @@ namespace gnash
 
 GtkCairoGlue::GtkCairoGlue()
 {
+    _drawing_area = 0;
+    _cairo_handle = 0;
+    _cairo_offscreen = 0;
 }
 
 GtkCairoGlue::~GtkCairoGlue()
 {
-    cairo_destroy(_cairo_handle);
+    if (_cairo_handle)  cairo_destroy(_cairo_handle);
+    if (_cairo_offscreen)  cairo_destroy(_cairo_offscreen);
 }
 
 bool
@@ -49,27 +53,44 @@ GtkCairoGlue::prepDrawingArea(GtkWidget 
     _drawing_area = drawing_area;
     assert(_drawing_area);
     assert(_drawing_area->window);
-    _cairo_handle = gdk_cairo_create (_drawing_area->window);
-    assert(_cairo_handle);
-    renderer::cairo::set_handle(_cairo_handle);
 }
 
 render_handler*
 GtkCairoGlue::createRenderHandler()
 {
-    //_cairo_handle = gdk_cairo_create (_drawing_area->window);
-    //return create_render_handler_cairo((void*)_cairo_handle);
     return renderer::cairo::create_handler();
 }
 
 void
 GtkCairoGlue::render()
 {
+    if (!_cairo_offscreen)  return;
+
+    // Blit offscreen image onto output window 
+    cairo_set_source_surface(_cairo_handle,
+       cairo_get_target(_cairo_offscreen), 0, 0);
+    cairo_paint(_cairo_handle);
 }
 
 void
-GtkCairoGlue::configure(GtkWidget *const /*widget*/, GdkEventConfigure *const 
/*event*/)
+GtkCairoGlue::configure(GtkWidget *const /*widget*/,
+    GdkEventConfigure *const event)
 {
+    if (!_drawing_area)  return;
+
+    // Create cairo handle for output window
+    if (_cairo_handle)  cairo_destroy(_cairo_handle);
+    _cairo_handle = gdk_cairo_create(_drawing_area->window);
+    assert(_cairo_handle);
+
+    // Create offscreen image for rendering
+    if (_cairo_offscreen)  cairo_destroy(_cairo_offscreen);
+    cairo_surface_t* surface = cairo_image_surface_create(
+       CAIRO_FORMAT_RGB24, event->width, event->height);
+    _cairo_offscreen = cairo_create(surface);
+    assert(_cairo_offscreen);
+    cairo_surface_destroy(surface);
+    renderer::cairo::set_handle(_cairo_offscreen);
 }
 
 
diff -p -u -b -r1.7 gtk_glue_cairo.h
--- gui/gtk_glue_cairo.h        6 Dec 2006 10:58:34 -0000       1.7
+++ gui/gtk_glue_cairo.h        9 Dec 2006 02:12:31 -0000
@@ -41,6 +41,7 @@ class GtkCairoGlue : public GtkGlue
     void configure(GtkWidget *const widget, GdkEventConfigure *const event);
   private:
     cairo_t     *_cairo_handle;
+    cairo_t     *_cairo_offscreen;
 };
 
 } // namespace gnash

reply via email to

[Prev in Thread] Current Thread [Next in Thread]