summaryrefslogtreecommitdiffstats
path: root/src/server/PortImpl.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2015-10-24 19:27:39 +0000
committerDavid Robillard <d@drobilla.net>2015-10-24 19:27:39 +0000
commit732bfb33105b4a534bc17caae9a50a1ccfcd7570 (patch)
treebad9715a99f11d17342adaef372361c3697beee9 /src/server/PortImpl.cpp
parentade7143eb2af64fd6743a64ebf1786dd5bbe1092 (diff)
downloadingen-732bfb33105b4a534bc17caae9a50a1ccfcd7570.tar.gz
ingen-732bfb33105b4a534bc17caae9a50a1ccfcd7570.tar.bz2
ingen-732bfb33105b4a534bc17caae9a50a1ccfcd7570.zip
Zero-copy to/from driver ports where possible
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5778 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/server/PortImpl.cpp')
-rw-r--r--src/server/PortImpl.cpp32
1 files changed, 21 insertions, 11 deletions
diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp
index 7119f94c..89b99b4c 100644
--- a/src/server/PortImpl.cpp
+++ b/src/server/PortImpl.cpp
@@ -168,7 +168,7 @@ PortImpl::activate(BufferFactory& bufs)
void
PortImpl::deactivate()
{
- if (is_output()) {
+ if (is_output() && !_is_driver_port) {
for (uint32_t v = 0; v < _poly; ++v) {
if (_voices->at(v).buffer) {
_voices->at(v).buffer->clear();
@@ -302,7 +302,7 @@ bool
PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- if (_parent->path().is_root() ||
+ if (_is_driver_port || _parent->path().is_root() ||
(_type == PortType::ATOM && !_value.is_valid())) {
return false;
}
@@ -385,6 +385,12 @@ PortImpl::recycle_buffers()
}
void
+PortImpl::set_is_driver_port(BufferFactory& bufs)
+{
+ _is_driver_port = true;
+}
+
+void
PortImpl::clear_buffers()
{
switch (_type.id()) {
@@ -442,13 +448,13 @@ PortImpl::monitor(Context& context, bool send_now)
break;
case PortType::ATOM:
if (_buffer_type == _bufs.uris().atom_Sequence) {
- const LV2_Atom* atom = buffer(0)->atom();
- if (buffer(0)->value() && !_monitored) {
- // Value sequence not fully monitored, monitor as control
- key = uris.ingen_value;
- val = ((LV2_Atom_Float*)buffer(0)->value())->body;
- } else if (_monitored && !buffer(0)->empty()) {
- // Monitoring explictly enabled, send everything
+ const LV2_Atom* atom = buffer(0)->get<const LV2_Atom>();
+ const LV2_Atom* value = buffer(0)->value();
+ if (atom->type != _bufs.uris().atom_Sequence) {
+ /* Buffer contents are not actually a Sequence. Probably an
+ uninitialized Chunk, so do nothing. */
+ } else if (_monitored) {
+ /* Sequence explicitly monitored, send everything. */
const LV2_Atom_Sequence* seq = (const LV2_Atom_Sequence*)atom;
LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
context.notify(uris.ingen_activity,
@@ -458,8 +464,12 @@ PortImpl::monitor(Context& context, bool send_now)
ev->body.type,
LV2_ATOM_BODY(&ev->body));
}
- } else if (!buffer(0)->empty()) {
- // Just send activity for blinkenlights
+ } else if (value && value->type == _bufs.uris().atom_Float) {
+ /* Float sequence, monitor as a control. */
+ key = uris.ingen_value;
+ val = ((LV2_Atom_Float*)buffer(0)->value())->body;
+ } else if (atom->size > sizeof(LV2_Atom_Sequence_Body)) {
+ /* General sequence, send activity for blinkenlights. */
const int32_t one = 1;
context.notify(uris.ingen_activity,
context.start(),