[Top][All Lists]
[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
- [Gnash-dev] Cairo backend cleanup,
Timothy Lee <=