diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index 19fc15048..4c9b64ecc 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -657,6 +657,8 @@ public: fAtomBufferWorkerResp(), fAtomBufferUiOutTmpData(nullptr), fAtomBufferWorkerInTmpData(nullptr), + fAtomBufferRealtime(nullptr), + fAtomBufferRealtimeSize(0), fEventsIn(), fEventsOut(), fLv2Options(), @@ -858,6 +860,12 @@ public: fAtomBufferWorkerInTmpData = nullptr; } + if (fAtomBufferRealtime != nullptr) + { + std::free(fAtomBufferRealtime); + fAtomBufferRealtime = nullptr; + } + clearBuffers(); } @@ -2131,14 +2139,19 @@ public: CARLA_SAFE_ASSERT_RETURN(tmpRingBuffer.isDataAvailableForReading(),); CARLA_SAFE_ASSERT_RETURN(fExt.worker != nullptr && fExt.worker->work != nullptr,); + const size_t localSize = fAtomBufferWorkerIn.getSize(); + uint8_t* const localData = new uint8_t[localSize]; + LV2_Atom* const localAtom = static_cast(static_cast(localData)); + localAtom->size = localSize; uint32_t portIndex; - const LV2_Atom* atom; - for (; tmpRingBuffer.get(atom, portIndex);) + for (; tmpRingBuffer.get(portIndex, localAtom); localAtom->size = localSize) { - CARLA_SAFE_ASSERT_CONTINUE(atom->type == kUridCarlaAtomWorkerIn); - fExt.worker->work(fHandle, carla_lv2_worker_respond, this, atom->size, LV2_ATOM_BODY_CONST(atom)); + CARLA_SAFE_ASSERT_CONTINUE(localAtom->type == kUridCarlaAtomWorkerIn); + fExt.worker->work(fHandle, carla_lv2_worker_respond, this, localAtom->size, LV2_ATOM_BODY_CONST(localAtom)); } + + delete[] localData; } if (fInlineDisplayNeedsRedraw) @@ -2200,29 +2213,35 @@ public: Lv2AtomRingBuffer tmpRingBuffer(fAtomBufferUiOut, fAtomBufferUiOutTmpData); CARLA_SAFE_ASSERT(tmpRingBuffer.isDataAvailableForReading()); + const size_t localSize = fAtomBufferUiOut.getSize(); + uint8_t* const localData = new uint8_t[localSize]; + LV2_Atom* const localAtom = static_cast(static_cast(localData)); + localAtom->size = localSize; + uint32_t portIndex; - const LV2_Atom* atom; const bool hasPortEvent(fUI.handle != nullptr && fUI.descriptor != nullptr && fUI.descriptor->port_event != nullptr); - for (; tmpRingBuffer.get(atom, portIndex);) + for (; tmpRingBuffer.get(portIndex, localAtom); localAtom->size = localSize) { #ifndef LV2_UIS_ONLY_INPROCESS if (fUI.type == UI::TYPE_BRIDGE) { if (fPipeServer.isPipeRunning()) - fPipeServer.writeLv2AtomMessage(portIndex, atom); + fPipeServer.writeLv2AtomMessage(portIndex, localAtom); } else #endif { if (hasPortEvent && ! fNeedsUiClose) - fUI.descriptor->port_event(fUI.handle, portIndex, lv2_atom_total_size(atom), kUridAtomTransferEvent, atom); + fUI.descriptor->port_event(fUI.handle, portIndex, lv2_atom_total_size(localAtom), kUridAtomTransferEvent, localAtom); } - inspectAtomForParameterChange(atom); + inspectAtomForParameterChange(localAtom); } + + delete[] localData; } #ifndef LV2_UIS_ONLY_INPROCESS @@ -3221,7 +3240,9 @@ public: { fAtomBufferWorkerIn.createBuffer(eventBufferSize); fAtomBufferWorkerResp.createBuffer(eventBufferSize); - fAtomBufferWorkerInTmpData = new uint8_t[fAtomBufferWorkerIn.getSize()]; + fAtomBufferRealtimeSize = fAtomBufferWorkerIn.getSize(); // actual buffer size will be next power of 2 + fAtomBufferRealtime = static_cast(std::malloc(fAtomBufferRealtimeSize)); + fAtomBufferWorkerInTmpData = new uint8_t[fAtomBufferRealtimeSize]; } if (fRdfDescriptor->ParameterCount > 0 || @@ -3869,10 +3890,11 @@ public: { if (fAtomBufferEvIn.isDataAvailableForReading()) { - const LV2_Atom* atom; uint32_t j, portIndex; + LV2_Atom* const atom = fAtomBufferRealtime; + atom->size = fAtomBufferRealtimeSize; - for (; fAtomBufferEvIn.get(atom, portIndex);) + for (; fAtomBufferEvIn.get(portIndex, atom); atom->size = fAtomBufferRealtimeSize) { j = (portIndex < fEventsIn.count) ? portIndex : fEventsIn.ctrlIndex; @@ -4331,10 +4353,11 @@ public: { if (fAtomBufferWorkerResp.isDataAvailableForReading()) { - const LV2_Atom* atom; uint32_t portIndex; + LV2_Atom* const atom = fAtomBufferRealtime; + atom->size = fAtomBufferRealtimeSize; - for (; fAtomBufferWorkerResp.get(atom, portIndex);) + for (; fAtomBufferWorkerResp.get(portIndex, atom); atom->size = fAtomBufferRealtimeSize) { CARLA_SAFE_ASSERT_CONTINUE(atom->type == kUridCarlaAtomWorkerResp); fExt.worker->work_response(fHandle, atom->size, LV2_ATOM_BODY_CONST(atom)); @@ -7472,6 +7495,8 @@ private: Lv2AtomRingBuffer fAtomBufferWorkerResp; uint8_t* fAtomBufferUiOutTmpData; uint8_t* fAtomBufferWorkerInTmpData; + LV2_Atom* fAtomBufferRealtime; + uint32_t fAtomBufferRealtimeSize; CarlaPluginLV2EventData fEventsIn; CarlaPluginLV2EventData fEventsOut; diff --git a/source/utils/Lv2AtomRingBuffer.hpp b/source/utils/Lv2AtomRingBuffer.hpp index ae0575ece..65f2f736b 100644 --- a/source/utils/Lv2AtomRingBuffer.hpp +++ b/source/utils/Lv2AtomRingBuffer.hpp @@ -32,9 +32,6 @@ public: : fMutex(), fHeapBuffer(HeapBuffer_INIT), fNeedsDataDelete(true) -#ifdef CARLA_PROPER_CPP11_SUPPORT - , fRetAtom{{0,0}, {0}} -#endif { carla_zeroStruct(fHeapBuffer); } @@ -43,9 +40,6 @@ public: : fMutex(), fHeapBuffer(HeapBuffer_INIT), fNeedsDataDelete(false) -#ifdef CARLA_PROPER_CPP11_SUPPORT - , fRetAtom{{0,0}, {0}} -#endif { carla_zeroStruct(fHeapBuffer); @@ -120,14 +114,12 @@ public: // ------------------------------------------------------------------- // NOTE: must have been locked before - bool get(const LV2_Atom*& atom, uint32_t& portIndex) noexcept + bool get(uint32_t& portIndex, LV2_Atom* const retAtom) noexcept { - if (const LV2_Atom* const retAtom = readAtom(portIndex)) - { - atom = retAtom; + if (readAtom(portIndex, retAtom)) return true; - } + retAtom->size = retAtom->type = 0; return false; } @@ -155,29 +147,32 @@ public: protected: // ------------------------------------------------------------------- - const LV2_Atom* readAtom(uint32_t& portIndex) noexcept + bool readAtom(uint32_t& portIndex, LV2_Atom* const retAtom) noexcept { - fRetAtom.atom.size = 0; - fRetAtom.atom.type = 0; + const uint32_t maxAtomSize = retAtom->size - sizeof(LV2_Atom); + + LV2_Atom atom = {}; - if (! tryRead(&fRetAtom.atom, sizeof(LV2_Atom))) - return nullptr; - if (fRetAtom.atom.size == 0 || fRetAtom.atom.type == 0) - return nullptr; + if (! tryRead(&atom, sizeof(LV2_Atom))) + return false; + if (atom.size == 0 || atom.type == 0) + return false; - CARLA_SAFE_ASSERT_UINT2_RETURN(fRetAtom.atom.size < kMaxAtomDataSize, fRetAtom.atom.size, kMaxAtomDataSize, nullptr); + CARLA_SAFE_ASSERT_UINT2_RETURN(atom.size < maxAtomSize, atom.size, maxAtomSize, false); int32_t index = -1; if (! tryRead(&index, sizeof(int32_t))) - return nullptr; + return false; if (index < 0) - return nullptr; + return false; - if (! tryRead(fRetAtom.data, fRetAtom.atom.size)) - return nullptr; + if (! tryRead(retAtom + 1, atom.size)) + return false; portIndex = static_cast(index); - return &fRetAtom.atom; + retAtom->size = atom.size; + retAtom->type = atom.type; + return true; } // ------------------------------------------------------------------- @@ -203,13 +198,6 @@ private: HeapBuffer fHeapBuffer; const bool fNeedsDataDelete; - static const std::size_t kMaxAtomDataSize = 32768 - sizeof(LV2_Atom); - - struct RetAtom { - LV2_Atom atom; - char data[kMaxAtomDataSize]; - } fRetAtom; - friend class Lv2AtomQueue; CARLA_PREVENT_VIRTUAL_HEAP_ALLOCATION