stubbed relevant parts of BufferProvider and OutputSlot
This commit is contained in:
parent
991eec8185
commit
ca0ae9c120
9 changed files with 195 additions and 121 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "proc/engine/buffhandle.hpp"
|
||||
#include "proc/engine/procnode.hpp"
|
||||
#include "lib/iter-adapter.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <vector>
|
||||
|
|
@ -57,122 +58,99 @@ namespace engine {
|
|||
{
|
||||
typedef BuffHandle * PHa;
|
||||
typedef BuffHandle::PBuff * PBu;
|
||||
typedef pair<PHa const,PBu const> 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<uint count>
|
||||
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<BuffHaXXXX> hTab_;
|
||||
vector<BuffHandle::PBuff> 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<BuffHandle> BuffHandleTable;
|
||||
typedef lib::RangeIter<BuffHandleTable::iterator> 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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,14 @@ namespace engine {
|
|||
: public BufferProvider
|
||||
, public ScopedPtrVect<Block>
|
||||
{
|
||||
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@ namespace engine {
|
|||
bool isCurrent (BufferProvider const&);
|
||||
|
||||
|
||||
DiagnosticBufferProvider();
|
||||
~DiagnosticBufferProvider();
|
||||
|
||||
friend class lib::singleton::StaticCreate<DiagnosticBufferProvider>;
|
||||
|
||||
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<typename BU>
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ namespace play {
|
|||
{
|
||||
|
||||
public:
|
||||
BuffHandle lockBufferFor(FrameNr);
|
||||
void emit(FrameNr);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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<TestFrame>(); // 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <boost/noncopyable.hpp>
|
||||
|
|
@ -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<TestFrame>
|
||||
{
|
||||
/////////////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:
|
||||
|
||||
};
|
||||
|
|
@ -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 <boost/format.hpp>
|
||||
//#include <iostream>
|
||||
|
|
@ -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<TestFrame>();
|
||||
|
||||
// rendering process calculates content....
|
||||
buff00.access<TestFrame>() = testData[0,0];
|
||||
buff00.accessAs<TestFrame>() = testData(0,0);
|
||||
|
||||
// while further frames might be processed in parallel
|
||||
BuffHandle buff11 = sink2.lockBufferFor (++frameNr);
|
||||
buff11.create<TestFrame>();
|
||||
buff11.access<TestFrame>() = testData[1,1];
|
||||
buff10.access<TestFrame>() = testData[1,0];
|
||||
buff11.accessAs<TestFrame>() = testData(1,1);
|
||||
buff10.accessAs<TestFrame>() = 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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue