Better monitoring of the resource loading in flights

This commit is contained in:
Sam Gateau 2019-09-19 16:56:55 -07:00
parent 6154611b05
commit ee5de175eb
5 changed files with 252 additions and 88 deletions

View file

@ -325,7 +325,11 @@ QVariantList ResourceCache::getResourceList() {
BLOCKING_INVOKE_METHOD(this, "getResourceList",
Q_RETURN_ARG(QVariantList, list));
} else {
auto resources = _resources.uniqueKeys();
QList<QUrl> resources;
{
QReadLocker locker(&_resourcesLock);
resources = _resources.uniqueKeys();
}
list.reserve(resources.size());
for (auto& resource : resources) {
list << resource;
@ -379,6 +383,7 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
}
if (!resource) {
_numLoadingResources++;
resource = createResource(url);
resource->setExtra(extra);
resource->setExtraHash(extraHash);
@ -386,6 +391,7 @@ QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl&
resource->setCache(this);
resource->moveToThread(qApp->thread());
connect(resource.data(), &Resource::updateSize, this, &ResourceCache::updateTotalSize);
connect(resource.data(), &Resource::finished, this, &ResourceCache::decreaseNumLoading);
{
QWriteLocker locker(&_resourcesLock);
_resources[url].insert(extraHash, resource);
@ -513,6 +519,11 @@ void ResourceCache::updateTotalSize(const qint64& deltaSize) {
emit dirty();
}
void ResourceCache::decreaseNumLoading() {
_numLoadingResources--;
emit dirty();
}
QList<QSharedPointer<Resource>> ResourceCache::getLoadingRequests() {
return DependencyManager::get<ResourceCacheSharedItems>()->getLoadingRequests();
}
@ -530,7 +541,7 @@ bool ResourceCache::attemptRequest(QSharedPointer<Resource> resource) {
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
if (sharedItems->appendRequest(resource)) {
resource->makeRequest();
resource->makeRequest();
return true;
}
return false;

View file

@ -201,6 +201,7 @@ class ResourceCache : public QObject {
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty)
Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty)
public:
@ -208,10 +209,13 @@ public:
size_t getSizeTotalResources() const { return _totalResourcesSize; }
size_t getNumCachedResources() const { return _numUnusedResources; }
size_t getSizeCachedResources() const { return _unusedResourcesSize; }
size_t getSizeCachedResources() const { return _unusedResourcesSize; }
size_t getNumPendingResources() const { return _numPendingResources; }
size_t getNumLoadingResources() const { return _numLoadingResources; }
Q_INVOKABLE QVariantList getResourceList();
Q_INVOKABLE void decreaseNumLoading();
static void setRequestLimit(uint32_t limit);
static uint32_t getRequestLimit() { return DependencyManager::get<ResourceCacheSharedItems>()->getRequestLimit(); }
@ -292,6 +296,8 @@ private:
std::atomic<size_t> _numTotalResources { 0 };
std::atomic<qint64> _totalResourcesSize { 0 };
std::atomic<size_t> _numPendingResources{ 0 };
std::atomic<size_t> _numLoadingResources{ 0 };
// Cached resources
QMap<int, QSharedPointer<Resource>> _unusedResources;
@ -320,6 +326,12 @@ class ScriptableResourceCache : public QObject {
Q_PROPERTY(size_t sizeTotal READ getSizeTotalResources NOTIFY dirty)
Q_PROPERTY(size_t sizeCached READ getSizeCachedResources NOTIFY dirty)
Q_PROPERTY(size_t numPending READ getNumPendingResources NOTIFY dirty)
Q_PROPERTY(size_t numLoading READ getNumLoadingResources NOTIFY dirty)
Q_PROPERTY(size_t numGlobalQueriesPending READ getNumGlobalQueriesPending NOTIFY dirty)
Q_PROPERTY(size_t numGlobalQueriesLoading READ getNumGlobalQueriesLoading NOTIFY dirty)
public:
ScriptableResourceCache(QSharedPointer<ResourceCache> resourceCache);
@ -393,6 +405,11 @@ private:
size_t getSizeTotalResources() const { return _resourceCache->getSizeTotalResources(); }
size_t getNumCachedResources() const { return _resourceCache->getNumCachedResources(); }
size_t getSizeCachedResources() const { return _resourceCache->getSizeCachedResources(); }
size_t getNumPendingResources() const { return _resourceCache->getNumPendingResources(); }
size_t getNumLoadingResources() const { return _resourceCache->getNumLoadingResources(); }
size_t getNumGlobalQueriesPending() const { return ResourceCache::getLoadingRequestCount(); }
size_t getNumGlobalQueriesLoading() const { return ResourceCache::getPendingRequestCount(); }
};
/// Base class for resources.

View file

@ -34,6 +34,99 @@ Rectangle {
id: column
width: parent.width
Prop.PropFolderPanel {
label: "Resource Queries Inspector"
isUnfold: true
panelFrameData: Component {
Column {
PlotPerf {
title: "Global Queries"
height: 80
valueScale: 1
valueUnit: ""
plots: [
{
object: ModelCache,
prop: "numGlobalQueriesPending",
label: "Pending",
color: "#1AC567"
},
{
object: ModelCache,
prop: "numGlobalQueriesLoading",
label: "Loading",
color: "#FEC567"
},
{
object: ModelCache,
prop: "numLoading",
label: "Model Loading",
color: "#C5FE67"
}
]
}
}
}
}
Prop.PropFolderPanel {
label: "Cache Inspectors"
isUnfold: true
panelFrameData: Component {
Column {
Prop.PropButton {
text: "Model"
onClicked: {
sendToScript({method: "openModelCacheInspector"});
}
width:column.width
}
Prop.PropButton {
text: "Material"
onClicked: {
sendToScript({method: "openMaterialCacheInspector"});
}
width:column.width
}
Prop.PropButton {
text: "Texture"
onClicked: {
sendToScript({method: "openTextureCacheInspector"});
}
width:column.width
}
Prop.PropButton {
text: "Animation"
onClicked: {
sendToScript({method: "openAnimationCacheInspector"});
}
width:column.width
}
Prop.PropButton {
text: "Sound"
onClicked: {
sendToScript({method: "openSoundCacheInspector"});
}
width:column.width
}
Prop.PropScalar {
label: "Texture Loading"
object: TextureCache
property: "numLoading"
integral: true
readOnly: true
}
Prop.PropScalar {
label: "Model Loading"
object: ModelCache
property: "numLoading"
integral: true
readOnly: true
}
}
}
}
Prop.PropFolderPanel {
label: "Stats"
isUnfold: true
@ -81,51 +174,7 @@ Rectangle {
color: "#FFB4EF"
}
]
}
}}
}
Prop.PropFolderPanel {
label: "Cache Inspectors"
isUnfold: true
panelFrameData: Component {
Column {
Prop.PropButton {
text: "Model"
onClicked: {
sendToScript({method: "openModelCacheInspector"});
}
width:column.width
}
Prop.PropButton {
text: "Material"
onClicked: {
sendToScript({method: "openMaterialCacheInspector"});
}
width:column.width
}
Prop.PropButton {
text: "Texture"
onClicked: {
sendToScript({method: "openTextureCacheInspector"});
}
width:column.width
}
Prop.PropButton {
text: "Animation"
onClicked: {
sendToScript({method: "openAnimationCacheInspector"});
}
width:column.width
}
Prop.PropButton {
text: "Sound"
onClicked: {
sendToScript({method: "openSoundCacheInspector"});
}
width:column.width
}
}
}}
}
}
}

View file

@ -7,7 +7,7 @@
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.7
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
@ -36,18 +36,39 @@ Item {
if (cache !== undefined) {
theList = cache.getResourceList();
} else {
theList = [{"name": "ResourceCacheInspector.cache is undefined"}];
theList = ["ResourceCacheInspector.cache is undefined"];
}
return theList;
var theListString = new Array(theList.length)
for (var i in theList) {
theListString[i] = (theList[i].toString())
}
return theListString;
}
function resetItemListFromCache() {
resourceItemsModel.resetItemList(fetchItemsList())
resetItemList(fetchItemsList())
}
function updateItemListFromCache() {
resourceItemsModel.updateItemList(fetchItemsList())
property var needFreshList : false
function updateItemListFromCache() {
needFreshList = true
}
Timer {
interval: 1000; running: true; repeat: true
onTriggered: pullFreshValues()
}
function pullFreshValues() {
if (needFreshList) {
console.log("Updating " + cacheResourceName + "cache list")
updateItemList(fetchItemsList())
needFreshList = false
}
}
Column {
id: header
@ -77,7 +98,7 @@ Item {
property: "numTotal"
integral: true
readOnly: true
onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() }
onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;*/updateItemListFromCache() }
}
Prop.PropScalar {
id: cachedCount
@ -88,7 +109,7 @@ Item {
property: "numCached"
integral: true
readOnly: true
onSourceValueVarChanged: { console.log( root.cacheResourceName + " NumResource Value Changed!!!!") ;updateItemListFromCache() }
onSourceValueVarChanged: { /*console.log( root.cacheResourceName + " NumCached Value Changed!!!!");*/updateItemListFromCache() }
}
height: totalCount.height
}
@ -97,26 +118,81 @@ Item {
ListModel {
id: resourceItemsModel
function packItemEntry(item) {
var some_uri = Qt.resolvedUrl(item)
return { "name": item, "url": some_uri}
}
property var currentItemsList: new Array();
function packItemEntry(item) {
var entry = { "name": "", "root": "", "path": "", "base": "", "url": item}
if (item.length > 0) {
var rootPos = item.search("://")
entry.root = item.substring(0, rootPos)
if (rootPos >= 0) rootPos += 3
entry.path = item.substring(rootPos, item.length)
var splitted = entry.path.split('/')
entry.name = splitted[splitted.length - 1]
entry.base = splitted[0]
}
function resetItemList(itemList) {
resourceItemsModel.clear()
for (var i in itemList) {
resourceItemsModel.append(packItemEntry(itemList[i]))
}
return entry
}
function resetItemList(itemList) {
currentItemsList = []
resourceItemsModel.clear()
for (var i in itemList) {
var item = itemList[i]
currentItemsList.push(item)
resourceItemsModel.append(packItemEntry(item))
}
}
function updateItemList(newItemList) {
resetItemList(newItemList)
/*
var nextListLength = (currentItemList.length < newItemList.length ? newItemList.length : currentItemList.length )
var nextList = new Array(nextListLength)
var addedList = []
var removedList = []
var movedList = []
for (var i in currentItemList) {
var item = currentItemList[i]
var foundPos = newItemList.findIndex(item)
if (foundPos == i) {
newList[i] = item
newItemList[i] = 0
} else if (foundPos == -1) {
removedList.push(i)
} else {
movedList.push([i,foundPos])
}
}
function updateItemList(itemList) {
resourceItemsModel.clear()
for (var i in itemList) {
resourceItemsModel.append(packItemEntry(itemList[i]))
}
for (var i in newItemList) {
var item = newItemList[i]
if (item != 0) {
var foundPos = currentItemList.findIndex(item)
if (foundPos == -1) {
addedList.push(item)
}
}
}
for (var i in itemList) {
newList[i] = itemList[i]
}
*/
/*currentItemsList.clear()
resourceItemsModel.clear()
for (var i in itemList) {
currentItemsList.append(itemList[i].toString())
resourceItemsModel.append(packItemEntry(currentItemsList[i]))
} */
}
Component {
@ -131,24 +207,35 @@ Item {
size:8
}
Prop.PropLabel {
text: JSON.stringify(model.url)
text: model.root
width: 30
}
/* Prop.PropLabel {
text: model.url
}*/
Prop.PropSplitter {
size:8
}
Prop.PropLabel {
text: model.base
width: 60
}
Prop.PropSplitter {
size:8
}
Prop.PropLabel {
text: model.name
}
}
}
ScrollView {
ListView {
anchors.top: header.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
clip: true
ListView {
id: listView
model: resourceItemsModel
delegate: resouceItemDelegate
}
id: listView
model: resourceItemsModel
delegate: resouceItemDelegate
}
}

View file

@ -91,12 +91,12 @@ Rectangle {
}
}
Original.ScrollView {
ListView {
anchors.fill: parent
ListView {
id: theView
model: jobsModel
delegate: objRecursiveDelegate
}
id: theView
model: jobsModel
delegate: objRecursiveDelegate
}
}