stubbed relevant parts of BufferProvider and OutputSlot

This commit is contained in:
Fischlurch 2011-10-19 02:47:11 +02:00
parent 991eec8185
commit ca0ae9c120
9 changed files with 195 additions and 121 deletions

View file

@ -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;

View file

@ -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
*/

View file

@ -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");
}

View file

@ -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()

View file

@ -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>

View file

@ -75,6 +75,7 @@ namespace play {
{
public:
BuffHandle lockBufferFor(FrameNr);
void emit(FrameNr);
};

View file

@ -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
}

View file

@ -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:
};

View file

@ -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
}