Cache ObjectHelper instances

Task-number: QTRD-2792
Change-Id: I90d83bd9b73a0f337fd26f1b92000e72b3ec0607
Reviewed-by: Tomi Korpipää <tomi.korpipaa@digia.com>
This commit is contained in:
Miikka Heikkinen 2014-05-21 13:37:11 +03:00
parent 37a82fbeb7
commit cb79f11be1
16 changed files with 148 additions and 96 deletions

View File

@ -24,29 +24,19 @@ CustomRenderItem::CustomRenderItem()
: AbstractRenderItem(),
m_texture(0),
m_object(0),
m_visible(true)
m_visible(true),
m_renderer(0)
{
}
CustomRenderItem::CustomRenderItem(const CustomRenderItem &other)
: AbstractRenderItem(other)
{
m_texture = other.m_texture;
}
CustomRenderItem::~CustomRenderItem()
{
if (m_object)
delete m_object;
ObjectHelper::releaseObjectHelper(m_renderer, m_object);
}
void CustomRenderItem::setMesh(const QString &meshFile)
{
if (m_object)
delete m_object;
// Load mesh and make an object of it
m_object = new ObjectHelper(meshFile);
m_object->load();
ObjectHelper::resetObjectHelper(m_renderer, m_object, meshFile);
}
QT_END_NAMESPACE_DATAVISUALIZATION

View File

@ -35,12 +35,12 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class QCustom3DItem;
class Abstract3DRenderer;
class CustomRenderItem : public AbstractRenderItem
{
public:
CustomRenderItem();
CustomRenderItem(const CustomRenderItem &other);
virtual ~CustomRenderItem();
inline void setTexture(GLuint texture) { m_texture = texture; }
@ -65,19 +65,24 @@ public:
inline int index() const { return m_index; }
inline void setShadowCasting(bool shadowCasting) { m_shadowCasting = shadowCasting; }
inline bool isShadowCasting() const { return m_shadowCasting; }
inline void setRenderer(Abstract3DRenderer *renderer) { m_renderer = renderer; }
private:
Q_DISABLE_COPY(CustomRenderItem)
GLuint m_texture;
QVector3D m_scaling;
QVector3D m_position;
bool m_absolute;
ObjectHelper *m_object;
ObjectHelper *m_object; // shared reference
bool m_needBlend;
bool m_visible;
bool m_valid;
int m_index;
bool m_shadowCasting;
QCustom3DItem *m_item;
Abstract3DRenderer *m_renderer;
};
typedef QHash<QCustom3DItem *, CustomRenderItem *> CustomRenderItemArray;

View File

@ -570,6 +570,7 @@ QVector4D Abstract3DRenderer::indexToSelectionColor(GLint index)
CustomRenderItem *Abstract3DRenderer::addCustomItem(QCustom3DItem *item)
{
CustomRenderItem *newItem = new CustomRenderItem();
newItem->setRenderer(this);
newItem->setItemPointer(item); // Store pointer for render item updates
newItem->setMesh(item->meshFile());
newItem->setScaling(item->scaling());

View File

@ -120,9 +120,9 @@ Bars3DRenderer::~Bars3DRenderer()
delete m_depthShader;
delete m_selectionShader;
delete m_backgroundShader;
delete m_backgroundObj;
delete m_gridLineObj;
delete m_labelObj;
ObjectHelper::releaseObjectHelper(this, m_backgroundObj);
ObjectHelper::releaseObjectHelper(this, m_gridLineObj);
ObjectHelper::releaseObjectHelper(this, m_labelObj);
delete m_labelShader;
}
@ -2336,26 +2336,20 @@ void Bars3DRenderer::updateShadowQuality(QAbstract3DGraph::ShadowQuality quality
void Bars3DRenderer::loadBackgroundMesh()
{
if (m_backgroundObj)
delete m_backgroundObj;
m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/negativeBackground"));
m_backgroundObj->load();
ObjectHelper::resetObjectHelper(this, m_backgroundObj,
QStringLiteral(":/defaultMeshes/negativeBackground"));
}
void Bars3DRenderer::loadGridLineMesh()
{
if (m_gridLineObj)
delete m_gridLineObj;
m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_gridLineObj->load();
ObjectHelper::resetObjectHelper(this, m_gridLineObj,
QStringLiteral(":/defaultMeshes/plane"));
}
void Bars3DRenderer::loadLabelMesh()
{
if (m_labelObj)
delete m_labelObj;
m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_labelObj->load();
ObjectHelper::resetObjectHelper(this, m_labelObj,
QStringLiteral(":/defaultMeshes/plane"));
}
void Bars3DRenderer::updateTextures()

View File

@ -73,9 +73,9 @@ private:
ShaderHelper *m_selectionShader;
ShaderHelper *m_backgroundShader;
ShaderHelper *m_labelShader;
ObjectHelper *m_backgroundObj;
ObjectHelper *m_gridLineObj;
ObjectHelper *m_labelObj;
ObjectHelper *m_backgroundObj; // Shared reference
ObjectHelper *m_gridLineObj; // Shared reference
ObjectHelper *m_labelObj; // Shared reference
GLuint m_bgrTexture;
GLuint m_depthTexture;
GLuint m_selectionTexture;

View File

@ -118,11 +118,11 @@ Scatter3DRenderer::~Scatter3DRenderer()
delete m_selectionShader;
delete m_backgroundShader;
delete m_labelShader;
delete m_backgroundObj;
ObjectHelper::releaseObjectHelper(this, m_backgroundObj);
#if !defined(QT_OPENGL_ES_2)
delete m_gridLineObj;
ObjectHelper::releaseObjectHelper(this, m_gridLineObj);
#endif
delete m_labelObj;
ObjectHelper::releaseObjectHelper(this, m_labelObj);
}
void Scatter3DRenderer::initializeOpenGL()
@ -1731,28 +1731,22 @@ void Scatter3DRenderer::updateShadowQuality(QAbstract3DGraph::ShadowQuality qual
void Scatter3DRenderer::loadBackgroundMesh()
{
if (m_backgroundObj)
delete m_backgroundObj;
m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
m_backgroundObj->load();
ObjectHelper::resetObjectHelper(this, m_backgroundObj,
QStringLiteral(":/defaultMeshes/background"));
}
#if !(defined QT_OPENGL_ES_2)
void Scatter3DRenderer::loadGridLineMesh()
{
if (m_gridLineObj)
delete m_gridLineObj;
m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_gridLineObj->load();
ObjectHelper::resetObjectHelper(this, m_gridLineObj,
QStringLiteral(":/defaultMeshes/plane"));
}
#endif
void Scatter3DRenderer::loadLabelMesh()
{
if (m_labelObj)
delete m_labelObj;
m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_labelObj->load();
ObjectHelper::resetObjectHelper(this, m_labelObj,
QStringLiteral(":/defaultMeshes/plane"));
}
void Scatter3DRenderer::updateTextures()

View File

@ -68,11 +68,11 @@ private:
ShaderHelper *m_selectionShader;
ShaderHelper *m_backgroundShader;
ShaderHelper *m_labelShader;
ObjectHelper *m_backgroundObj;
ObjectHelper *m_backgroundObj; // Shared reference
#if !(defined QT_OPENGL_ES_2)
ObjectHelper *m_gridLineObj;
ObjectHelper *m_gridLineObj; // Shared reference
#endif
ObjectHelper *m_labelObj;
ObjectHelper *m_labelObj; // Shared reference
GLuint m_bgrTexture;
GLuint m_depthTexture;
GLuint m_selectionTexture;

View File

@ -54,7 +54,6 @@ SelectionPointer::~SelectionPointer()
{
delete m_labelShader;
delete m_pointShader;
delete m_labelObj;
delete m_textureHelper;
}
@ -66,7 +65,6 @@ void SelectionPointer::initializeOpenGL()
m_drawer->initializeOpenGL();
initShaders();
loadLabelMesh();
}
void SelectionPointer::updateScene(Q3DScene *scene)
@ -235,6 +233,11 @@ void SelectionPointer::setPointerObject(ObjectHelper *object)
m_pointObj = object;
}
void SelectionPointer::setLabelObject(ObjectHelper *object)
{
m_labelObj = object;
}
void SelectionPointer::handleDrawerChange()
{
m_cachedTheme = m_drawer->theme();
@ -269,12 +272,4 @@ void SelectionPointer::initShaders()
}
void SelectionPointer::loadLabelMesh()
{
if (m_labelObj)
delete m_labelObj;
m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_labelObj->load();
}
QT_END_NAMESPACE_DATAVISUALIZATION

View File

@ -53,6 +53,7 @@ public:
void setPosition(const QVector3D &position);
void setLabel(const QString &label);
void setPointerObject(ObjectHelper *object);
void setLabelObject(ObjectHelper *object);
void handleDrawerChange();
void updateBoundingRect(const QRect &rect);
void updateScene(Q3DScene *scene);
@ -63,12 +64,11 @@ public:
private:
void initializeOpenGL();
void initShaders();
void loadLabelMesh();
private:
ShaderHelper *m_labelShader;
ShaderHelper *m_pointShader;
ObjectHelper *m_labelObj;
ObjectHelper *m_labelObj; // Not owned
ObjectHelper *m_pointObj; // Not owned
TextureHelper *m_textureHelper;
Q3DTheme *m_cachedTheme;

View File

@ -109,13 +109,7 @@ void SeriesRenderCache::populate(bool newSeries)
m_renderer->fixMeshFileName(meshFileName, m_mesh);
}
delete m_object;
if (meshFileName.isEmpty()) {
m_object = 0;
} else {
m_object = new ObjectHelper(meshFileName);
m_object->load();
}
ObjectHelper::resetObjectHelper(m_renderer, m_object, meshFileName);
}
if (newSeries || changeTracker.meshRotationChanged) {
@ -193,7 +187,7 @@ void SeriesRenderCache::populate(bool newSeries)
void SeriesRenderCache::cleanup(TextureHelper *texHelper)
{
delete m_object;
ObjectHelper::releaseObjectHelper(m_renderer, m_object);
if (QOpenGLContext::currentContext()) {
texHelper->deleteTexture(&m_baseUniformTexture);
texHelper->deleteTexture(&m_baseGradientTexture);

View File

@ -74,7 +74,7 @@ public:
protected:
QAbstract3DSeries *m_series;
ObjectHelper *m_object;
ObjectHelper *m_object; // Shared reference
QAbstract3DSeries::Mesh m_mesh;
QQuaternion m_meshRotation;

View File

@ -142,11 +142,11 @@ Surface3DRenderer::~Surface3DRenderer()
delete m_surfaceSliceSmoothShader;
delete m_labelShader;
delete m_backgroundObj;
ObjectHelper::releaseObjectHelper(this, m_backgroundObj);
#if !defined(QT_OPENGL_ES_2)
delete m_gridLineObj;
ObjectHelper::releaseObjectHelper(this, m_gridLineObj);
#endif
delete m_labelObj;
ObjectHelper::releaseObjectHelper(this, m_labelObj);
}
void Surface3DRenderer::initializeOpenGL()
@ -2311,19 +2311,15 @@ void Surface3DRenderer::resetClickedStatus()
void Surface3DRenderer::loadBackgroundMesh()
{
if (m_backgroundObj)
delete m_backgroundObj;
m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
m_backgroundObj->load();
ObjectHelper::resetObjectHelper(this, m_backgroundObj,
QStringLiteral(":/defaultMeshes/background"));
}
#if !(defined QT_OPENGL_ES_2)
void Surface3DRenderer::loadGridLineMesh()
{
if (m_gridLineObj)
delete m_gridLineObj;
m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_gridLineObj->load();
ObjectHelper::resetObjectHelper(this, m_gridLineObj,
QStringLiteral(":/defaultMeshes/plane"));
}
#endif
@ -2407,6 +2403,7 @@ void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, co
slicePointer->setPosition((subPosFront + subPosBack) / 2.0f);
slicePointer->setLabel(selectionLabel);
slicePointer->setPointerObject(cache->object());
slicePointer->setLabelObject(m_labelObj);
slicePointer->setHighlightColor(cache->singleHighlightColor());
slicePointer->updateScene(m_cachedScene);
slicePointer->setRotation(cache->meshRotation());
@ -2420,6 +2417,7 @@ void Surface3DRenderer::updateSelectionPoint(SurfaceSeriesRenderCache *cache, co
mainPointer->setPosition(mainPos);
mainPointer->setLabel(selectionLabel);
mainPointer->setPointerObject(cache->object());
mainPointer->setLabelObject(m_labelObj);
mainPointer->setHighlightColor(cache->singleHighlightColor());
mainPointer->updateScene(m_cachedScene);
mainPointer->setRotation(cache->meshRotation());
@ -2548,10 +2546,8 @@ void Surface3DRenderer::updateSlicingActive(bool isSlicing)
void Surface3DRenderer::loadLabelMesh()
{
if (m_labelObj)
delete m_labelObj;
m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/plane"));
m_labelObj->load();
ObjectHelper::resetObjectHelper(this, m_labelObj,
QStringLiteral(":/defaultMeshes/plane"));
}
void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)

View File

@ -73,11 +73,11 @@ private:
GLfloat m_maxVisibleRowValue;
GLfloat m_visibleColumnRange;
GLfloat m_visibleRowRange;
ObjectHelper *m_backgroundObj;
ObjectHelper *m_backgroundObj; // Shared reference
#if !(defined QT_OPENGL_ES_2)
ObjectHelper *m_gridLineObj;
ObjectHelper *m_gridLineObj; // Shared reference
#endif
ObjectHelper *m_labelObj;
ObjectHelper *m_labelObj; // Shared reference
GLuint m_depthTexture;
GLuint m_depthModelTexture;
GLuint m_depthFrameBuffer;

View File

@ -27,15 +27,87 @@ ObjectHelper::ObjectHelper(const QString &objectFile)
: m_objectFile(objectFile)
{
m_indicesType = GL_UNSIGNED_SHORT;
load();
}
struct ObjectHelperRef {
int refCount;
ObjectHelper *obj;
};
// The "Abstract3DRenderer *" key identifies the renderer
static QHash<const Abstract3DRenderer *, QHash<QString, ObjectHelperRef *> *> cacheTable;
ObjectHelper::~ObjectHelper()
{
}
void ObjectHelper::setObjectFile(const QString &objectFile)
void ObjectHelper::resetObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj,
const QString &meshFile)
{
m_objectFile = objectFile;
Q_ASSERT(cacheId);
if (obj) {
const QString &oldFile = obj->objectFile();
if (meshFile == oldFile)
return; // same file, do nothing
releaseObjectHelper(cacheId, obj);
}
obj = getObjectHelper(cacheId, meshFile);
}
void ObjectHelper::releaseObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj)
{
Q_ASSERT(cacheId);
if (obj) {
QHash<QString, ObjectHelperRef *> *objectTable = cacheTable.value(cacheId, 0);
if (objectTable) {
// Delete object if last reference is released
ObjectHelperRef *objRef = objectTable->value(obj->m_objectFile, 0);
if (objRef) {
objRef->refCount--;
if (objRef->refCount <= 0) {
objectTable->remove(obj->m_objectFile);
delete objRef->obj;
delete objRef;
}
}
if (objectTable->isEmpty()) {
// Remove the entire cache if last object was removed
cacheTable.remove(cacheId);
delete objectTable;
}
} else {
// Just delete the object if unknown cache
delete obj;
}
obj = 0;
}
}
ObjectHelper *ObjectHelper::getObjectHelper(const Abstract3DRenderer *cacheId,
const QString &objectFile)
{
if (objectFile.isEmpty())
return 0;
QHash<QString, ObjectHelperRef *> *objectTable = cacheTable.value(cacheId, 0);
if (!objectTable) {
objectTable = new QHash<QString, ObjectHelperRef *>;
cacheTable.insert(cacheId, objectTable);
}
// Check if object helper for this mesh already exists
ObjectHelperRef *objRef = objectTable->value(objectFile, 0);
if (!objRef) {
objRef = new ObjectHelperRef;
objRef->refCount = 0;
objRef->obj = new ObjectHelper(objectFile);
objectTable->insert(objectFile, objRef);
}
objRef->refCount++;
return objRef->obj;
}
void ObjectHelper::load()

View File

@ -35,17 +35,26 @@
QT_BEGIN_NAMESPACE_DATAVISUALIZATION
class Abstract3DRenderer;
class ObjectHelper : public AbstractObjectHelper
{
private:
ObjectHelper(const QString &objectFile);
public:
ObjectHelper(const QString &objectFile = QString());
~ObjectHelper();
void setObjectFile(const QString &objectFile);
static void resetObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj,
const QString &meshFile);
static void releaseObjectHelper(const Abstract3DRenderer *cacheId, ObjectHelper *&obj);
void load();
inline const QString &objectFile() { return m_objectFile; }
private:
static ObjectHelper *getObjectHelper(const Abstract3DRenderer *cacheId,
const QString &objectFile);
void load();
QString m_objectFile;
};

View File

@ -268,6 +268,8 @@ void Data::changeMode(int mode)
void Data::start()
{
m_started = true;
// Reset resolution before starting (otherwise restart will crash due to empty data)
setResolution(m_resolutionLevel);
updateData();
m_statusArea->append(QStringLiteral("<b>Started<\b>"));
}