a couple of debug output statements to help diagnose a crash
[ardour.git] / libs / canvas / image.cc
index 22ef042cfba542816b73714b04fe35c107fa1663..46cadd0d1cc32008b3c0482725715970c11df2bc 100644 (file)
 
 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<Cairo::Context> 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<Rect> 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::Data>
-Image::get_image ()
+Image::get_image (bool allocate_data)
 {
-       int stride = Cairo::ImageSurface::format_stride_for_width (_format, _width);
-       boost::shared_ptr<Data> d (new Data (boost::shared_array<uint8_t> (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<Data> d (new Data (new uint8_t[stride*_height], _width, _height, stride, _format));
+               return d;
+       } else {
+               boost::shared_ptr<Data> d (new Data (NULL, _width, _height, stride, _format));
+               return d;
+       }
 }
 
 void
 Image::put_image (boost::shared_ptr<Data> 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
 }