Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
buffer-provider.cpp
Go to the documentation of this file.
1/*
2 BufferProvider - Abstraction for Buffer management during playback/render
3
4 Copyright (C)
5 2008, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
14
20#include "lib/error.hpp"
23#include "lib/util.hpp"
24
25using util::isSameAdr;
26
27namespace steam {
28namespace engine {
29
30 // storage for the default-marker constants
31 const TypeHandler TypeHandler::RAW{};
32 const LocalTag LocalTag::UNKNOWN{};
33
34
35 namespace { // impl. details and definitions
36
38
39 }
40
41 LUMIERA_ERROR_DEFINE (BUFFER_MANAGEMENT, "Problem providing working buffers");
42
43
50 : meta_(new BufferMetadata (implementationID))
51 { }
52
54
55
60 bool
62 {
63 return meta_->isLocked (bufferID);
64 }
65
66
69 {
70 return BuffDescr (*this, meta_->key (storageSize));
71 }
72
73
75 BufferProvider::getDescriptorFor(size_t storageSize, TypeHandler specialTreatment)
76 {
77 return BuffDescr (*this, meta_->key (storageSize, specialTreatment));
78 }
79
80
81 size_t
82 BufferProvider::getBufferSize (HashVal typeID) const
83 {
84 metadata::Key& typeKey = meta_->get (typeID);
85 return typeKey.storageSize();
86 }
87
88
96 BufferProvider::buildHandle (HashVal typeID, Buff* storage, LocalTag const& localTag)
97 {
98 metadata::Key& typeKey = meta_->get (typeID);
99 metadata::Entry& entry = meta_->markLocked(typeKey, storage, localTag);
100
101 return BuffHandle (BuffDescr(*this, entry), storage);
102 }
103
104
117 uint
119 {
120 uint actually_possible = prepareBuffers (count, type);
121 if (!actually_possible)
122 throw error::State ("unable to fulfil request for buffers"
123 ,LUMIERA_ERROR_BUFFER_MANAGEMENT);
124 return actually_possible;
125 }
126
127
143 {
144 REQUIRE (was_created_by_this_provider (type));
145
146 return provideLockedBuffer (type);
147 } // is expected to call buildHandle() --> state transition
148
149
162 void
164 {
165 metadata::Entry& metaEntry = meta_->get (handle.entryID());
166 mark_emitted (metaEntry.parentKey(), metaEntry.localTag());
167 metaEntry.mark(EMITTED);
168 }
169
170
179 void
181 try {
182 metadata::Entry& metaEntry = meta_->get (handle.entryID());
183 metaEntry.mark(FREE); // might invoke embedded dtor function
184 detachBuffer (metaEntry.parentKey(), metaEntry.localTag(), *handle);
185 meta_->release (metaEntry);
186 }
187 ERROR_LOG_AND_IGNORE (engine, "releasing a buffer from BufferProvider")
188
189
190
191
201 void
202 BufferProvider::attachTypeHandler (BuffHandle const& target, BuffDescr const& reference)
203 {
204 metadata::Entry& metaEntry = meta_->get (target.entryID());
205 metadata::Entry& refEntry = meta_->get (reference);
206 REQUIRE (refEntry.isTypeKey());
207 REQUIRE (!metaEntry.isTypeKey());
208 if (!metaEntry.isLocked())
209 throw error::Logic{"unable to attach an object because buffer isn't locked for use"
210 , LERR_(LIFECYCLE)};
211
212 metaEntry.useTypeHandlerFrom (refEntry); // EX_STRONG
213 }
214
215
223 void
224 BufferProvider::emergencyCleanup (BuffHandle const& target, bool invokeDtor)
225 try {
226 metadata::Entry& metaEntry = meta_->get (target.entryID());
227 metaEntry.invalidate (invokeDtor);
228 detachBuffer (metaEntry.parentKey(), metaEntry.localTag(), *target);
229 meta_->release (metaEntry);
230 }
231 ERROR_LOG_AND_IGNORE (engine, "cleanup of buffer metadata while handling an error")
232
233
234
235 bool
236 BufferProvider::was_created_by_this_provider (BuffDescr const& descr) const
237 {
238 return isSameAdr (this, descr.provider_);
239 }
240
241
242
243
244
245 /* === BuffDescr and BuffHandle === */
246
247 bool
249 {
250 ENSURE (provider_);
251 return provider_->verifyValidity(*this);
252 }
253
254
255 size_t
257 {
258 ENSURE (provider_);
259 return provider_->getBufferSize (*this);
260 }
261
262
263 uint
265 {
266 ENSURE (provider_);
267 return provider_->announce(count, *this);
268 }
269
270
273 {
274 ENSURE (provider_);
275 return provider_->lockBuffer(*this);
276 }
277
278
279 void
281 {
282 REQUIRE (isValid());
284 }
285
286
287 void
289 {
290 if (pBuffer_)
291 {
292 REQUIRE (isValid());
294 pBuffer_ = 0;
295 }
296 ENSURE (!isValid());
297 }
298
299
300 void
302 {
303 descriptor_.provider_->emergencyCleanup(*this); // EX_FREE
304 pBuffer_ = 0;
305 }
306
307
320 void
322 {
323 if (!this->isValid())
324 throw error::Logic ("attaching an object requires an buffer in locked state", LERR_(LIFECYCLE));
325 if (this->size() < type.determineBufferSize())
326 throw error::Logic ("insufficient buffer size to hold an instance of that type");
327
328 descriptor_.provider_->attachTypeHandler(*this, type); // EX_STRONG
329 }
330
331
332
333
334}} // namespace engine
Metadata for managing and accessing buffers.
Abstraction to represent buffer management and lifecycle within the render engine.
Inline string literal.
Definition symbol.hpp:78
placeholder type for the contents of a data buffer.
An opaque descriptor to identify the type and further properties of a data buffer.
BufferProvider * provider_
uint announce(uint count)
convenience shortcut to start a buffer handling cycle
Handle for a buffer for processing data, abstracting away the actual implementation.
Registry for managing buffer metadata.
Interface: a facility providing and managing working buffers for media calculations.
uint announce(uint count, BuffDescr const &)
BufferProvider API: declare in advance the need for working buffers.
BuffHandle buildHandle(HashVal typeID, Buff *storage, LocalTag const &=LocalTag::UNKNOWN)
callback from implementation to build and enrol a BufferHandle, to be returned to the client as resul...
bool was_created_by_this_provider(BuffDescr const &) const
virtual uint prepareBuffers(uint count, HashVal typeID)=0
bool verifyValidity(BuffDescr const &) const
void emergencyCleanup(BuffHandle const &target, bool invokeDtor=false)
void emitBuffer(BuffHandle const &)
BufferProvider API: state transition to emitted state.
virtual ~BufferProvider()
this is an ABC
unique_ptr< BufferMetadata > meta_
BuffDescr getDescriptorFor(size_t storageSize=0)
describe the kind of buffer managed by this provider
virtual void detachBuffer(HashVal, LocalTag const &, Buff &)=0
void attachTypeHandler(BuffHandle const &target, BuffDescr const &reference)
allow for attaching and owing an object within an already created buffer
virtual void mark_emitted(HashVal, LocalTag const &)=0
size_t getBufferSize(HashVal typeID) const
BufferProvider(Literal implementationID)
build a new provider instance, managing a family of buffers.
BuffHandle lockBuffer(BuffDescr const &)
BufferProvider API: retrieve a single buffer for exclusive use.
void releaseBuffer(BuffHandle const &)
BufferProvider API: declare done and detach.
virtual BuffHandle provideLockedBuffer(HashVal typeID)=0
an opaque mark to be used by the BufferProvider implementation.
static const LocalTag UNKNOWN
Marker when no distinct local key is given.
A complete metadata Entry, based on a Key.
bool isTypeKey() const
is this Entry just an (abstract) placeholder for a type?
Entry & mark(BufferState newState)
Buffer state machine.
bool isLocked() const
is this Entry currently associated to a concrete buffer? Is this buffer in use?
Entry & invalidate(bool invokeDtor=true)
Description of a Buffer-"type".
void useTypeHandlerFrom(Key const &ref)
LocalTag const & localTag() const
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition error.h:71
Lumiera error handling (C++ interface).
#define ERROR_LOG_AND_IGNORE(_FLAG_, _OP_DESCR_)
convenience shortcut for a sequence of catch blocks just logging and consuming an error.
Definition error.hpp:267
#define LERR_(_NAME_)
Definition error.hpp:45
unsigned int uint
Definition integral.hpp:29
LumieraError< LERR_(STATE)> State
Definition error.hpp:209
LumieraError< LERR_(LOGIC)> Logic
Definition error.hpp:207
@ FREE
allocated buffer, no longer in use
@ EMITTED
allocated buffer, returned from client
Steam-Layer implementation namespace root.
bool isSameAdr(A const &a, B const &b)
compare plain object address identity, disregarding type.
Definition util.hpp:411
A pair of functors to maintain a datastructure within a buffer.
static const TypeHandler RAW
Marker for the default case: raw buffer without type handling.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...