diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2016-01-21 12:46:01 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@theqtcompany.com> | 2016-01-22 14:06:16 +0000 |
commit | 9a77f5f429c88518793673e924bb81768796215c (patch) | |
tree | b62fa85ecd129087ed910640a620e36abac28909 /plugins/qmlprofiler/pixmapcachemodel.cpp | |
parent | ed15f7067df9f25475915b2f69d6ff4140b926c6 (diff) |
Prepare for merging into qtcreatorqp-master
Remove the licensechecker dependency, move everything into
src/plugins/qmlprofilerextension, and adapt the build system.
Change-Id: I58bf34ecd838514d02b5c50189cd8a5eb99793b0
Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
Diffstat (limited to 'plugins/qmlprofiler/pixmapcachemodel.cpp')
-rw-r--r-- | plugins/qmlprofiler/pixmapcachemodel.cpp | 500 |
1 files changed, 0 insertions, 500 deletions
diff --git a/plugins/qmlprofiler/pixmapcachemodel.cpp b/plugins/qmlprofiler/pixmapcachemodel.cpp deleted file mode 100644 index b472fd8449..0000000000 --- a/plugins/qmlprofiler/pixmapcachemodel.cpp +++ /dev/null @@ -1,500 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "pixmapcachemodel.h" -#include "qmldebug/qmlprofilereventtypes.h" -#include "qmlprofiler/qmlprofilermodelmanager.h" - -namespace QmlProfilerExtension { -namespace Internal { - -using namespace QmlProfiler; - -PixmapCacheModel::PixmapCacheModel(QmlProfilerModelManager *manager, QObject *parent) : - QmlProfilerTimelineModel(manager, QmlDebug::PixmapCacheEvent, QmlDebug::MaximumRangeType, - QmlDebug::ProfilePixmapCache, parent) -{ - m_maxCacheSize = 1; -} - -int PixmapCacheModel::rowMaxValue(int rowNumber) const -{ - if (rowNumber == 1) { - return m_maxCacheSize; - } else { - return QmlProfilerTimelineModel::rowMaxValue(rowNumber); - } -} - -int PixmapCacheModel::expandedRow(int index) const -{ - return selectionId(index) + 1; -} - -int PixmapCacheModel::collapsedRow(int index) const -{ - return m_data[index].rowNumberCollapsed; -} - -int PixmapCacheModel::typeId(int index) const -{ - return m_data[index].typeId; -} - -QColor PixmapCacheModel::color(int index) const -{ - if (m_data[index].pixmapEventType == PixmapCacheCountChanged) - return colorByHue(s_pixmapCacheCountHue); - - return colorBySelectionId(index); -} - -float PixmapCacheModel::relativeHeight(int index) const -{ - if (m_data[index].pixmapEventType == PixmapCacheCountChanged) - return (float)m_data[index].cacheSize / (float)m_maxCacheSize; - else - return 1.0f; -} - -QString getFilenameOnly(QString absUrl) -{ - int characterPos = absUrl.lastIndexOf(QLatin1Char('/'))+1; - if (characterPos < absUrl.length()) - absUrl = absUrl.mid(characterPos); - return absUrl; -} - -QVariantList PixmapCacheModel::labels() const -{ - QVariantList result; - - // Cache Size - QVariantMap element; - element.insert(QLatin1String("description"), QVariant(QLatin1String("Cache Size"))); - - element.insert(QLatin1String("id"), QVariant(0)); - result << element; - - for (int i=0; i < m_pixmaps.count(); i++) { - // Loading - QVariantMap element; - element.insert(QLatin1String("displayName"), m_pixmaps[i].url); - element.insert(QLatin1String("description"), - QVariant(getFilenameOnly(m_pixmaps[i].url))); - - element.insert(QLatin1String("id"), QVariant(i+1)); - result << element; - } - - return result; -} - -QVariantMap PixmapCacheModel::details(int index) const -{ - QVariantMap result; - const PixmapCacheEvent *ev = &m_data[index]; - - if (ev->pixmapEventType == PixmapCacheCountChanged) { - result.insert(QLatin1String("displayName"), tr("Image Cached")); - } else { - if (ev->pixmapEventType == PixmapLoadingStarted) { - result.insert(QLatin1String("displayName"), tr("Image Loaded")); - if (m_pixmaps[ev->urlIndex].sizes[ev->sizeIndex].loadState != Finished) - result.insert(tr("Result"), tr("Load Error")); - } - result.insert(tr("Duration"), QmlProfilerDataModel::formatTime(duration(index))); - } - - result.insert(tr("Cache Size"), QString::fromLatin1("%1 px").arg(ev->cacheSize)); - result.insert(tr("File"), getFilenameOnly(m_pixmaps[ev->urlIndex].url)); - result.insert(tr("Width"), QString::fromLatin1("%1 px") - .arg(m_pixmaps[ev->urlIndex].sizes[ev->sizeIndex].size.width())); - result.insert(tr("Height"), QString::fromLatin1("%1 px") - .arg(m_pixmaps[ev->urlIndex].sizes[ev->sizeIndex].size.height())); - 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() -{ - QmlProfilerDataModel *simpleModel = modelManager()->qmlModel(); - if (simpleModel->isEmpty()) - return; - - int lastCacheSizeEvent = -1; - int cumulatedCount = 0; - - const QVector<QmlProfilerDataModel::QmlEventTypeData> &types = simpleModel->getEventTypes(); - foreach (const QmlProfilerDataModel::QmlEventData &event, simpleModel->getEvents()) { - const QmlProfilerDataModel::QmlEventTypeData &type = types[event.typeIndex()]; - if (!accepted(type)) - continue; - - PixmapCacheEvent newEvent; - newEvent.pixmapEventType = static_cast<PixmapEventType>(type.detailType); - qint64 pixmapStartTime = event.startTime(); - - newEvent.urlIndex = -1; - for (QVector<Pixmap>::const_iterator it(m_pixmaps.cend()); it != m_pixmaps.cbegin();) { - if ((--it)->url == type.location.filename) { - newEvent.urlIndex = it - m_pixmaps.cbegin(); - break; - } - } - - newEvent.sizeIndex = -1; - if (newEvent.urlIndex == -1) { - newEvent.urlIndex = m_pixmaps.count(); - m_pixmaps << Pixmap(type.location.filename); - } - - Pixmap &pixmap = m_pixmaps[newEvent.urlIndex]; - switch (newEvent.pixmapEventType) { - case PixmapSizeKnown: {// pixmap size - // Look for pixmaps for which we don't know the size, yet and which have actually been - // 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.numericData(0)); - i->size.setHeight(event.numericData(1)); - newEvent.sizeIndex = i - pixmap.sizes.begin(); - break; - } - - if (newEvent.sizeIndex == -1) { - newEvent.sizeIndex = pixmap.sizes.length(); - pixmap.sizes << PixmapState(event.numericData(0), event.numericData(1)); - } - - PixmapState &state = pixmap.sizes[newEvent.sizeIndex]; - if (state.cacheState == ToBeCached) { - lastCacheSizeEvent = updateCacheCount(lastCacheSizeEvent, pixmapStartTime, - state.size.width() * state.size.height(), newEvent, - event.typeIndex()); - state.cacheState = Cached; - } - break; - } - case PixmapCacheCountChanged: {// Cache Size Changed Event - pixmapStartTime = event.startTime() + 1; // delay 1 ns for proper sorting - - bool uncache = cumulatedCount > event.numericData(2); - cumulatedCount = event.numericData(2); - qint64 pixSize = 0; - - // First try to find a preferred pixmap, which either is Corrupt and will be uncached - // or is uncached and will be cached. - for (QVector<PixmapState>::iterator i(pixmap.sizes.begin()); - i != pixmap.sizes.end(); ++i) { - 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; - } - } - - // If none found, check for cached or ToBeCached pixmaps that shall be uncached or - // 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 = updateCacheCount(lastCacheSizeEvent, pixmapStartTime, pixSize, - newEvent, event.typeIndex()); - break; - } - case PixmapLoadingStarted: { // Load - // 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(); - } - - PixmapState &state = pixmap.sizes[newEvent.sizeIndex]; - state.loadState = Loading; - newEvent.typeId = event.typeIndex(); - state.started = insertStart(pixmapStartTime, newEvent.urlIndex + 1); - m_data.insert(state.started, newEvent); - break; - } - case PixmapLoadingFinished: - case PixmapLoadingError: { - // First try to find one that has already started - for (QVector<PixmapState>::const_iterator i(pixmap.sizes.cbegin()); - i != pixmap.sizes.cend(); ++i) { - if (i->loadState != Loading) - 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 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; - newEvent.typeId = event.typeIndex(); - qint64 traceStart = modelManager()->traceTime()->startTime(); - state.started = insert(traceStart, pixmapStartTime - traceStart, - newEvent.urlIndex + 1); - m_data.insert(state.started, newEvent); - - // All other indices are wrong now as we've prepended. Fix them ... - if (lastCacheSizeEvent >= state.started) - ++lastCacheSizeEvent; - - for (int pixmapIndex = 0; pixmapIndex < m_pixmaps.count(); ++pixmapIndex) { - Pixmap &brokenPixmap = m_pixmaps[pixmapIndex]; - for (int sizeIndex = 0; sizeIndex < brokenPixmap.sizes.count(); ++sizeIndex) { - PixmapState &brokenSize = brokenPixmap.sizes[sizeIndex]; - if ((pixmapIndex != newEvent.urlIndex || sizeIndex != newEvent.sizeIndex) && - brokenSize.started >= state.started) { - ++brokenSize.started; - } - } - } - } - - insertEnd(state.started, pixmapStartTime - startTime(state.started)); - 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; - } - break; - } - default: - break; - } - - updateProgress(count(), 2 * simpleModel->getEvents().count()); - } - - if (lastCacheSizeEvent != -1) - insertEnd(lastCacheSizeEvent, modelManager()->traceTime()->endTime() - - startTime(lastCacheSizeEvent)); - - resizeUnfinishedLoads(); - - computeMaxCacheSize(); - flattenLoads(); - computeNesting(); - - updateProgress(1, 1); -} - -void PixmapCacheModel::clear() -{ - m_pixmaps.clear(); - m_maxCacheSize = 1; - m_data.clear(); - QmlProfilerTimelineModel::clear(); -} - -void PixmapCacheModel::computeMaxCacheSize() -{ - m_maxCacheSize = 1; - foreach (const PixmapCacheModel::PixmapCacheEvent &event, m_data) { - if (event.pixmapEventType == PixmapCacheModel::PixmapCacheCountChanged) { - if (event.cacheSize > m_maxCacheSize) - m_maxCacheSize = event.cacheSize; - } - } -} - -void PixmapCacheModel::resizeUnfinishedLoads() -{ - // all the "load start" events with duration 0 continue till the end of the trace - for (int i = 0; i < count(); i++) { - if (m_data[i].pixmapEventType == PixmapCacheModel::PixmapLoadingStarted && - duration(i) == 0) { - insertEnd(i, modelManager()->traceTime()->endTime() - startTime(i)); - } - } -} - -void PixmapCacheModel::flattenLoads() -{ - int collapsedRowCount = 0; - - // computes "compressed row" - QVector <qint64> eventEndTimes; - for (int i = 0; i < count(); i++) { - PixmapCacheModel::PixmapCacheEvent &event = m_data[i]; - if (event.pixmapEventType == PixmapCacheModel::PixmapLoadingStarted) { - event.rowNumberCollapsed = 0; - while (eventEndTimes.count() > event.rowNumberCollapsed && - eventEndTimes[event.rowNumberCollapsed] > startTime(i)) - event.rowNumberCollapsed++; - - if (eventEndTimes.count() == event.rowNumberCollapsed) - eventEndTimes << 0; // increase stack length, proper value added below - eventEndTimes[event.rowNumberCollapsed] = endTime(i); - - // readjust to account for category empty row and bargraph - event.rowNumberCollapsed += 2; - } - if (event.rowNumberCollapsed > collapsedRowCount) - collapsedRowCount = event.rowNumberCollapsed; - } - - // Starting from 0, count is maxIndex+1 - setCollapsedRowCount(collapsedRowCount + 1); - setExpandedRowCount(m_pixmaps.count() + 2); -} - -int PixmapCacheModel::updateCacheCount(int lastCacheSizeEvent, - qint64 pixmapStartTime, qint64 pixSize, PixmapCacheEvent &newEvent, int typeId) -{ - newEvent.pixmapEventType = PixmapCacheCountChanged; - newEvent.rowNumberCollapsed = 1; - - qint64 prevSize = 0; - if (lastCacheSizeEvent != -1) { - prevSize = m_data[lastCacheSizeEvent].cacheSize; - insertEnd(lastCacheSizeEvent, pixmapStartTime - startTime(lastCacheSizeEvent)); - } - - newEvent.cacheSize = prevSize + pixSize; - newEvent.typeId = typeId; - int index = insertStart(pixmapStartTime, 0); - m_data.insert(index, newEvent); - return index; -} - - -} // namespace Internal -} // namespace QmlProfilerExtension |