summaryrefslogtreecommitdiff
path: root/libs/canvas
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-04-15 21:40:15 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-04-15 21:40:15 -0400
commitfe344859073b00ff63b0fd0b68c26af6cd96aae3 (patch)
tree8f7c8d07bdeca9c28030a6c8177dbfdcbfb69a2b /libs/canvas
parent64c861a79136d0ff4011e98b847606e1015c1ac4 (diff)
add new canvas Image item, with somewhat optimized API for asynchronous, threaded rendering directly into an image buffer suitable for use by cairo as a source surface (currently untested)
Diffstat (limited to 'libs/canvas')
-rw-r--r--libs/canvas/canvas/image.h57
-rw-r--r--libs/canvas/image.cc80
-rw-r--r--libs/canvas/wscript3
3 files changed, 139 insertions, 1 deletions
diff --git a/libs/canvas/canvas/image.h b/libs/canvas/canvas/image.h
new file mode 100644
index 0000000000..e23e9221a3
--- /dev/null
+++ b/libs/canvas/canvas/image.h
@@ -0,0 +1,57 @@
+#ifndef __CANVAS_IMAGE__
+#define __CANVAS_IMAGE__
+
+#include <stdint.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/shared_array.hpp>
+
+#include "canvas/item.h"
+
+namespace ArdourCanvas {
+
+class Image : public Item
+{
+public:
+ Image (Group *, Cairo::Format, int width, int height);
+
+ struct Data {
+ Data (boost::shared_array<uint8_t> d, int w, int h, int s, Cairo::Format fmt)
+ : data (d)
+ , width (w)
+ , height (h)
+ , stride (s)
+ , format (fmt)
+ {}
+
+ boost::shared_array<uint8_t> data;
+ int width;
+ int height;
+ int stride;
+ Cairo::Format format;
+ };
+
+ boost::shared_ptr<Data> get_image ();
+ void put_image (boost::shared_ptr<Data>);
+
+ void render (Rect const &, Cairo::RefPtr<Cairo::Context>) const;
+ void compute_bounding_box () const;
+ XMLNode* get_state () const;
+ void set_state (XMLNode const *);
+
+private:
+ Cairo::Format _format;
+ int _width;
+ int _height;
+ int _data;
+ mutable boost::shared_ptr<Data> _current;
+ boost::shared_ptr<Data> _pending;
+ mutable bool _need_render;
+ mutable Cairo::RefPtr<Cairo::Surface> _surface;
+
+ void accept_data ();
+ PBD::Signal0<void> DataReady;
+ PBD::ScopedConnectionList data_connections;
+};
+
+}
+#endif
diff --git a/libs/canvas/image.cc b/libs/canvas/image.cc
new file mode 100644
index 0000000000..0c7ce6eb28
--- /dev/null
+++ b/libs/canvas/image.cc
@@ -0,0 +1,80 @@
+#include "canvas/image.h"
+
+#include "gtkmm2ext/gui_thread.h"
+
+#include "pbd/xml++.h"
+
+using namespace ArdourCanvas;
+
+Image::Image (Group* group, Cairo::Format fmt, int width, int height)
+ : Item (group)
+ , _format (fmt)
+ , _width (width)
+ , _height (height)
+ , _need_render (false)
+{
+ DataReady.connect (data_connections, MISSING_INVALIDATOR, boost::bind (&Image::accept_data, this), gui_context());
+}
+
+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);
+ }
+
+ _current.reset ();
+
+ context->set_source (_surface, 0, 0);
+ context->rectangle (area.x0, area.y0, area.width(), area.height());
+ context->fill ();
+}
+
+void
+Image::compute_bounding_box () const
+{
+ _bounding_box = boost::optional<Rect> (Rect (0, 0, _width, _height));
+ _bounding_box_dirty = false;
+}
+
+boost::shared_ptr<Image::Data>
+Image::get_image ()
+{
+ 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));
+
+ return d;
+}
+
+void
+Image::put_image (boost::shared_ptr<Data> d)
+{
+ _pending = d;
+ DataReady (); /* EMIT SIGNAL */
+}
+
+void
+Image::accept_data ()
+{
+ /* must be executed in gui thread */
+ _current = _pending;
+ _pending.reset ();
+ _need_render = true;
+}
+
+XMLNode *
+Image::get_state () const
+{
+ /* XXX */
+ return new XMLNode ("Image");
+}
+
+void
+Image::set_state (XMLNode const * /*node*/)
+{
+ /* XXX */
+}
diff --git a/libs/canvas/wscript b/libs/canvas/wscript
index 5b36edcb03..eb1613c117 100644
--- a/libs/canvas/wscript
+++ b/libs/canvas/wscript
@@ -36,6 +36,7 @@ canvas_sources = [
'fill.cc',
'flag.cc',
'group.cc',
+ 'image.cc',
'item_factory.cc',
'line.cc',
'line_set.cc',
@@ -72,7 +73,7 @@ def build(bld):
obj.export_includes = ['.']
obj.includes = ['.']
- obj.uselib = 'SIGCPP CAIROMM GTKMM'
+ obj.uselib = 'SIGCPP CAIROMM GTKMM BOOST'
obj.use = [ 'libpbd', 'libevoral', 'libardour', 'libgtkmm2ext' ]
obj.name = 'libcanvas'
obj.target = 'canvas'