diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2013-04-15 21:40:15 -0400 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2013-04-15 21:40:15 -0400 |
commit | fe344859073b00ff63b0fd0b68c26af6cd96aae3 (patch) | |
tree | 8f7c8d07bdeca9c28030a6c8177dbfdcbfb69a2b /libs/canvas | |
parent | 64c861a79136d0ff4011e98b847606e1015c1ac4 (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.h | 57 | ||||
-rw-r--r-- | libs/canvas/image.cc | 80 | ||||
-rw-r--r-- | libs/canvas/wscript | 3 |
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' |