gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog backend/render_handler_cairo.cp...


From: Bastiaan Jacques
Subject: [Gnash-commit] gnash ChangeLog backend/render_handler_cairo.cp...
Date: Fri, 20 Jun 2008 07:37:24 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Bastiaan Jacques <bjacques>     08/06/20 07:37:23

Modified files:
        .              : ChangeLog 
        backend        : render_handler_cairo.cpp 
        gui            : gtk_glue_cairo.cpp gtk_glue_cairo.h 

Log message:
                * backend/render_handler_cairo.cpp: Implement set_translation 
and the
                "stage matrix".
                * gui/gtk_glue_cairo.{cpp,h}: Implement rendering to GdkImage, 
which
                implicitly enables XShm support in this GUI. This brings the
                performance I see with cairo to about 70% of GTK-AGG's. Do 
further
                cleanups.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6993&r2=1.6994
http://cvs.savannah.gnu.org/viewcvs/gnash/backend/render_handler_cairo.cpp?cvsroot=gnash&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/gtk_glue_cairo.cpp?cvsroot=gnash&r1=1.16&r2=1.17
http://cvs.savannah.gnu.org/viewcvs/gnash/gui/gtk_glue_cairo.h?cvsroot=gnash&r1=1.17&r2=1.18

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6993
retrieving revision 1.6994
diff -u -b -r1.6993 -r1.6994
--- ChangeLog   20 Jun 2008 06:36:57 -0000      1.6993
+++ ChangeLog   20 Jun 2008 07:37:22 -0000      1.6994
@@ -1,3 +1,12 @@
+2008-06-20 Bastiaan Jacques <address@hidden>
+
+       * backend/render_handler_cairo.cpp: Implement set_translation and the
+       "stage matrix".
+       * gui/gtk_glue_cairo.{cpp,h}: Implement rendering to GdkImage, which
+       implicitly enables XShm support in this GUI. This brings the
+       performance I see with cairo to about 70% of GTK-AGG's. Do further
+       cleanups.
+
 2008-06-20 Zou Lunkai <address@hidden>
 
        * backend/render_handler_agg_style.h,

Index: backend/render_handler_cairo.cpp
===================================================================
RCS file: /sources/gnash/gnash/backend/render_handler_cairo.cpp,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- backend/render_handler_cairo.cpp    15 Jun 2008 07:47:16 -0000      1.47
+++ backend/render_handler_cairo.cpp    20 Jun 2008 07:37:23 -0000      1.48
@@ -190,10 +190,8 @@
     : _video_bufsize(0),
       _drawing_mask(false)
   {    
-       cairo_surface_t* dummy_surface = cairo_image_surface_create(
-                                            CAIRO_FORMAT_A8, 1, 1);
-         _cr = cairo_create(dummy_surface);
-         cairo_surface_destroy(dummy_surface);
+    _cr = cairo_create(NULL);
+    cairo_matrix_init_scale(&_stage_mat, 1/20.0f, 1/20.0f);
   }
   
   ~render_handler_cairo()
@@ -294,13 +292,20 @@
   }
 
   
-  // FIXME
   geometry::Range2d<int>
   world_to_pixel(const rect& worldbounds)
 {
-  // TODO: verify this is correct
-  geometry::Range2d<int> ret(worldbounds.getRange());
-  ret.scale(1.0/20.0); // twips to pixels
+  double xmin = worldbounds.get_x_min(),
+         ymin = worldbounds.get_y_min(),
+         xmax = worldbounds.get_x_max(),
+         ymax = worldbounds.get_y_max();
+
+  cairo_matrix_transform_point(&_stage_mat, &xmin, &ymin);
+  cairo_matrix_transform_point(&_stage_mat, &xmax, &ymax);
+  
+
+  geometry::Range2d<int> ret(xmin, ymin, xmax, ymax);
+
   return ret;
 }
 
@@ -308,8 +313,15 @@
   point 
   pixel_to_world(int x, int y)
   {
-    // TODO: verify this is correct
-    return point(PIXELS_TO_TWIPS(x), PIXELS_TO_TWIPS(y));
+    cairo_matrix_t inv_stage = _stage_mat;
+    cairo_matrix_invert(&inv_stage);
+
+    double xconv = x;
+    double yconv = y;
+    
+    cairo_matrix_transform_point(&inv_stage, &xconv, &yconv);
+
+    return point(xconv, yconv);
   }
   
   void
@@ -357,9 +369,6 @@
     int viewport_width, int viewport_height,
     float x0, float x1, float y0, float y1)
   {
-    float display_width  = fabsf(x1 - x0);
-    float display_height = fabsf(y1 - y0);
-
     cairo_identity_matrix(_cr);
 
     cairo_save(_cr);
@@ -368,9 +377,7 @@
       set_color(bg_color);
     }
 
-    cairo_scale(_cr, viewport_width / display_width,
-                     viewport_height / display_height);
-    cairo_translate(_cr, x0, y0);
+    cairo_set_matrix(_cr, &_stage_mat);
 
     for (size_t rno=0; rno < _invalidated_ranges.size(); rno++) {
     
@@ -379,8 +386,10 @@
         continue;
       }
       if (range.isWorld()) {
-        cairo_rectangle(_cr, x0, y0, display_width, display_height);
-        break;
+        cairo_paint(_cr);
+        // reset any rectangles that might have been added to the path...
+        cairo_new_path(_cr);
+        return;
       }
 
       double x = range.getMinX(),
@@ -405,6 +414,17 @@
     cairo_restore(_cr);
   }
     
+  void set_scale(float xscale, float yscale)
+  {
+    _stage_mat.xx = xscale / 20;
+    _stage_mat.yy = xscale / 20;
+  }
+
+  virtual void set_translation(float xoff, float yoff) {
+    _stage_mat.x0 = xoff;
+    _stage_mat.y0 = yoff;
+  }
+    
   virtual void  draw_line_strip(const boost::int16_t coords[], int 
vertex_count,
       const rgba& color, const matrix& mat)
   {
@@ -1049,6 +1069,7 @@
   size_t _video_bufsize;
   bool _drawing_mask;
   InvalidatedRanges _invalidated_ranges;
+  cairo_matrix_t _stage_mat;
     
 }; // class render_handler_cairo
 

Index: gui/gtk_glue_cairo.cpp
===================================================================
RCS file: /sources/gnash/gnash/gui/gtk_glue_cairo.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -b -r1.16 -r1.17
--- gui/gtk_glue_cairo.cpp      13 Mar 2008 06:43:55 -0000      1.16
+++ gui/gtk_glue_cairo.cpp      20 Jun 2008 07:37:23 -0000      1.17
@@ -27,16 +27,18 @@
 {
 
 GtkCairoGlue::GtkCairoGlue()
+  : _image(0),
+    _drawing_area(0),
+    _cairo_handle(0),
+    _cairo_offscreen(0)
 {
-    _drawing_area = 0;
-    _cairo_handle = 0;
-    _cairo_offscreen = 0;
 }
 
 GtkCairoGlue::~GtkCairoGlue()
 {
     if (_cairo_handle)  cairo_destroy(_cairo_handle);
     if (_cairo_offscreen)  cairo_destroy(_cairo_offscreen);
+    if (_image) gdk_image_destroy(_image);
 }
 
 bool
@@ -49,8 +51,6 @@
 GtkCairoGlue::prepDrawingArea(GtkWidget *drawing_area)
 {
     _drawing_area = drawing_area;
-    assert(_drawing_area);
-    assert(_drawing_area->window);
     gtk_widget_set_double_buffered(_drawing_area, FALSE);
 }
 
@@ -69,6 +69,21 @@
       return;
     }
 
+    const int& x = minx;
+    const int& y = miny;
+    int width = maxx - minx;
+    int height = maxy - miny;
+
+    if (_image) {
+      // Using GdkImage for our image buffer, use GdkRgb (potentially shm).
+      GdkGC* gc = gdk_gc_new(_drawing_area->window);
+
+      gdk_draw_image(_drawing_area->window, gc, _image, x, y, x, y, width,
+                     height);
+      gdk_gc_unref(gc);
+      return;
+    }
+
     cairo_save(_cairo_offscreen);
 
     cairo_rectangle(_cairo_offscreen, minx, miny, maxx - minx, maxy - miny);
@@ -90,24 +105,109 @@
     cairo_paint(_cairo_handle);
 }
 
+bool
+cairoFormatFromVisual(const GdkVisual* visual, cairo_format_t* format /*out*/)
+{
+  switch(visual->depth) {
+    case 24:
+      *format = CAIRO_FORMAT_RGB24;
+      break;
+    case 36:
+      *format = CAIRO_FORMAT_ARGB32;
+      break;
+    default:
+      format = NULL;
+      return false;
+  }
+  return true;
+}
+
+cairo_surface_t*
+GtkCairoGlue::createGdkImageSurface(const int& width, const int& height)
+{
+  GdkVisual* visual = gdk_drawable_get_visual(_drawing_area->window);
+  cairo_format_t format;
+
+  if (!cairoFormatFromVisual(visual, &format)) {
+    return NULL;
+  }
+
+  _image = gdk_image_new (GDK_IMAGE_FASTEST, visual, width, height);
+  if (!_image) {
+    return NULL;
+  }
+
+  cairo_surface_t* surface =
+    cairo_image_surface_create_for_data ((unsigned char *)_image->mem,
+      format, _image->width, _image->height, _image->bpl);
+
+  if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+    cairo_surface_destroy(surface);
+    gdk_image_destroy(_image);
+    _image = 0;
+    return NULL;
+  }
+
+  return surface;
+}
+
+cairo_surface_t*
+GtkCairoGlue::createSimilarSurface(const int& width, const int& height)
+{
+  cairo_surface_t* target = cairo_get_target(_cairo_handle);
+
+  cairo_surface_t* surface = cairo_surface_create_similar(target,
+    cairo_surface_get_content(target), width, height);
+
+  if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+    cairo_surface_destroy(surface);
+    return NULL;
+  }
+  return surface;
+}
+
+cairo_surface_t*
+GtkCairoGlue::createMemorySurface(const int& width, const int& height)
+{
+  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
+                                                        width, height);
+
+  if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
+    cairo_surface_destroy(surface);
+    return NULL;
+  }
+  return surface;
+}
+
 void
 GtkCairoGlue::configure(GtkWidget *const /*widget*/,
     GdkEventConfigure *const event)
 {
     if (!_drawing_area)  return;
 
-    // Create cairo handle for output window
+    if (_image) {
+      gdk_image_destroy(_image);
+      _image = 0;
+    }
+
+    cairo_surface_t* surface = createGdkImageSurface(event->width, 
event->height);
+
+    if (!surface) {
+
+      if (!_cairo_handle) {
     _cairo_handle = gdk_cairo_create(_drawing_area->window);
+      }
 
-    cairo_surface_t* target = cairo_get_target(_cairo_handle);
+      surface = createMemorySurface(event->width, event->height);
+    }
 
-    cairo_surface_t* surface = cairo_surface_create_similar(target,
-      cairo_surface_get_content(target), event->width, event->height);
+    if (!surface) {
+      surface = createSimilarSurface(event->width, event->height);
+    }
 
-    if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
-      // fallback image surface
-      surface = cairo_image_surface_create(
-        CAIRO_FORMAT_ARGB32, event->width, event->height);
+    if (!surface) {
+      log_error("Cairo: failed to create a rendering buffer!");
+      return;
     }
 
     _cairo_offscreen = cairo_create(surface);
@@ -116,7 +216,5 @@
     renderer::cairo::set_context(_renderer, _cairo_offscreen);
 }
 
-
-
 } // namespace gnash
 

Index: gui/gtk_glue_cairo.h
===================================================================
RCS file: /sources/gnash/gnash/gui/gtk_glue_cairo.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- gui/gtk_glue_cairo.h        15 Jun 2008 07:47:17 -0000      1.17
+++ gui/gtk_glue_cairo.h        20 Jun 2008 07:37:23 -0000      1.18
@@ -38,9 +38,14 @@
     void render(int minx, int miny, int maxx, int maxy);
     void configure(GtkWidget *const widget, GdkEventConfigure *const event);
   private:
+    cairo_surface_t* createGdkImageSurface(const int& width, const int& 
height);
+    cairo_surface_t* createSimilarSurface(const int& width, const int& height);
+    cairo_surface_t* createMemorySurface(const int& width, const int& height);
+
     cairo_t     *_cairo_handle;
     cairo_t     *_cairo_offscreen;
     render_handler* _renderer;
+    GdkImage*       _image;
 };
 
 } // namespace gnash




reply via email to

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