Merge remote-tracking branch 'origin/3.1'

This commit is contained in:
Kai Koehne
2014-06-04 10:16:52 +02:00
3 changed files with 286 additions and 107 deletions

View File

@@ -23,29 +23,60 @@
#include "qmlprofiler/singlecategorytimelinemodel_p.h" #include "qmlprofiler/singlecategorytimelinemodel_p.h"
#include <QDebug> #include <QDebug>
#include <QSize>
namespace QmlProfilerExtension { namespace QmlProfilerExtension {
namespace Internal { namespace Internal {
using namespace QmlProfiler; using namespace QmlProfiler;
enum CacheState {
Uncached, // After loading started (or some other proof of existence) or after uncaching
ToBeCached, // After determining the pixmap is to be cached but before knowing its size
Cached, // After caching a pixmap or determining the size of a ToBeCached pixmap
Uncacheable, // If loading failed without ToBeCached or after a corrupt pixmap has been uncached
Corrupt // If after ToBeCached we learn that loading failed
};
enum LoadState {
Initial,
Loading,
Finished,
Error
};
struct PixmapState {
PixmapState(int width, int height, CacheState cache = Uncached) :
size(width, height), started(-1), loadState(Initial), cacheState(cache) {}
PixmapState(CacheState cache = Uncached) : started(-1), loadState(Initial), cacheState(cache) {}
QSize size;
int started;
LoadState loadState;
CacheState cacheState;
};
struct Pixmap {
Pixmap() {}
Pixmap(const QString &url) : url(url), sizes(1) {}
QString url;
QVector<PixmapState> sizes;
};
class PixmapCacheModel::PixmapCacheModelPrivate : class PixmapCacheModel::PixmapCacheModelPrivate :
public SortedTimelineModel<PixmapCacheEvent, public SortedTimelineModel<PixmapCacheEvent,
SingleCategoryTimelineModel::SingleCategoryTimelineModelPrivate> SingleCategoryTimelineModel::SingleCategoryTimelineModelPrivate>
{ {
public: public:
void computeCacheSizes(); void computeMaxCacheSize();
void resizeUnfinishedLoads(); void resizeUnfinishedLoads();
void flattenLoads(); void flattenLoads();
void computeRowCounts(); int updateCacheCount(int lastCacheSizeEvent, qint64 startTime, qint64 pixSize,
PixmapCacheEvent &newEvent);
QVector < QString > pixmapUrls; QVector<Pixmap> pixmaps;
QVector < QPair<int, int> > pixmapSizes;
int expandedRowCount;
int collapsedRowCount; int collapsedRowCount;
void addVP(QVariantList &l, QString label, qint64 time) const; void addVP(QVariantList &l, QString label, qint64 time) const;
qint64 minCacheSize;
qint64 maxCacheSize; qint64 maxCacheSize;
private: private:
Q_DECLARE_PUBLIC(PixmapCacheModel) Q_DECLARE_PUBLIC(PixmapCacheModel)
@@ -58,7 +89,7 @@ PixmapCacheModel::PixmapCacheModel(QObject *parent)
{ {
Q_D(PixmapCacheModel); Q_D(PixmapCacheModel);
d->collapsedRowCount = 1; d->collapsedRowCount = 1;
d->expandedRowCount = 1; d->maxCacheSize = 1;
} }
int PixmapCacheModel::categoryDepth(int categoryIndex) const int PixmapCacheModel::categoryDepth(int categoryIndex) const
@@ -68,7 +99,7 @@ int PixmapCacheModel::categoryDepth(int categoryIndex) const
if (isEmpty()) if (isEmpty())
return 1; return 1;
if (d->expanded) if (d->expanded)
return d->expandedRowCount; return d->pixmaps.count() + 2;
return d->collapsedRowCount; return d->collapsedRowCount;
} }
@@ -76,40 +107,33 @@ int PixmapCacheModel::getEventRow(int index) const
{ {
Q_D(const PixmapCacheModel); Q_D(const PixmapCacheModel);
if (d->expanded) if (d->expanded)
return d->range(index).rowNumberExpanded; return getEventId(index) + 1;
return d->range(index).rowNumberCollapsed; return d->range(index).rowNumberCollapsed;
} }
int PixmapCacheModel::getEventId(int index) const int PixmapCacheModel::getEventId(int index) const
{ {
Q_D(const PixmapCacheModel); Q_D(const PixmapCacheModel);
return d->range(index).eventId; return d->range(index).pixmapEventType == PixmapCacheCountChanged ?
0 : d->range(index).urlIndex + 1;
} }
QColor PixmapCacheModel::getColor(int index) const QColor PixmapCacheModel::getColor(int index) const
{ {
Q_D(const PixmapCacheModel); Q_D(const PixmapCacheModel);
if (d->range(index).pixmapEventType == PixmapCacheCountChanged) if (d->range(index).pixmapEventType == PixmapCacheCountChanged)
return QColor::fromHsl(240, 76, 166); return getColorByHue(PixmapCacheCountHue);
int ndx = getEventId(index); return getEventColor(index);
return QColor::fromHsl((ndx*25)%360, 76, 166);
} }
float PixmapCacheModel::getHeight(int index) const float PixmapCacheModel::getHeight(int index) const
{ {
Q_D(const PixmapCacheModel); Q_D(const PixmapCacheModel);
if (d->range(index).pixmapEventType == PixmapCacheCountChanged) { if (d->range(index).pixmapEventType == PixmapCacheCountChanged)
float scale = d->maxCacheSize - d->minCacheSize; return 0.15 + (float)d->range(index).cacheSize * 0.85 / (float)d->maxCacheSize;
float fraction = 1.0f; else
if (scale > 1) return 1.0f;
fraction = (float)(d->range(index).cacheSize -
d->minCacheSize) / scale;
return fraction * 0.85f + 0.15f;
}
return 1.0f;
} }
QString getFilenameOnly(QString absUrl) QString getFilenameOnly(QString absUrl)
@@ -137,11 +161,13 @@ const QVariantList PixmapCacheModel::getLabelsForCategory(int category) const
result << element; result << element;
} }
for (int i=0; i < d->pixmapUrls.count(); i++) { for (int i=0; i < d->pixmaps.count(); i++) {
// Loading // Loading
QVariantMap element; QVariantMap element;
element.insert(QLatin1String("displayName"), QVariant(getFilenameOnly(d->pixmapUrls[i]))); element.insert(QLatin1String("displayName"),
element.insert(QLatin1String("description"), QVariant(getFilenameOnly(d->pixmapUrls[i]))); QVariant(getFilenameOnly(d->pixmaps[i].url)));
element.insert(QLatin1String("description"),
QVariant(getFilenameOnly(d->pixmaps[i].url)));
element.insert(QLatin1String("id"), QVariant(i+1)); element.insert(QLatin1String("id"), QVariant(i+1));
result << element; result << element;
@@ -181,20 +207,23 @@ const QVariantList PixmapCacheModel::getEventDetails(int index) const
{ {
QVariantMap res; QVariantMap res;
res.insert(tr("File"), QVariant(getFilenameOnly(d->pixmapUrls[ev->urlIndex]))); res.insert(tr("File"), QVariant(getFilenameOnly(d->pixmaps[ev->urlIndex].url)));
result << res; result << res;
} }
{ {
QVariantMap res; QVariantMap res;
res.insert(tr("Width"), QVariant(QString::fromLatin1("%1 px").arg(d->pixmapSizes[ev->urlIndex].first))); res.insert(tr("Width"), QVariant(QString::fromLatin1("%1 px")
.arg(d->pixmaps[ev->urlIndex].sizes[ev->sizeIndex].size.width())));
result << res; result << res;
res.clear(); res.clear();
res.insert(tr("Height"), QVariant(QString::fromLatin1("%1 px").arg(d->pixmapSizes[ev->urlIndex].second))); res.insert(tr("Height"), QVariant(QString::fromLatin1("%1 px")
.arg(d->pixmaps[ev->urlIndex].sizes[ev->sizeIndex].size.height())));
result << res; result << res;
} }
if (ev->pixmapEventType == PixmapLoadingStarted && ev->cacheSize == -1) { if (ev->pixmapEventType == PixmapLoadingStarted &&
d->pixmaps[ev->urlIndex].sizes[ev->sizeIndex].loadState != Finished) {
QVariantMap res; QVariantMap res;
res.insert(tr("Result"), QVariant(QLatin1String("Load Error"))); res.insert(tr("Result"), QVariant(QLatin1String("Load Error")));
result << res; result << res;
@@ -203,6 +232,36 @@ const QVariantList PixmapCacheModel::getEventDetails(int index) const
return result; return result;
} }
/* Ultimately there is no way to know which cache entry a given event refers to as long as we only
* receive the pixmap URL from the application. Multiple copies of different sizes may be cached
* for each URL. However, we can apply some heuristics to make the result somewhat plausible by
* using the following assumptions:
*
* - PixmapSizeKnown will happen at most once for every cache entry.
* - PixmapSizeKnown cannot happen for entries with PixmapLoadingError and vice versa.
* - PixmapCacheCountChanged can happen for entries with PixmapLoadingError but doesn't have to.
* - Decreasing PixmapCacheCountChanged events can only happen for entries that have seen an
* increasing PixmapCacheCountChanged (but that may have happened before the trace).
* - PixmapCacheCountChanged can happen before or after PixmapSizeKnown.
* - For every PixmapLoadingFinished or PixmapLoadingError there is exactly one
* PixmapLoadingStarted event, but it may be before the trace.
* - For every PixmapLoadingStarted there is exactly one PixmapLoadingFinished or
* PixmapLoadingError, but it may be after the trace.
* - Decreasing PixmapCacheCountChanged events in the presence of corrupt cache entries are more
* likely to clear those entries than other, correctly loaded ones.
* - Increasing PixmapCacheCountChanged events are more likely to refer to correctly loaded entries
* than to ones with PixmapLoadingError.
* - PixmapLoadingFinished and PixmapLoadingError are more likely to refer to cache entries that
* have seen a PixmapLoadingStarted than to ones that haven't.
*
* For each URL we keep an ordered list of pixmaps possibly being loaded and assign new events to
* the first entry that "fits". If multiple sizes of the same pixmap are being loaded concurrently
* we generally assume that the PixmapLoadingFinished and PixmapLoadingError events occur in the
* order we learn about the existence of these sizes, subject to the above constraints. This is not
* necessarily the order the pixmaps are really loaded but it's the best we can do with the given
* information. If they're loaded sequentially the representation is correct.
*/
void PixmapCacheModel::loadData() void PixmapCacheModel::loadData()
{ {
Q_D(PixmapCacheModel); Q_D(PixmapCacheModel);
@@ -213,8 +272,6 @@ void PixmapCacheModel::loadData()
int lastCacheSizeEvent = -1; int lastCacheSizeEvent = -1;
int cumulatedCount = 0; int cumulatedCount = 0;
QVector < int > pixmapStartPoints;
QVector < int > pixmapCachePoints;
foreach (const QmlProfilerDataModel::QmlEventData &event, simpleModel->getEvents()) { foreach (const QmlProfilerDataModel::QmlEventData &event, simpleModel->getEvents()) {
if (!eventAccepted(event)) if (!eventAccepted(event))
@@ -224,69 +281,189 @@ void PixmapCacheModel::loadData()
newEvent.pixmapEventType = event.bindingType; newEvent.pixmapEventType = event.bindingType;
qint64 startTime = event.startTime; qint64 startTime = event.startTime;
bool isNewEntry = false; newEvent.urlIndex = -1;
newEvent.urlIndex = d->pixmapUrls.indexOf(event.location.filename); for (QVector<Pixmap>::const_iterator it(d->pixmaps.cend()); it != d->pixmaps.cbegin();) {
if (newEvent.urlIndex == -1) { if ((--it)->url == event.location.filename) {
isNewEntry = true; newEvent.urlIndex = it - d->pixmaps.cbegin();
newEvent.urlIndex = d->pixmapUrls.count(); break;
d->pixmapUrls << event.location.filename; }
d->pixmapSizes << QPair<int, int>(0,0); // default value
pixmapStartPoints << -1; // dummy value to be filled by load event
pixmapCachePoints << -1; // dummy value to be filled by cache event
} }
newEvent.eventId = newEvent.urlIndex + 1; newEvent.sizeIndex = -1;
newEvent.rowNumberExpanded = newEvent.urlIndex + 2; if (newEvent.urlIndex == -1) {
newEvent.urlIndex = d->pixmaps.count();
d->pixmaps << Pixmap(event.location.filename);
}
Pixmap &pixmap = d->pixmaps[newEvent.urlIndex];
switch (newEvent.pixmapEventType) { switch (newEvent.pixmapEventType) {
case PixmapSizeKnown: // pixmap size case PixmapSizeKnown: {// pixmap size
d->pixmapSizes[newEvent.urlIndex] = QPair<int,int>((int)event.numericData1, (int)event.numericData2); // Look for pixmaps for which we don't know the size, yet and which have actually been
if (pixmapCachePoints[newEvent.urlIndex] == -1) // loaded.
for (QVector<PixmapState>::iterator i(pixmap.sizes.begin());
i != pixmap.sizes.end(); ++i) {
if (i->size.isValid() || i->cacheState == Uncacheable || i->cacheState == Corrupt)
continue;
// We can't have cached it before we knew the size
Q_ASSERT(i->cacheState != Cached);
i->size.setWidth(event.numericData1);
i->size.setHeight(event.numericData2);
newEvent.sizeIndex = i - pixmap.sizes.begin();
break; break;
// else fall through and update cache size }
newEvent.pixmapEventType = PixmapCacheCountChanged;
if (newEvent.sizeIndex == -1) {
newEvent.sizeIndex = pixmap.sizes.length();
pixmap.sizes << PixmapState(event.numericData1, event.numericData2);
}
PixmapState &state = pixmap.sizes[newEvent.sizeIndex];
if (state.cacheState == ToBeCached) {
lastCacheSizeEvent = d->updateCacheCount(lastCacheSizeEvent, startTime,
state.size.width() * state.size.height(), newEvent);
state.cacheState = Cached;
}
break;
}
case PixmapCacheCountChanged: {// Cache Size Changed Event case PixmapCacheCountChanged: {// Cache Size Changed Event
startTime = event.startTime + 1; // delay 1 ns for proper sorting startTime = event.startTime + 1; // delay 1 ns for proper sorting
newEvent.eventId = 0;
newEvent.rowNumberExpanded = 1;
newEvent.rowNumberCollapsed = 1;
qint64 pixSize = d->pixmapSizes[newEvent.urlIndex].first * d->pixmapSizes[newEvent.urlIndex].second; bool uncache = cumulatedCount > event.numericData3;
qint64 prevSize = 0; cumulatedCount = event.numericData3;
if (lastCacheSizeEvent != -1) { qint64 pixSize = 0;
prevSize = d->range(lastCacheSizeEvent).cacheSize;
if (pixmapCachePoints[newEvent.urlIndex] == -1) { // First try to find a preferred pixmap, which either is Corrupt and will be uncached
// else it's a synthesized update and doesn't have a valid cache count // or is uncached and will be cached.
if (event.numericData3 < cumulatedCount) for (QVector<PixmapState>::iterator i(pixmap.sizes.begin());
pixSize = -pixSize; i != pixmap.sizes.end(); ++i) {
cumulatedCount = event.numericData3; if (uncache && i->cacheState == Corrupt) {
newEvent.sizeIndex = i - pixmap.sizes.begin();
i->cacheState = Uncacheable;
break;
} else if (!uncache && i->cacheState == Uncached) {
newEvent.sizeIndex = i - pixmap.sizes.begin();
if (i->size.isValid()) {
pixSize = i->size.width() * i->size.height();
i->cacheState = Cached;
} else {
i->cacheState = ToBeCached;
}
break;
} }
d->insertEnd(lastCacheSizeEvent, startTime - d->range(lastCacheSizeEvent).start);
} }
newEvent.cacheSize = prevSize + pixSize;
lastCacheSizeEvent = d->insertStart(startTime, newEvent); // If none found, check for cached or ToBeCached pixmaps that shall be uncached or
pixmapCachePoints[newEvent.urlIndex] = lastCacheSizeEvent; // Error pixmaps that become corrupt cache entries. We also accept Initial to be
// uncached as we may have missed the matching PixmapCacheCountChanged that cached it.
if (newEvent.sizeIndex == -1) {
for (QVector<PixmapState>::iterator i(pixmap.sizes.begin());
i != pixmap.sizes.end(); ++i) {
if (uncache && (i->cacheState == Cached || i->cacheState == ToBeCached ||
i->cacheState == Uncached)) {
newEvent.sizeIndex = i - pixmap.sizes.begin();
if (i->size.isValid())
pixSize = -i->size.width() * i->size.height();
i->cacheState = Uncached;
break;
} else if (!uncache && i->cacheState == Uncacheable) {
newEvent.sizeIndex = i - pixmap.sizes.begin();
i->cacheState = Corrupt;
break;
}
}
}
// If that does't work, create a new entry.
if (newEvent.sizeIndex == -1) {
newEvent.sizeIndex = pixmap.sizes.length();
pixmap.sizes << PixmapState(uncache ? Uncached : ToBeCached);
}
lastCacheSizeEvent = d->updateCacheCount(lastCacheSizeEvent, startTime, pixSize,
newEvent);
break; break;
} }
case PixmapLoadingStarted: // Load case PixmapLoadingStarted: // Load
pixmapStartPoints[newEvent.urlIndex] = d->insertStart(startTime, newEvent); // Look for a pixmap that hasn't been started, yet. There may have been a refcount
// event, which we ignore.
for (QVector<PixmapState>::const_iterator i(pixmap.sizes.cbegin());
i != pixmap.sizes.cend(); ++i) {
if (i->loadState == Initial) {
newEvent.sizeIndex = i - pixmap.sizes.cbegin();
break;
}
}
if (newEvent.sizeIndex == -1) {
newEvent.sizeIndex = pixmap.sizes.length();
pixmap.sizes << PixmapState();
}
pixmap.sizes[newEvent.sizeIndex].started = d->insertStart(startTime, newEvent);
pixmap.sizes[newEvent.sizeIndex].loadState = Loading;
break; break;
case PixmapLoadingFinished: case PixmapLoadingFinished:
case PixmapLoadingError: { case PixmapLoadingError: {
int loadIndex = pixmapStartPoints[newEvent.urlIndex]; // First try to find one that has already started
if (!isNewEntry && loadIndex != -1) { for (QVector<PixmapState>::const_iterator i(pixmap.sizes.cbegin());
d->insertEnd(loadIndex, startTime - d->range(loadIndex).start); i != pixmap.sizes.cend(); ++i) {
} else { if (i->loadState != Loading)
// if it's a new entry it means that we don't have a corresponding start continue;
newEvent.pixmapEventType = PixmapLoadingStarted; // Pixmaps with known size cannot be errors and vice versa
newEvent.rowNumberExpanded = newEvent.urlIndex + 2; if (newEvent.pixmapEventType == PixmapLoadingError && i->size.isValid())
loadIndex = d->insert(traceStartTime(), startTime - traceStartTime(), newEvent); continue;
pixmapStartPoints[newEvent.urlIndex] = loadIndex;
newEvent.sizeIndex = i - pixmap.sizes.cbegin();
break;
}
// If none was found use any other compatible one
if (newEvent.sizeIndex == -1) {
for (QVector<PixmapState>::const_iterator i(pixmap.sizes.cbegin());
i != pixmap.sizes.cend(); ++i) {
if (i->loadState != Initial)
continue;
// Pixmaps with known size cannot be errors and vice versa
if (newEvent.pixmapEventType == PixmapLoadingError && i->size.isValid())
continue;
newEvent.sizeIndex = i - pixmap.sizes.cbegin();
break;
}
}
// If again none was found, create one.
if (newEvent.sizeIndex == -1) {
newEvent.sizeIndex = pixmap.sizes.length();
pixmap.sizes << PixmapState();
}
PixmapState &state = pixmap.sizes[newEvent.sizeIndex];
// If the pixmap loading wasn't started, start it at traceStartTime()
if (state.loadState == Initial) {
newEvent.pixmapEventType = PixmapLoadingStarted;
state.started = d->insert(traceStartTime(), startTime - traceStartTime(), newEvent);
}
d->insertEnd(state.started, startTime - d->range(state.started).start);
if (newEvent.pixmapEventType == PixmapLoadingError) {
state.loadState = Error;
switch (state.cacheState) {
case Uncached:
state.cacheState = Uncacheable;
break;
case ToBeCached:
state.cacheState = Corrupt;
break;
default:
// Cached cannot happen as size would have to be known and Corrupt or
// Uncacheable cannot happen as we only accept one finish or error event per
// pixmap.
Q_ASSERT(false);
}
} else {
state.loadState = Finished;
} }
if (event.bindingType == PixmapLoadingFinished)
d->data(loadIndex).cacheSize = 1; // use count to mark success
else
d->data(loadIndex).cacheSize = -1; // ... or failure
break; break;
} }
default: default:
@@ -302,9 +479,8 @@ void PixmapCacheModel::loadData()
d->resizeUnfinishedLoads(); d->resizeUnfinishedLoads();
d->computeCacheSizes(); d->computeMaxCacheSize();
d->flattenLoads(); d->flattenLoads();
d->computeRowCounts();
d->computeNesting(); d->computeNesting();
d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
@@ -313,25 +489,21 @@ void PixmapCacheModel::loadData()
void PixmapCacheModel::clear() void PixmapCacheModel::clear()
{ {
Q_D(PixmapCacheModel); Q_D(PixmapCacheModel);
d->SortedTimelineModel::clear(); d->clear();
d->pixmapUrls.clear(); d->pixmaps.clear();
d->pixmapSizes.clear();
d->collapsedRowCount = 1; d->collapsedRowCount = 1;
d->expandedRowCount = 1; d->maxCacheSize = 1;
d->expanded = false; d->expanded = false;
d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1); d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
} }
void PixmapCacheModel::PixmapCacheModelPrivate::computeCacheSizes() void PixmapCacheModel::PixmapCacheModelPrivate::computeMaxCacheSize()
{ {
minCacheSize = -1; maxCacheSize = 1;
maxCacheSize = -1;
foreach (const PixmapCacheModel::PixmapCacheEvent &event, ranges) { foreach (const PixmapCacheModel::PixmapCacheEvent &event, ranges) {
if (event.pixmapEventType == PixmapCacheModel::PixmapCacheCountChanged) { if (event.pixmapEventType == PixmapCacheModel::PixmapCacheCountChanged) {
if (minCacheSize == -1 || event.cacheSize < minCacheSize) if (event.cacheSize > maxCacheSize)
minCacheSize = event.cacheSize;
if (maxCacheSize == -1 || event.cacheSize > maxCacheSize)
maxCacheSize = event.cacheSize; maxCacheSize = event.cacheSize;
} }
} }
@@ -351,6 +523,8 @@ void PixmapCacheModel::PixmapCacheModelPrivate::resizeUnfinishedLoads()
void PixmapCacheModel::PixmapCacheModelPrivate::flattenLoads() void PixmapCacheModel::PixmapCacheModelPrivate::flattenLoads()
{ {
collapsedRowCount = 0;
// computes "compressed row" // computes "compressed row"
QVector <qint64> eventEndTimes; QVector <qint64> eventEndTimes;
for (int i = 0; i < count(); i++) { for (int i = 0; i < count(); i++) {
@@ -369,25 +543,29 @@ void PixmapCacheModel::PixmapCacheModelPrivate::flattenLoads()
// readjust to account for category empty row and bargraph // readjust to account for category empty row and bargraph
event.rowNumberCollapsed += 2; event.rowNumberCollapsed += 2;
} }
}
}
void PixmapCacheModel::PixmapCacheModelPrivate::computeRowCounts()
{
expandedRowCount = 0;
collapsedRowCount = 0;
foreach (const PixmapCacheModel::PixmapCacheEvent &event, ranges) {
if (event.rowNumberExpanded > expandedRowCount)
expandedRowCount = event.rowNumberExpanded;
if (event.rowNumberCollapsed > collapsedRowCount) if (event.rowNumberCollapsed > collapsedRowCount)
collapsedRowCount = event.rowNumberCollapsed; collapsedRowCount = event.rowNumberCollapsed;
} }
// Starting from 0, count is maxIndex+1 // Starting from 0, count is maxIndex+1
expandedRowCount++;
collapsedRowCount++; collapsedRowCount++;
} }
int PixmapCacheModel::PixmapCacheModelPrivate::updateCacheCount(int lastCacheSizeEvent,
qint64 startTime, qint64 pixSize, PixmapCacheEvent &newEvent)
{
newEvent.pixmapEventType = PixmapCacheCountChanged;
newEvent.rowNumberCollapsed = 1;
qint64 prevSize = 0;
if (lastCacheSizeEvent != -1) {
prevSize = range(lastCacheSizeEvent).cacheSize;
insertEnd(lastCacheSizeEvent, startTime - range(lastCacheSizeEvent).start);
}
newEvent.cacheSize = prevSize + pixSize;
return insertStart(startTime, newEvent);
}
} // namespace Internal } // namespace Internal

View File

@@ -35,12 +35,11 @@ class PixmapCacheModel : public QmlProfiler::SingleCategoryTimelineModel
public: public:
struct PixmapCacheEvent { struct PixmapCacheEvent {
int eventId;
int pixmapEventType; int pixmapEventType;
int urlIndex; int urlIndex;
qint64 cacheSize; int sizeIndex;
int rowNumberExpanded;
int rowNumberCollapsed; int rowNumberCollapsed;
qint64 cacheSize;
}; };
enum PixmapEventType { enum PixmapEventType {
@@ -71,6 +70,8 @@ public:
void clear(); void clear();
private: private:
static const int PixmapCacheCountHue = 240;
class PixmapCacheModelPrivate; class PixmapCacheModelPrivate;
Q_DECLARE_PRIVATE(PixmapCacheModel) Q_DECLARE_PRIVATE(PixmapCacheModel)
}; };

View File

@@ -103,14 +103,14 @@ QColor SceneGraphTimelineModel::getColor(int index) const
double fpsFraction = 1 / (eventDuration * 60.0); double fpsFraction = 1 / (eventDuration * 60.0);
if (fpsFraction > 1.0) if (fpsFraction > 1.0)
fpsFraction = 1.0; fpsFraction = 1.0;
return QColor::fromHsl((fpsFraction*96)+10, 76, 166); return getFractionColor(fpsFraction);
} }
QString labelForSGType(int t) QString labelForSGType(int t)
{ {
switch ((SceneGraphCategoryType)t) { switch ((SceneGraphCategoryType)t) {
case SceneGraphRenderThread: case SceneGraphRenderThread:
return QCoreApplication::translate("SceneGraphTimelineModel", "Renderer Thread"); return QCoreApplication::translate("SceneGraphTimelineModel", "Render Thread");
case SceneGraphGUIThread: case SceneGraphGUIThread:
return QCoreApplication::translate("SceneGraphTimelineModel", "GUI Thread"); return QCoreApplication::translate("SceneGraphTimelineModel", "GUI Thread");
default: return QString(); default: return QString();