From ca0ae9c120ec8a343f6cc6e3bb4fd6cf8c86352b Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 19 Oct 2011 02:47:11 +0200 Subject: [PATCH] stubbed relevant parts of BufferProvider and OutputSlot --- src/proc/engine/buffer-provider.hpp | 2 + src/proc/engine/buffhandle.hpp | 2 +- src/proc/engine/bufftable.hpp | 186 ++++++++---------- .../engine/diagnostic-buffer-provider.cpp | 15 ++ .../engine/diagnostic-buffer-provider.hpp | 10 +- src/proc/play/output-slot.hpp | 1 + .../engine/buffer-provider-protocol-test.cpp | 19 +- .../proc/play/diagnostic-output-slot.hpp | 62 ++++++ .../proc/play/output-slot-protocol-test.cpp | 19 +- 9 files changed, 195 insertions(+), 121 deletions(-) rename {src => tests/components}/proc/play/diagnostic-output-slot.hpp (55%) diff --git a/src/proc/engine/buffer-provider.hpp b/src/proc/engine/buffer-provider.hpp index 6f025a1c8..ca6382d66 100644 --- a/src/proc/engine/buffer-provider.hpp +++ b/src/proc/engine/buffer-provider.hpp @@ -80,6 +80,8 @@ namespace engine { virtual ~BufferProvider(); ///< this is an interface + virtual uint announce (uint count, BufferDescriptor const&) =0; + virtual BuffHandle lockBufferFor (BufferDescriptor const&) =0; virtual void releaseBuffer (BuffHandle const&) =0; diff --git a/src/proc/engine/buffhandle.hpp b/src/proc/engine/buffhandle.hpp index df7018e05..14845a849 100644 --- a/src/proc/engine/buffhandle.hpp +++ b/src/proc/engine/buffhandle.hpp @@ -185,7 +185,7 @@ namespace engine { } - /** convenience shortcuts: access the buffer contents in a typesafe fashion. + /** convenience shortcut: access the buffer contents in a typesafe fashion. * This is equivalent to a plain dereferentiation with additional metadata check * @throw error::Logic in case of type mismatch \c LUMIERA_ERROR_WRONG_TYPE */ diff --git a/src/proc/engine/bufftable.hpp b/src/proc/engine/bufftable.hpp index ac5773e24..00738cd64 100644 --- a/src/proc/engine/bufftable.hpp +++ b/src/proc/engine/bufftable.hpp @@ -28,6 +28,7 @@ #include "lib/error.hpp" #include "proc/engine/buffhandle.hpp" #include "proc/engine/procnode.hpp" +#include "lib/iter-adapter.hpp" #include #include @@ -57,122 +58,99 @@ namespace engine { { typedef BuffHandle * PHa; typedef BuffHandle::PBuff * PBu; - typedef pair Chunk; - PHa outHandle; - PHa inHandle; - PBu outBuff; - PBu inBuff; - }; - - - class BuffTableStorage - { - /////////////////////////////////////////////////////////////////////////TICKET #826 need to be reworked entirely - /** just a placeholder to decouple the existing code - * from the reworked BuffHandle logic. The existing - * code in turn will be reworked rather fundamentally - */ - struct BuffHaXXXX - : BuffHandle + struct StorageChunk + { }; + + template + struct Storage { - BuffHaXXXX() : BuffHandle(just_satisfy_the_compiler()) { /* wont work ever */ } - static BufferDescriptor const& - just_satisfy_the_compiler() { } + enum{size = count * sizeof(StorageChunk)}; }; - - ////////////////////////////////////TICKET #825 should be backed by mpool and integrated with node invocation - vector hTab_; - vector pTab_; - size_t level_; - public: - BuffTableStorage (const size_t maxSiz) - : hTab_(maxSiz), - pTab_(maxSiz), - level_(0) - { } - - ~BuffTableStorage() { ASSERT (0==level_, "buffer management logic broken."); } - - protected: - - friend class BuffTableChunk; - - /** allocate the given number of slots - * starting at current level to be used - * by the newly created BuffTableChunk - */ - BuffTable::Chunk - claim (uint slots) + class Builder { - ASSERT (pTab_.size() == hTab_.size()); - REQUIRE (level_+slots <= hTab_.size()); - - size_t prev_level (level_); - level_ += slots; - return std::make_pair (&hTab_[prev_level], - &pTab_[prev_level]); - } + public: + Builder& announce (uint count, BufferDescriptor const& type); + BuffTable& build(); + }; - void - release (uint slots) - { - ASSERT (slots <= level_); - REQUIRE (level_ <= hTab_.size()); - REQUIRE (level_ <= pTab_.size()); - - level_ -= slots; - } + static Builder& prepare (const size_t STORAGE_SIZE, void* storage); - bool - level_check (BuffTable::Chunk& prev_level) - { - return prev_level.first == &hTab_[level_] - && prev_level.second == &pTab_[level_]; - } + void lockBuffers(); + void releaseBuffers(); + + typedef vector BuffHandleTable; + typedef lib::RangeIter iterator; + + iterator buffers(); + iterator inBuffers(); + iterator outBuffers(); }; - /** - * to be allocated on the stack while evaluating a ProcNode#pull() call. - * The "current" State (StateProxy) maintains a BuffTableStorage (=pool), - * which can be used to crate such chunks. The claiming and releasing of - * slots in the BuffTableStorage is automatically tied to BuffTableChunk - * object's lifecycle. - */ - class BuffTableChunk - : public BuffTable, - boost::noncopyable - { - const uint siz_; - BuffTable::Chunk tab_; - BuffTableStorage& sto_; - - public: - BuffTableChunk (WiringDescriptor const& wd, BuffTableStorage& storage) - : siz_(wd.nrI + wd.nrO), - tab_(storage.claim (siz_)), - sto_(storage) - { - const uint nrO(wd.nrO); - - // Setup the publicly visible table locations - this->outHandle = &tab_.first[ 0 ]; - this->inHandle = &tab_.first[nrO]; - this->outBuff = &tab_.second[ 0 ]; - this->inBuff = &tab_.second[nrO]; - } - - ~BuffTableChunk () - { - sto_.release (siz_); - ASSERT ( sto_.level_check (tab_), - "buffer management logic broken."); - } - }; + /* === Implementation === */ + + inline BuffTable::Builder& + BuffTable::prepare (const size_t STORAGE_SIZE, void* storage) + { + UNIMPLEMENTED ("expose a builder object for outfitting a buffer pointer table"); + } + + + inline BuffTable::Builder& + BuffTable::Builder::announce (uint count, BufferDescriptor const& type) + { + UNIMPLEMENTED ("accept announcement of additional buffer table entries required"); + } + + + inline BuffTable& + BuffTable::Builder::build() + { + UNIMPLEMENTED ("finally drop off the newly configured buffer pointer table"); + } + + + inline void + BuffTable::lockBuffers() + { + UNIMPLEMENTED ("convenience shortcut: lock all preconfigured buffers within this table through the underlying buffer provider"); + } + + + inline void + BuffTable::releaseBuffers() + { + UNIMPLEMENTED ("convenience shortcut: release all the buffers managed through this buffer table, by forwarding to the underlying buffer provider"); + } + + + + inline BuffTable::iterator + BuffTable::buffers() + { + UNIMPLEMENTED ("expose an iterator to yield all prepared buffers within this buffer table"); + } + + + inline BuffTable::iterator + BuffTable::inBuffers() + { + UNIMPLEMENTED ("expose an iterator to access all the input buffer slots of this buffer table"); + } + + + inline BuffTable::iterator + BuffTable::outBuffers() + { + UNIMPLEMENTED ("expose an iterator to access all the output buffer slots of this buffer table"); + } + + + diff --git a/src/proc/engine/diagnostic-buffer-provider.cpp b/src/proc/engine/diagnostic-buffer-provider.cpp index 1711e1a6b..8a5efdfbe 100644 --- a/src/proc/engine/diagnostic-buffer-provider.cpp +++ b/src/proc/engine/diagnostic-buffer-provider.cpp @@ -97,6 +97,14 @@ namespace engine { : public BufferProvider , public ScopedPtrVect { + + virtual uint + announce (uint count, BufferDescriptor const& type) + { + UNIMPLEMENTED ("pre-register storage for buffers of a specific kind"); + } + + virtual BuffHandle lockBufferFor (BufferDescriptor const& descriptor) { @@ -141,6 +149,13 @@ namespace engine { }; + + DiagnosticBufferProvider::DiagnosticBufferProvider() + : pImpl_() //////////TODO create PImpl here + { } + + DiagnosticBufferProvider::~DiagnosticBufferProvider() { } + BufferProvider& DiagnosticBufferProvider::build() diff --git a/src/proc/engine/diagnostic-buffer-provider.hpp b/src/proc/engine/diagnostic-buffer-provider.hpp index f79ca49d2..0f80fea6e 100644 --- a/src/proc/engine/diagnostic-buffer-provider.hpp +++ b/src/proc/engine/diagnostic-buffer-provider.hpp @@ -68,6 +68,11 @@ namespace engine { bool isCurrent (BufferProvider const&); + DiagnosticBufferProvider(); + ~DiagnosticBufferProvider(); + + friend class lib::singleton::StaticCreate; + public: /** build a new Diagnostic Buffer Provider instance, * discard the existing one. Use the static query API @@ -88,8 +93,9 @@ namespace engine { /* === diagnostic API === */ bool buffer_was_used (uint bufferID) const; - bool buffer_was_closed (uint bufferID) const; - void* accessMemory (uint bufferID) const; + bool buffer_was_closed (uint bufferID) const; + void* accessMemory (uint bufferID) const; + bool all_buffers_released() const; template diff --git a/src/proc/play/output-slot.hpp b/src/proc/play/output-slot.hpp index b3188724e..ece7c4627 100644 --- a/src/proc/play/output-slot.hpp +++ b/src/proc/play/output-slot.hpp @@ -75,6 +75,7 @@ namespace play { { public: + BuffHandle lockBufferFor(FrameNr); void emit(FrameNr); }; diff --git a/tests/components/proc/engine/buffer-provider-protocol-test.cpp b/tests/components/proc/engine/buffer-provider-protocol-test.cpp index d2e5261dd..fdfba1e67 100644 --- a/tests/components/proc/engine/buffer-provider-protocol-test.cpp +++ b/tests/components/proc/engine/buffer-provider-protocol-test.cpp @@ -54,6 +54,13 @@ namespace test { const uint TEST_SIZE = 1024*1024; const uint TEST_ELMS = 20; + + void + do_some_calculations (BuffHandle const& buffer) + { + UNIMPLEMENTED ("some verifiable test/dummy buffer accessing operations"); + } + } @@ -108,6 +115,7 @@ namespace test { void verifyStandardCase() { +#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #829 // Create Test fixture. // In real usage, a suitable memory/frame/buffer provider // will be preconfigured, depending on the usage context @@ -115,12 +123,11 @@ namespace test { BufferDescriptor desc1 = provider.getDescriptor(); // note: implies also sizeof(TestFrame) BufferDescriptor desc2 = provider.getDescriptorFor(TEST_SIZE); -#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #829 CHECK (desc1.verifyValidity()); CHECK (desc2.verifyValidity()); - size_t num1 = provider.announce(TEST_ELMS, desc1); - size_t num2 = provider.announce(TEST_ELMS, desc2); + uint num1 = provider.announce(TEST_ELMS, desc1); + uint num2 = provider.announce(TEST_ELMS, desc2); CHECK (num1 == TEST_ELMS); CHECK (0 < num2 && num2 <=TEST_ELMS); @@ -128,15 +135,15 @@ namespace test { char storage[STORAGE_SIZE]; BuffTable& tab = BuffTable::prepare(STORAGE_SIZE, storage) - .prepare(num1, desc1) - .prepare(num2, desc2) + .announce(num1, desc1) + .announce(num2, desc2) .build(); tab.lockBuffers(); for_each (tab.buffers(), do_some_calculations); tab.releaseBuffers(); - DiagnosticBufferProvider checker = DiagnosticBufferProvider::access(provider); + DiagnosticBufferProvider& checker = DiagnosticBufferProvider::access(provider); CHECK (checker.all_buffers_released()); #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #829 } diff --git a/src/proc/play/diagnostic-output-slot.hpp b/tests/components/proc/play/diagnostic-output-slot.hpp similarity index 55% rename from src/proc/play/diagnostic-output-slot.hpp rename to tests/components/proc/play/diagnostic-output-slot.hpp index b699e0ae8..18a13c6b3 100644 --- a/src/proc/play/diagnostic-output-slot.hpp +++ b/tests/components/proc/play/diagnostic-output-slot.hpp @@ -33,6 +33,8 @@ #include "lib/error.hpp" #include "proc/play/output-slot.hpp" +#include "lib/iter-source.hpp" ////////////TODO really going down that path...? +#include "proc/engine/testframe.hpp" //#include "lib/sync.hpp" //#include @@ -46,6 +48,7 @@ namespace proc { namespace play { //using std::string; + using ::engine::test::TestFrame; //using std::vector; //using std::tr1::shared_ptr; @@ -71,6 +74,65 @@ namespace play { UNIMPLEMENTED ("Diagnostic Output Slot instance"); } + static DiagnosticOutputSlot& + access (OutputSlot& to_investigate) + { + UNIMPLEMENTED ("access the diagnostics data for the given OutputSlot instance"); + } + + + /* === diagnostics API === */ + + /** + * diagnostic facility to verify + * test data frames written to this + * Test/Dummy "output" + */ + struct OutputStreamProtocol + : lib::IterSource + { + /////////////TODO: implement the extension points required to drive an IterSource + }; + + typedef OutputStreamProtocol::iterator OutFrames; + + + OutFrames + getChannel (uint channel) + { + UNIMPLEMENTED ("access output stream tracing entry"); + } + + + bool + buffer_was_used (uint channel, FrameNr frame) + { + UNIMPLEMENTED ("determine if the denoted buffer was indeed used"); + } + + + bool + buffer_unused (uint channel, FrameNr frame) + { + UNIMPLEMENTED ("determine if the specified buffer was never touched/locked for use"); + } + + + bool + buffer_was_closed (uint channel, FrameNr frame) + { + UNIMPLEMENTED ("determine if the specified buffer was indeed closed properly"); + } + + + bool + emitted (uint channel, FrameNr frame) + { + UNIMPLEMENTED ("determine if the specivied buffer was indeed handed over for emitting output"); + } + + + private: }; diff --git a/tests/components/proc/play/output-slot-protocol-test.cpp b/tests/components/proc/play/output-slot-protocol-test.cpp index 124d49372..ae3ec2ae5 100644 --- a/tests/components/proc/play/output-slot-protocol-test.cpp +++ b/tests/components/proc/play/output-slot-protocol-test.cpp @@ -25,6 +25,7 @@ //#include "lib/util.hpp" #include "proc/play/diagnostic-output-slot.hpp" #include "proc/engine/buffhandle.hpp" +#include "proc/engine/testframe.hpp" //#include //#include @@ -41,6 +42,8 @@ namespace test { // using lib::AllocationCluster; // using mobject::session::PEffect; using ::engine::BuffHandle; + using ::engine::test::testData; + using ::engine::test::TestFrame; namespace { // Test fixture @@ -77,7 +80,7 @@ namespace test { // Client claims the OutputSlot // and opens it for exclusive use. - Allocation alloc = oSlot.allocate(); + OutputSlot::Allocation alloc = oSlot.allocate(); // Now the client is able to prepare // "calculation streams" for the individual @@ -95,13 +98,13 @@ namespace test { buff10.create(); // rendering process calculates content.... - buff00.access() = testData[0,0]; + buff00.accessAs() = testData(0,0); // while further frames might be processed in parallel BuffHandle buff11 = sink2.lockBufferFor (++frameNr); buff11.create(); - buff11.access() = testData[1,1]; - buff10.access() = testData[1,0]; + buff11.accessAs() = testData(1,1); + buff10.accessAs() = testData(1,0); // Now it's time to emit the output sink2.emit (frameNr-1); @@ -110,7 +113,7 @@ namespace test { // that's all for the client // Verify sane operation.... - DiagnosticOutputSlot checker = DiagnosticOutputSlot::access(oSlot); + DiagnosticOutputSlot& checker = DiagnosticOutputSlot::access(oSlot); CHECK (checker.buffer_was_used (0,0)); CHECK (checker.buffer_unused (0,1)); CHECK (checker.buffer_was_used (1,0)); @@ -129,12 +132,12 @@ namespace test { DiagnosticOutputSlot::OutFrames stream1 = checker.getChannel(1); CHECK ( stream0); - CHECK (*stream0++ == testData[0,0]); + CHECK (*stream0++ == testData(0,0)); CHECK (!stream0); CHECK ( stream1); - CHECK (*stream1++ == testData[1,0]); - CHECK (*stream1++ == testData[1,1]); + CHECK (*stream1++ == testData(1,0)); + CHECK (*stream1++ == testData(1,1)); CHECK (!stream1); #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #819 }