diff options
| author | Uli Schlachter <psychon@znc.in> | 2017-06-26 08:31:45 +0000 |
|---|---|---|
| committer | Uli Schlachter <psychon@znc.in> | 2017-07-01 09:41:10 +0000 |
| commit | 6ef4b7cae493468892242aec8cdd3a5fb4e26d0e (patch) | |
| tree | 0484375b765f602c612554d7c2c74da51ffca355 | |
| parent | SPCanvas: Use a similar image for _backing_store (diff) | |
| download | inkscape-6ef4b7cae493468892242aec8cdd3a5fb4e26d0e.tar.gz inkscape-6ef4b7cae493468892242aec8cdd3a5fb4e26d0e.zip | |
SPCanvas::paintSingleBuffer: Draw directly to _backing_store
Before this commit, this function creates a new cairo image surface,
draws the tile that it was told to redraw to this buffer and then uses
cairo to copy the drawn data at the right position inside of
_backing_store. Thus, the drawn data was copied around at least once.
This commit changes the code so that it draws directly to
_backing_store: We get the information from _backing_store and then
create a new image surface from this that covers just the part that we
should redraw. Thus, one copy of the data is avoided.
Signed-off-by: Uli Schlachter <psychon@znc.in>
| -rw-r--r-- | src/display/sp-canvas.cpp | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 196a14069..8857b8c68 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1525,8 +1525,23 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect buf.canvas_rect = canvas_rect; buf.is_empty = true; - // create temporary surface - cairo_surface_t *imgs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, paint_rect.width(), paint_rect.height()); + // Make sure the following code does not go outside of _backing_store's data + assert(cairo_image_surface_get_format(_backing_store) == CAIRO_FORMAT_ARGB32); + assert(paint_rect.left() - _x0 >= 0); + assert(paint_rect.top() - _y0 >= 0); + assert(paint_rect.right() - _x0 <= cairo_image_surface_get_width(_backing_store)); + assert(paint_rect.bottom() - _y0 <= cairo_image_surface_get_height(_backing_store)); + + // Create a temporary surface that draws directly to _backing_store + cairo_surface_flush(_backing_store); + unsigned char *data = cairo_image_surface_get_data(_backing_store); + int stride = cairo_image_surface_get_stride(_backing_store); + // Move to the right row + data += stride * (paint_rect.top() - _y0); + // Move to the right pixel inside of that row + data += 4 * (paint_rect.left() - _x0); + cairo_surface_t *imgs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, + paint_rect.width(), paint_rect.height(), stride); buf.ct = cairo_create(imgs); cairo_save(buf.ct); @@ -1567,16 +1582,7 @@ void SPCanvas::paintSingleBuffer(Geom::IntRect const &paint_rect, Geom::IntRect } #endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - //cairo_t *xct = gdk_cairo_create(gtk_widget_get_window (widget)); - cairo_t *xct = cairo_create(_backing_store); - cairo_translate(xct, paint_rect.left() - _x0, paint_rect.top() - _y0); - cairo_rectangle(xct, 0, 0, paint_rect.width(), paint_rect.height()); - cairo_clip(xct); - cairo_set_source_surface(xct, imgs, 0, 0); - cairo_set_operator(xct, CAIRO_OPERATOR_SOURCE); - cairo_paint(xct); - cairo_destroy(xct); - cairo_surface_destroy(imgs); + cairo_surface_mark_dirty(_backing_store); // Mark the painted rectangle clean markRect(paint_rect, 0); |
