forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.1'
This commit is contained in:
@@ -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
|
||||||
|
@@ -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)
|
||||||
};
|
};
|
||||||
|
@@ -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();
|
||||||
|
Reference in New Issue
Block a user