X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fcanvas%2Fimage.cc;h=46cadd0d1cc32008b3c0482725715970c11df2bc;hb=8671e109fcc5089226da1e539bc8b7327b2cb5bf;hp=22ef042cfba542816b73714b04fe35c107fa1663;hpb=37dd7e952bd084cd35a4c4f67949890ee3e7c152;p=ardour.git diff --git a/libs/canvas/image.cc b/libs/canvas/image.cc index 22ef042cfb..46cadd0d1c 100644 --- a/libs/canvas/image.cc +++ b/libs/canvas/image.cc @@ -22,8 +22,18 @@ using namespace ArdourCanvas; -Image::Image (Group* group, Cairo::Format fmt, int width, int height) - : Item (group) +Image::Image (Canvas* canvas, Cairo::Format fmt, int width, int height) + : Item (canvas) + , _format (fmt) + , _width (width) + , _height (height) + , _need_render (false) +{ + DataReady.connect (data_connections, MISSING_INVALIDATOR, boost::bind (&Image::accept_data, this), gui_context()); +} + +Image::Image (Item* parent, Cairo::Format fmt, int width, int height) + : Item (parent) , _format (fmt) , _width (width) , _height (height) @@ -35,19 +45,23 @@ Image::Image (Group* group, Cairo::Format fmt, int width, int height) void Image::render (Rect const& area, Cairo::RefPtr context) const { - if (_current) { - _surface = Cairo::ImageSurface::create (_current->data.get(), - _current->format, - _current->width, - _current->height, - _current->stride); + if (_need_render && _pending) { + _surface = Cairo::ImageSurface::create (_pending->data, + _pending->format, + _pending->width, + _pending->height, + _pending->stride); + _current = _pending; + } + + Rect self = item_to_window (Rect (0, 0, _width, _height)); + boost::optional draw = self.intersection (area); + + if (_surface && draw) { + context->set_source (_surface, self.x0, self.y0); + context->rectangle (draw->x0, draw->y0, draw->width(), draw->height()); + context->fill (); } - - _current.reset (); - - context->set_source (_surface, 0, 0); - context->rectangle (area.x0, area.y0, area.width(), area.height()); - context->fill (); } void @@ -58,17 +72,25 @@ Image::compute_bounding_box () const } boost::shared_ptr -Image::get_image () +Image::get_image (bool allocate_data) { - int stride = Cairo::ImageSurface::format_stride_for_width (_format, _width); - boost::shared_ptr d (new Data (boost::shared_array (new uint8_t[stride*_height]), _width, _height, stride, _format)); + /* can be called by any thread */ - return d; + int stride = Cairo::ImageSurface::format_stride_for_width (_format, _width); + if (allocate_data) { + boost::shared_ptr d (new Data (new uint8_t[stride*_height], _width, _height, stride, _format)); + return d; + } else { + boost::shared_ptr d (new Data (NULL, _width, _height, stride, _format)); + return d; + } } void Image::put_image (boost::shared_ptr d) { + /* can be called by any thread */ + _pending = d; DataReady (); /* EMIT SIGNAL */ } @@ -77,8 +99,9 @@ void Image::accept_data () { /* must be executed in gui thread */ - _current = _pending; - _pending.reset (); + + begin_change (); _need_render = true; + end_change (); // notify canvas that we need redrawing }