forked from qt-creator/qt-creator
Timeline: Properly encapsulate render pass states
We have to make sure that all the nodes get deleted when the states are deleted. Previously, we relied on the RenderState destructor to recursively delete nodes owned by their parents. This is rather hard to understand and can easily fail if we create a pass state without calling TimelineRenderState::assembleNodeTree() afterwards. The best way to deal with this is to properly encapsulate the nodes into the states and add destructors which delete them. Change-Id: I8b1ce16084afc1c85a90609f8f8d889147f7832f Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
This commit is contained in:
@@ -56,16 +56,30 @@ private:
|
|||||||
QColor m_selectionColor;
|
QColor m_selectionColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TimelineItemsRenderPassState : public TimelineRenderPass::State {
|
class TimelineItemsRenderPassState : public TimelineRenderPass::State {
|
||||||
TimelineItemsRenderPassState() : indexFrom(std::numeric_limits<int>::max()), indexTo(-1) {}
|
public:
|
||||||
int indexFrom;
|
TimelineItemsRenderPassState(const TimelineModel *model);
|
||||||
int indexTo;
|
~TimelineItemsRenderPassState();
|
||||||
TimelineItemsMaterial collapsedRowMaterial;
|
|
||||||
|
QSGNode *expandedRow(int row) const { return m_expandedRows[row]; }
|
||||||
|
QSGNode *collapsedRow(int row) const { return m_collapsedRows[row]; }
|
||||||
|
|
||||||
|
const QVector<QSGNode *> &expandedRows() const { return m_expandedRows; }
|
||||||
|
const QVector<QSGNode *> &collapsedRows() const { return m_collapsedRows; }
|
||||||
|
TimelineItemsMaterial *collapsedRowMaterial() { return &m_collapsedRowMaterial; }
|
||||||
|
|
||||||
|
int indexFrom() const { return m_indexFrom; }
|
||||||
|
int indexTo() const { return m_indexTo; }
|
||||||
|
void updateIndexes(int from, int to);
|
||||||
|
void updateCollapsedRowMaterial(float xScale, int selectedItem, QColor selectionColor);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_indexFrom;
|
||||||
|
int m_indexTo;
|
||||||
|
TimelineItemsMaterial m_collapsedRowMaterial;
|
||||||
|
|
||||||
QVector<QSGNode *> m_expandedRows;
|
QVector<QSGNode *> m_expandedRows;
|
||||||
QVector<QSGNode *> m_collapsedRows;
|
QVector<QSGNode *> m_collapsedRows;
|
||||||
const QVector<QSGNode *> &expandedRows() const { return m_expandedRows; }
|
|
||||||
const QVector<QSGNode *> &collapsedRows() const { return m_collapsedRows; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OpaqueColoredPoint2DWithSize {
|
struct OpaqueColoredPoint2DWithSize {
|
||||||
@@ -214,16 +228,16 @@ static void updateNodes(int from, int to, const TimelineModel *model,
|
|||||||
TimelineItemsGeometry &row = expandedPerRow[i];
|
TimelineItemsGeometry &row = expandedPerRow[i];
|
||||||
if (row.usedVertices > 0) {
|
if (row.usedVertices > 0) {
|
||||||
row.allocate(&static_cast<TimelineExpandedRowNode *>(
|
row.allocate(&static_cast<TimelineExpandedRowNode *>(
|
||||||
state->m_expandedRows[i])->material);
|
state->expandedRow(i))->material);
|
||||||
state->m_expandedRows[i]->appendChildNode(row.node);
|
state->expandedRow(i)->appendChildNode(row.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < model->collapsedRowCount(); ++i) {
|
for (int i = 0; i < model->collapsedRowCount(); ++i) {
|
||||||
TimelineItemsGeometry &row = collapsedPerRow[i];
|
TimelineItemsGeometry &row = collapsedPerRow[i];
|
||||||
if (row.usedVertices > 0) {
|
if (row.usedVertices > 0) {
|
||||||
row.allocate(&state->collapsedRowMaterial);
|
row.allocate(state->collapsedRowMaterial());
|
||||||
state->m_collapsedRows[i]->appendChildNode(row.node);
|
state->collapsedRow(i)->appendChildNode(row.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,36 +304,25 @@ TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineAbstrac
|
|||||||
|
|
||||||
TimelineItemsRenderPassState *state;
|
TimelineItemsRenderPassState *state;
|
||||||
if (oldState == 0)
|
if (oldState == 0)
|
||||||
state = new TimelineItemsRenderPassState;
|
state = new TimelineItemsRenderPassState(model);
|
||||||
else
|
else
|
||||||
state = static_cast<TimelineItemsRenderPassState *>(oldState);
|
state = static_cast<TimelineItemsRenderPassState *>(oldState);
|
||||||
|
|
||||||
|
|
||||||
float selectedItem = renderer->selectedItem() == -1 ? -1 :
|
int selectedItem = renderer->selectedItem() == -1 ? -1 :
|
||||||
model->selectionId(renderer->selectedItem());
|
model->selectionId(renderer->selectedItem());
|
||||||
|
|
||||||
state->collapsedRowMaterial.setScale(QVector2D(spacing / parentState->scale(), 1));
|
state->updateCollapsedRowMaterial(spacing / parentState->scale(), selectedItem, selectionColor);
|
||||||
state->collapsedRowMaterial.setSelectedItem(selectedItem);
|
|
||||||
state->collapsedRowMaterial.setSelectionColor(selectionColor);
|
|
||||||
|
|
||||||
if (state->m_expandedRows.isEmpty()) {
|
if (state->indexFrom() < state->indexTo()) {
|
||||||
state->m_expandedRows.reserve(model->expandedRowCount());
|
if (indexFrom < state->indexFrom()) {
|
||||||
state->m_collapsedRows.reserve(model->collapsedRowCount());
|
for (int i = indexFrom; i < state->indexFrom();
|
||||||
for (int i = 0; i < model->expandedRowCount(); ++i)
|
|
||||||
state->m_expandedRows << new TimelineExpandedRowNode;
|
|
||||||
for (int i = 0; i < model->collapsedRowCount(); ++i)
|
|
||||||
state->m_collapsedRows << new QSGNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->indexFrom < state->indexTo) {
|
|
||||||
if (indexFrom < state->indexFrom) {
|
|
||||||
for (int i = indexFrom; i < state->indexFrom;
|
|
||||||
i+= TimelineItemsGeometry::maxEventsPerNode)
|
i+= TimelineItemsGeometry::maxEventsPerNode)
|
||||||
updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, state->indexFrom),
|
updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode,
|
||||||
model, parentState, state);
|
state->indexFrom()), model, parentState, state);
|
||||||
}
|
}
|
||||||
if (indexTo > state->indexTo) {
|
if (indexTo > state->indexTo()) {
|
||||||
for (int i = state->indexTo; i < indexTo; i+= TimelineItemsGeometry::maxEventsPerNode)
|
for (int i = state->indexTo(); i < indexTo; i+= TimelineItemsGeometry::maxEventsPerNode)
|
||||||
updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), model,
|
updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), model,
|
||||||
parentState, state);
|
parentState, state);
|
||||||
}
|
}
|
||||||
@@ -332,7 +335,7 @@ TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineAbstrac
|
|||||||
if (model->expanded()) {
|
if (model->expanded()) {
|
||||||
for (int row = 0; row < model->expandedRowCount(); ++row) {
|
for (int row = 0; row < model->expandedRowCount(); ++row) {
|
||||||
TimelineExpandedRowNode *rowNode = static_cast<TimelineExpandedRowNode *>(
|
TimelineExpandedRowNode *rowNode = static_cast<TimelineExpandedRowNode *>(
|
||||||
state->m_expandedRows[row]);
|
state->expandedRow(row));
|
||||||
rowNode->material.setScale(
|
rowNode->material.setScale(
|
||||||
QVector2D(spacing / parentState->scale(),
|
QVector2D(spacing / parentState->scale(),
|
||||||
static_cast<qreal>(model->expandedRowHeight(row))) /
|
static_cast<qreal>(model->expandedRowHeight(row))) /
|
||||||
@@ -342,8 +345,7 @@ TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineAbstrac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state->indexFrom = qMin(state->indexFrom, indexFrom);
|
state->updateIndexes(indexFrom, indexTo);
|
||||||
state->indexTo = qMax(state->indexTo, indexTo);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,4 +460,43 @@ void OpaqueColoredPoint2DWithSize::set(float nx, float ny, float nw, float nh, f
|
|||||||
r = nr; g = ng, b = nb; a = 255;
|
r = nr; g = ng, b = nb; a = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimelineItemsRenderPassState::TimelineItemsRenderPassState(const TimelineModel *model) :
|
||||||
|
m_indexFrom(std::numeric_limits<int>::max()), m_indexTo(-1)
|
||||||
|
{
|
||||||
|
m_expandedRows.reserve(model->expandedRowCount());
|
||||||
|
m_collapsedRows.reserve(model->collapsedRowCount());
|
||||||
|
for (int i = 0; i < model->expandedRowCount(); ++i) {
|
||||||
|
TimelineExpandedRowNode *node = new TimelineExpandedRowNode;
|
||||||
|
node->setFlag(QSGNode::OwnedByParent, false);
|
||||||
|
m_expandedRows << node;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < model->collapsedRowCount(); ++i) {
|
||||||
|
QSGNode *node = new QSGNode;
|
||||||
|
node->setFlag(QSGNode::OwnedByParent, false);
|
||||||
|
m_collapsedRows << node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineItemsRenderPassState::~TimelineItemsRenderPassState()
|
||||||
|
{
|
||||||
|
qDeleteAll(m_collapsedRows);
|
||||||
|
qDeleteAll(m_expandedRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineItemsRenderPassState::updateIndexes(int from, int to)
|
||||||
|
{
|
||||||
|
if (from < m_indexFrom)
|
||||||
|
m_indexFrom = from;
|
||||||
|
if (to > m_indexTo)
|
||||||
|
m_indexTo = to;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimelineItemsRenderPassState::updateCollapsedRowMaterial(float xScale, int selectedItem,
|
||||||
|
QColor selectionColor)
|
||||||
|
{
|
||||||
|
m_collapsedRowMaterial.setScale(QVector2D(xScale, 1));
|
||||||
|
m_collapsedRowMaterial.setSelectedItem(selectedItem);
|
||||||
|
m_collapsedRowMaterial.setSelectionColor(selectionColor);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Timeline
|
} // namespace Timeline
|
||||||
|
|||||||
@@ -57,19 +57,26 @@ struct NotesGeometry
|
|||||||
|
|
||||||
const int NotesGeometry::maxNotes = 0xffff / 2;
|
const int NotesGeometry::maxNotes = 0xffff / 2;
|
||||||
|
|
||||||
struct TimelineNotesRenderPassState : public TimelineRenderPass::State
|
class TimelineNotesRenderPassState : public TimelineRenderPass::State
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
TimelineNotesRenderPassState(int expandedRows);
|
TimelineNotesRenderPassState(int expandedRows);
|
||||||
|
~TimelineNotesRenderPassState();
|
||||||
|
|
||||||
QSGGeometryNode *createNode();
|
QSGNode *expandedRow(int row) const { return m_expandedRows[row]; }
|
||||||
|
|
||||||
NotesMaterial material;
|
|
||||||
QSGGeometry nullGeometry;
|
|
||||||
QSGGeometryNode *m_collapsedOverlay;
|
|
||||||
QVector<QSGNode *> m_expandedRows;
|
|
||||||
|
|
||||||
QSGNode *collapsedOverlay() const { return m_collapsedOverlay; }
|
QSGNode *collapsedOverlay() const { return m_collapsedOverlay; }
|
||||||
const QVector<QSGNode *> &expandedRows() const { return m_expandedRows; }
|
const QVector<QSGNode *> &expandedRows() const { return m_expandedRows; }
|
||||||
|
|
||||||
|
QSGGeometry *nullGeometry() { return &m_nullGeometry; }
|
||||||
|
NotesMaterial *material() { return &m_material; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSGGeometryNode *createNode();
|
||||||
|
|
||||||
|
NotesMaterial m_material;
|
||||||
|
QSGGeometry m_nullGeometry;
|
||||||
|
QSGGeometryNode *m_collapsedOverlay;
|
||||||
|
QVector<QSGNode *> m_expandedRows;
|
||||||
};
|
};
|
||||||
|
|
||||||
const QSGGeometry::AttributeSet &NotesGeometry::point2DWithDistanceFromTop()
|
const QSGGeometry::AttributeSet &NotesGeometry::point2DWithDistanceFromTop()
|
||||||
@@ -135,21 +142,21 @@ TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineAbstrac
|
|||||||
collapsed << timelineIndex;
|
collapsed << timelineIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGGeometryNode *collapsedNode = state->m_collapsedOverlay;
|
QSGGeometryNode *collapsedNode = static_cast<QSGGeometryNode *>(state->collapsedOverlay());
|
||||||
|
|
||||||
if (collapsed.count() > 0) {
|
if (collapsed.count() > 0) {
|
||||||
collapsedNode->setGeometry(NotesGeometry::createGeometry(collapsed, model, parentState,
|
collapsedNode->setGeometry(NotesGeometry::createGeometry(collapsed, model, parentState,
|
||||||
true));
|
true));
|
||||||
collapsedNode->setFlag(QSGGeometryNode::OwnsGeometry, true);
|
collapsedNode->setFlag(QSGGeometryNode::OwnsGeometry, true);
|
||||||
} else {
|
} else {
|
||||||
collapsedNode->setGeometry(&state->nullGeometry);
|
collapsedNode->setGeometry(state->nullGeometry());
|
||||||
collapsedNode->setFlag(QSGGeometryNode::OwnsGeometry, false);
|
collapsedNode->setFlag(QSGGeometryNode::OwnsGeometry, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int row = 0; row < model->expandedRowCount(); ++row) {
|
for (int row = 0; row < model->expandedRowCount(); ++row) {
|
||||||
QSGGeometryNode *rowNode = static_cast<QSGGeometryNode *>(state->m_expandedRows[row]);
|
QSGGeometryNode *rowNode = static_cast<QSGGeometryNode *>(state->expandedRow(row));
|
||||||
if (expanded[row].isEmpty()) {
|
if (expanded[row].isEmpty()) {
|
||||||
rowNode->setGeometry(&state->nullGeometry);
|
rowNode->setGeometry(state->nullGeometry());
|
||||||
rowNode->setFlag(QSGGeometryNode::OwnsGeometry, false);
|
rowNode->setFlag(QSGGeometryNode::OwnsGeometry, false);
|
||||||
} else {
|
} else {
|
||||||
rowNode->setGeometry(NotesGeometry::createGeometry(expanded[row], model, parentState,
|
rowNode->setGeometry(NotesGeometry::createGeometry(expanded[row], model, parentState,
|
||||||
@@ -162,20 +169,27 @@ TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineAbstrac
|
|||||||
}
|
}
|
||||||
|
|
||||||
TimelineNotesRenderPassState::TimelineNotesRenderPassState(int numExpandedRows) :
|
TimelineNotesRenderPassState::TimelineNotesRenderPassState(int numExpandedRows) :
|
||||||
nullGeometry(NotesGeometry::point2DWithDistanceFromTop(), 0)
|
m_nullGeometry(NotesGeometry::point2DWithDistanceFromTop(), 0)
|
||||||
{
|
{
|
||||||
material.setFlag(QSGMaterial::Blending, true);
|
m_material.setFlag(QSGMaterial::Blending, true);
|
||||||
m_expandedRows.reserve(numExpandedRows);
|
m_expandedRows.reserve(numExpandedRows);
|
||||||
for (int i = 0; i < numExpandedRows; ++i)
|
for (int i = 0; i < numExpandedRows; ++i)
|
||||||
m_expandedRows << createNode();
|
m_expandedRows << createNode();
|
||||||
m_collapsedOverlay = createNode();
|
m_collapsedOverlay = createNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimelineNotesRenderPassState::~TimelineNotesRenderPassState()
|
||||||
|
{
|
||||||
|
qDeleteAll(m_expandedRows);
|
||||||
|
delete m_collapsedOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
QSGGeometryNode *TimelineNotesRenderPassState::createNode()
|
QSGGeometryNode *TimelineNotesRenderPassState::createNode()
|
||||||
{
|
{
|
||||||
QSGGeometryNode *node = new QSGGeometryNode;
|
QSGGeometryNode *node = new QSGGeometryNode;
|
||||||
node->setGeometry(&nullGeometry);
|
node->setGeometry(&m_nullGeometry);
|
||||||
node->setMaterial(&material);
|
node->setMaterial(&m_material);
|
||||||
|
node->setFlag(QSGNode::OwnedByParent, false);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ QSGSimpleRectNode *createSelectionNode()
|
|||||||
QSGSimpleRectNode *selectionNode = new QSGSimpleRectNode;
|
QSGSimpleRectNode *selectionNode = new QSGSimpleRectNode;
|
||||||
selectionNode->material()->setFlag(QSGMaterial::Blending, false);
|
selectionNode->material()->setFlag(QSGMaterial::Blending, false);
|
||||||
selectionNode->setRect(0, 0, 0, 0);
|
selectionNode->setRect(0, 0, 0, 0);
|
||||||
|
selectionNode->setFlag(QSGNode::OwnedByParent, false);
|
||||||
QSGSimpleRectNode *selectionChild = new QSGSimpleRectNode;
|
QSGSimpleRectNode *selectionChild = new QSGSimpleRectNode;
|
||||||
selectionChild->material()->setFlag(QSGMaterial::Blending, false);
|
selectionChild->material()->setFlag(QSGMaterial::Blending, false);
|
||||||
selectionChild->setRect(0, 0, 0, 0);
|
selectionChild->setRect(0, 0, 0, 0);
|
||||||
@@ -47,12 +48,16 @@ QSGSimpleRectNode *createSelectionNode()
|
|||||||
return selectionNode;
|
return selectionNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TimelineSelectionRenderPassState : public TimelineRenderPass::State {
|
class TimelineSelectionRenderPassState : public TimelineRenderPass::State {
|
||||||
QSGSimpleRectNode *m_expandedOverlay;
|
public:
|
||||||
QSGSimpleRectNode *m_collapsedOverlay;
|
TimelineSelectionRenderPassState();
|
||||||
|
~TimelineSelectionRenderPassState();
|
||||||
|
|
||||||
QSGNode *expandedOverlay() const { return m_expandedOverlay; }
|
QSGNode *expandedOverlay() const { return m_expandedOverlay; }
|
||||||
QSGNode *collapsedOverlay() const { return m_collapsedOverlay; }
|
QSGNode *collapsedOverlay() const { return m_collapsedOverlay; }
|
||||||
|
private:
|
||||||
|
QSGSimpleRectNode *m_expandedOverlay;
|
||||||
|
QSGSimpleRectNode *m_collapsedOverlay;
|
||||||
};
|
};
|
||||||
|
|
||||||
TimelineRenderPass::State *TimelineSelectionRenderPass::update(
|
TimelineRenderPass::State *TimelineSelectionRenderPass::update(
|
||||||
@@ -67,17 +72,14 @@ TimelineRenderPass::State *TimelineSelectionRenderPass::update(
|
|||||||
|
|
||||||
TimelineSelectionRenderPassState *state;
|
TimelineSelectionRenderPassState *state;
|
||||||
|
|
||||||
if (oldState == 0) {
|
if (oldState == 0)
|
||||||
state = new TimelineSelectionRenderPassState;
|
state = new TimelineSelectionRenderPassState;
|
||||||
state->m_expandedOverlay = createSelectionNode();
|
else
|
||||||
state->m_collapsedOverlay = createSelectionNode();
|
|
||||||
} else {
|
|
||||||
state = static_cast<TimelineSelectionRenderPassState *>(oldState);
|
state = static_cast<TimelineSelectionRenderPassState *>(oldState);
|
||||||
}
|
|
||||||
|
|
||||||
QSGSimpleRectNode *selectionNode = static_cast<QSGSimpleRectNode *>(model->expanded() ?
|
QSGSimpleRectNode *selectionNode = static_cast<QSGSimpleRectNode *>(model->expanded() ?
|
||||||
state->m_expandedOverlay :
|
state->expandedOverlay() :
|
||||||
state->m_collapsedOverlay);
|
state->collapsedOverlay());
|
||||||
|
|
||||||
QSGSimpleRectNode *child = static_cast<QSGSimpleRectNode *>(selectionNode->firstChild());
|
QSGSimpleRectNode *child = static_cast<QSGSimpleRectNode *>(selectionNode->firstChild());
|
||||||
int selectedItem = renderer->selectedItem();
|
int selectedItem = renderer->selectedItem();
|
||||||
@@ -147,4 +149,15 @@ TimelineSelectionRenderPass::TimelineSelectionRenderPass()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimelineSelectionRenderPassState::TimelineSelectionRenderPassState() :
|
||||||
|
m_expandedOverlay(createSelectionNode()), m_collapsedOverlay(createSelectionNode())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TimelineSelectionRenderPassState::~TimelineSelectionRenderPassState()
|
||||||
|
{
|
||||||
|
delete m_collapsedOverlay;
|
||||||
|
delete m_expandedOverlay;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Timeline
|
} // namespace Timeline
|
||||||
|
|||||||
@@ -40,17 +40,27 @@ public:
|
|||||||
BindingLoopMaterial();
|
BindingLoopMaterial();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BindingLoopsRenderPassState : public Timeline::TimelineRenderPass::State {
|
class BindingLoopsRenderPassState : public Timeline::TimelineRenderPass::State {
|
||||||
BindingLoopsRenderPassState() : indexFrom(std::numeric_limits<int>::max()), indexTo(-1) {}
|
public:
|
||||||
BindingLoopMaterial material;
|
BindingLoopsRenderPassState(const QmlProfilerRangeModel *model);
|
||||||
int indexFrom;
|
~BindingLoopsRenderPassState();
|
||||||
int indexTo;
|
|
||||||
|
|
||||||
QVector<QSGNode *> m_expandedRows;
|
BindingLoopMaterial *material() { return &m_material; }
|
||||||
|
void updateIndexes(int from, int to);
|
||||||
|
|
||||||
|
int indexFrom() const { return m_indexFrom; }
|
||||||
|
int indexTo() const { return m_indexTo; }
|
||||||
|
|
||||||
|
QSGNode *expandedRow(int row) const { return m_expandedRows[row]; }
|
||||||
const QVector<QSGNode *> &expandedRows() const { return m_expandedRows; }
|
const QVector<QSGNode *> &expandedRows() const { return m_expandedRows; }
|
||||||
|
|
||||||
QSGNode *m_collapsedOverlay;
|
|
||||||
QSGNode *collapsedOverlay() const { return m_collapsedOverlay; }
|
QSGNode *collapsedOverlay() const { return m_collapsedOverlay; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<QSGNode *> m_expandedRows;
|
||||||
|
QSGNode *m_collapsedOverlay;
|
||||||
|
BindingLoopMaterial m_material;
|
||||||
|
int m_indexFrom;
|
||||||
|
int m_indexTo;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Point2DWithOffset {
|
struct Point2DWithOffset {
|
||||||
@@ -111,14 +121,14 @@ void updateNodes(const QmlProfilerRangeModel *model, int from, int to,
|
|||||||
for (int i = 0; i < model->expandedRowCount(); ++i) {
|
for (int i = 0; i < model->expandedRowCount(); ++i) {
|
||||||
BindlingLoopsGeometry &row = expandedPerRow[i];
|
BindlingLoopsGeometry &row = expandedPerRow[i];
|
||||||
if (row.usedVertices > 0) {
|
if (row.usedVertices > 0) {
|
||||||
row.allocate(&state->material);
|
row.allocate(state->material());
|
||||||
state->m_expandedRows[i]->appendChildNode(row.node);
|
state->expandedRow(i)->appendChildNode(row.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collapsed.usedVertices > 0) {
|
if (collapsed.usedVertices > 0) {
|
||||||
collapsed.allocate(&state->material);
|
collapsed.allocate(state->material());
|
||||||
state->m_collapsedOverlay->appendChildNode(collapsed.node);
|
state->collapsedOverlay()->appendChildNode(collapsed.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rowHeight = Timeline::TimelineModel::defaultRowHeight();
|
int rowHeight = Timeline::TimelineModel::defaultRowHeight();
|
||||||
@@ -163,25 +173,20 @@ Timeline::TimelineRenderPass::State *QmlProfilerBindingLoopsRenderPass::update(
|
|||||||
return oldState;
|
return oldState;
|
||||||
|
|
||||||
BindingLoopsRenderPassState *state;
|
BindingLoopsRenderPassState *state;
|
||||||
if (oldState == 0) {
|
if (oldState == 0)
|
||||||
state = new BindingLoopsRenderPassState;
|
state = new BindingLoopsRenderPassState(model);
|
||||||
state->m_expandedRows.reserve(model->expandedRowCount());
|
else
|
||||||
for (int i = 0; i < model->expandedRowCount(); ++i)
|
|
||||||
state->m_expandedRows << new QSGNode;
|
|
||||||
state->m_collapsedOverlay = new QSGNode;
|
|
||||||
} else {
|
|
||||||
state = static_cast<BindingLoopsRenderPassState *>(oldState);
|
state = static_cast<BindingLoopsRenderPassState *>(oldState);
|
||||||
}
|
|
||||||
|
|
||||||
if (state->indexFrom < state->indexTo) {
|
if (state->indexFrom() < state->indexTo()) {
|
||||||
if (indexFrom < state->indexFrom) {
|
if (indexFrom < state->indexFrom()) {
|
||||||
for (int i = indexFrom; i < state->indexFrom;
|
for (int i = indexFrom; i < state->indexFrom();
|
||||||
i += BindlingLoopsGeometry::maxEventsPerNode)
|
i += BindlingLoopsGeometry::maxEventsPerNode)
|
||||||
updateNodes(model, i, qMin(i + BindlingLoopsGeometry::maxEventsPerNode,
|
updateNodes(model, i, qMin(i + BindlingLoopsGeometry::maxEventsPerNode,
|
||||||
state->indexFrom), parentState, state);
|
state->indexFrom()), parentState, state);
|
||||||
}
|
}
|
||||||
if (indexTo > state->indexTo) {
|
if (indexTo > state->indexTo()) {
|
||||||
for (int i = state->indexTo; i < indexTo; i+= BindlingLoopsGeometry::maxEventsPerNode)
|
for (int i = state->indexTo(); i < indexTo; i+= BindlingLoopsGeometry::maxEventsPerNode)
|
||||||
updateNodes(model, i, qMin(i + BindlingLoopsGeometry::maxEventsPerNode, indexTo),
|
updateNodes(model, i, qMin(i + BindlingLoopsGeometry::maxEventsPerNode, indexTo),
|
||||||
parentState, state);
|
parentState, state);
|
||||||
}
|
}
|
||||||
@@ -191,8 +196,7 @@ Timeline::TimelineRenderPass::State *QmlProfilerBindingLoopsRenderPass::update(
|
|||||||
parentState, state);
|
parentState, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
state->indexFrom = qMin(state->indexFrom, indexFrom);
|
state->updateIndexes(indexFrom, indexTo);
|
||||||
state->indexTo = qMax(state->indexTo, indexTo);
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,6 +358,32 @@ void Point2DWithOffset::set(float nx, float ny, float nx2, float ny2)
|
|||||||
x = nx; y = ny; x2 = nx2; y2 = ny2;
|
x = nx; y = ny; x2 = nx2; y2 = ny2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BindingLoopsRenderPassState::BindingLoopsRenderPassState(const QmlProfilerRangeModel *model) :
|
||||||
|
m_indexFrom(std::numeric_limits<int>::max()), m_indexTo(-1)
|
||||||
|
{
|
||||||
|
m_collapsedOverlay = new QSGNode;
|
||||||
|
m_collapsedOverlay->setFlag(QSGNode::OwnedByParent, false);
|
||||||
|
m_expandedRows.reserve(model->expandedRowCount());
|
||||||
|
for (int i = 0; i < model->expandedRowCount(); ++i) {
|
||||||
|
QSGNode *node = new QSGNode;
|
||||||
|
node->setFlag(QSGNode::OwnedByParent, false);
|
||||||
|
m_expandedRows << node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BindingLoopsRenderPassState::~BindingLoopsRenderPassState()
|
||||||
|
{
|
||||||
|
delete m_collapsedOverlay;
|
||||||
|
qDeleteAll(m_expandedRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingLoopsRenderPassState::updateIndexes(int from, int to)
|
||||||
|
{
|
||||||
|
if (from < m_indexFrom)
|
||||||
|
m_indexFrom = from;
|
||||||
|
if (to > m_indexTo)
|
||||||
|
m_indexTo = to;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user