Notice: If you are member of any public project or group, please make sure that your GitLab username is not the same as the LRZ identifier/Kennung (see https://gitlab.lrz.de/profile/account). Please change your username if necessary. For more information see the section "Public projects / Öffentliche Projekte" at https://doku.lrz.de/display/PUBLIC/GitLab . Thank you!

Commit c56f094b authored by Jakob Weiss's avatar Jakob Weiss

minor fixes and clarifications regarding ScopedTypedData

parent ce377bcc
......@@ -44,10 +44,10 @@ namespace campvis {
DataHandle DataContainer::addData(const std::string& name, AbstractData* data) {
if (name.empty()) {
LERROR("Tried to add data with empty name to DataContainer.");
return DataHandle(0);
return DataHandle(nullptr);
}
cgtAssert(data != 0, "The Data must not be 0.");
cgtAssert(data != nullptr, "The Data must not be 0.");
cgtAssert(!name.empty(), "The data's name must not be empty.");
DataHandle dh(data);
......@@ -61,7 +61,7 @@ namespace campvis {
return;
}
cgtAssert(dh.getData() != 0, "The data in the DataHandle must not be 0!");
cgtAssert(dh, "The data in the DataHandle must not be 0!");
cgtAssert(!name.empty(), "The data's name must not be empty.");
_handles.erase(name);
_handles.insert(std::make_pair(name, dh));
......@@ -81,7 +81,7 @@ namespace campvis {
return a->second;
}
else {
return DataHandle(0);
return DataHandle(nullptr);
}
}
......
......@@ -28,7 +28,7 @@
#include "core/datastructures/abstractdata.h"
namespace campvis {
DataHandle::DataHandle(AbstractData* data)
DataHandle::DataHandle(AbstractData* data)
: _timestamp(clock())
{
if (data) {
......@@ -42,7 +42,7 @@ namespace campvis {
}
}
DataHandle::DataHandle(const DataHandle& rhs)
DataHandle::DataHandle(const DataHandle& rhs)
: _ptr(rhs._ptr)
, _timestamp(rhs._timestamp)
{
......
......@@ -36,18 +36,17 @@ namespace campvis {
/**
* A DataHandle is responsible to manage the lifetime of an AbstractData instance.
* Therefore, it implements a reference counting technique in cooperation with AbstractData.
*
* This class can be considered as thread safe under the following conditions:
* * A single DataHandle instance must not be accessed from different threads.
* * Concurrent access to the same AbstractData instance via different DataHandles is safe.
*
* \note For clarity: An AbstractData instance can be referenced by multiple DataHandles. As soon
* Therefore, it implements a reference counting technique and automatically deletes instances when
* no other references exist anymore.
*
* This class can be considered as thread safe, since through the getData() and getWritableData() thread-safe
* access is ensured.
*
* \note For clarity: An AbstractData instance can be referenced by multiple DataHandles. As soon
* as it is afterwards reference by 0 DataHandles, the AbstractData instance will be destroyed.
* Also remember that a DataHandle takes ownership of the given AbstractData instance. So do
* not delete it once it has been assigned to a DataHandle (respectively DataContainer) or mess
* with its reference counting!
* \note Reference counting implementation inspired from Scott Meyers: More Effective C++, Item 29
*/
class CAMPVIS_CORE_API DataHandle {
template<class T, bool isWritable> friend class ScopedTypedData;
......@@ -83,7 +82,7 @@ namespace campvis {
/**
* Grants const access to the managed AbstractData instance.
* \return _data;
* \return const pointer proxy class managing access
*/
template <class T = AbstractData>
ScopedTypedData<T, false> getData() const {
......@@ -91,8 +90,8 @@ namespace campvis {
}
/**
* Grants const access to the managed AbstractData instance.
* \return _data;
* Grants writable access to the managed AbstractData instance.
* \return non-const pointer proxy class managing the access
*/
template <class T = AbstractData>
ScopedTypedData<T, true> getWritableData() {
......@@ -113,11 +112,11 @@ namespace campvis {
}
/**
* Explicit cast to bool, returns true if pointer is valid. Allows to check DataHandles
* Explicit cast to bool, returns true if pointer is valid. Allows to check DataHandles
* conveniently using an if(dh) { [DataHandle is valid] } statement.
* \return !empty()
*/
operator bool() const {
explicit operator bool() const {
return !empty();
}
......
This diff is collapsed.
......@@ -72,23 +72,26 @@ namespace campvis {
void VisualizationProcessor::createAndAttachTexture(GLint internalFormat, GLenum attachment, ScopedTypedData<RenderData, true>* renderData /*= nullptr*/) {
cgtAssert(_fbo->isActive(), "Trying to attach a texture while FBO is not bound!");
// acqiure a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
// acquire a new TextureUnit, so that we don't mess with other currently bound textures during texture upload...
cgt::TextureUnit rtUnit;
rtUnit.activate();
// Set OpenGL pixel alignment to 1 to avoid problems with NPOT textures
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Check the render data if we can reuse a texture
cgt::Texture* tex = nullptr;
if (renderData) {
if (renderData) {`
// check if we can get a GL representation of the desired texture
ImageRepresentationGL* glRep;
if (attachment == GL_DEPTH_ATTACHMENT)
if(auto id = (*renderData)->getDepthTexture())
glRep = const_cast<ImageRepresentationGL*>(id->getRepresentation<ImageRepresentationGL>(false));
else
if(auto id =(*renderData)->getColorTexture(_fbo->getNumColorAttachments()))
if(auto id =(*renderData)->getColorTexture(_fbo->getNumColorAttachments())) //_fbo->getNumColorAttachments() is the index of the texture that is to be created
glRep = const_cast<ImageRepresentationGL*>(id->getRepresentation<ImageRepresentationGL>(false));
// check if the texture is compatible with what we want, and in that case detach from the old RenderTargetData
if (glRep) {
tex = const_cast<cgt::Texture*>(glRep->getTexture());
if (tex->getType() != GL_TEXTURE_2D || tex->getDimensions() != getRenderTargetSize()
......@@ -96,13 +99,15 @@ namespace campvis {
tex = nullptr;
else {
// somehow detach the cgt::Texture from the ImageRepresentationGL
// yes this is horrible code
// yes this is horrible - however, we know that renderData has write access, ergo
// we can safely do this const_cast
const_cast<ImageData*>(glRep->getParent())->removeRepresentationUnsafe<ImageRepresentationGL>();
}
}
}
// if we could not get the texture from a previous render target, create a new one
if (!tex) {
// create texture
tex = new cgt::Texture(GL_TEXTURE_2D, getRenderTargetSize(), internalFormat, cgt::Texture::LINEAR);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment