mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-07 18:12:38 +02:00
Exploring the performance profile of the render engine
This commit is contained in:
parent
883c758722
commit
11a240e2db
8 changed files with 338 additions and 71 deletions
|
@ -196,11 +196,13 @@ public:
|
|||
|
||||
void run(const render::RenderContextPointer& renderContext, const RenderArgsPointer& cachedArgs) {
|
||||
auto args = renderContext->args;
|
||||
if (cachedArgs) {
|
||||
args->_blitFramebuffer = cachedArgs->_blitFramebuffer;
|
||||
args->_viewport = cachedArgs->_viewport;
|
||||
args->popViewFrustum();
|
||||
args->_displayMode = cachedArgs->_displayMode;
|
||||
args->_renderMode = cachedArgs->_renderMode;
|
||||
}
|
||||
args->popViewFrustum();
|
||||
|
||||
gpu::doInBatch("EndSecondaryCameraFrame::run", args->_context, [&](gpu::Batch& batch) {
|
||||
batch.restoreContextStereo();
|
||||
|
|
|
@ -98,10 +98,10 @@ public:
|
|||
JobConfig() = default;
|
||||
JobConfig(bool enabled) : alwaysEnabled{ false }, enabled{ enabled } {}
|
||||
|
||||
bool isEnabled() { return alwaysEnabled || enabled; }
|
||||
void setEnabled(bool enable) { enabled = alwaysEnabled || enable; emit dirtyEnabled(); }
|
||||
bool isEnabled() { return /*alwaysEnabled ||*/ enabled; }
|
||||
void setEnabled(bool enable) { enabled = /*alwaysEnabled ||*/ enable; emit dirtyEnabled(); }
|
||||
|
||||
bool alwaysEnabled{ true };
|
||||
bool alwaysEnabled{ false };
|
||||
bool enabled{ true };
|
||||
|
||||
virtual void setPresetList(const QJsonObject& object);
|
||||
|
|
|
@ -73,6 +73,120 @@ function job_print_functor(printout, showProps, maxDepth) {
|
|||
}
|
||||
}
|
||||
|
||||
// Use this function to create a functor that will build a tree datastructure of the Job visited
|
||||
|
||||
function job_tree_model_array_functor(jobTreeArray, newNodeFunctor) {
|
||||
var jobsRoot;
|
||||
var numJobs = 0;
|
||||
var jobTreePath = []
|
||||
if (newNodeFunctor === undefined) newNodeFunctor = function (node) {}
|
||||
|
||||
return function (job, depth, index) {
|
||||
var id = numJobs
|
||||
var newItem = {"name": job.objectName, "level": depth, "index": index, "id": id, "subNode": [], "path": ""}
|
||||
if (depth == 0) {
|
||||
newNodeFunctor(newItem)
|
||||
jobTreeArray.push(newItem)
|
||||
numJobs++
|
||||
jobsRoot = jobTreeArray[0].subNode;
|
||||
} else {
|
||||
if (jobTreePath.length < depth) {
|
||||
var node = jobsRoot;
|
||||
var path;
|
||||
for (var n = 0; n < jobTreePath.length; n++) {
|
||||
newItem.path += (n > 0 ? "." : "") + node[jobTreePath[n]].name
|
||||
node = node[jobTreePath[n]].subNode
|
||||
}
|
||||
|
||||
newNodeFunctor(newItem)
|
||||
node.push((newItem))
|
||||
numJobs++
|
||||
jobTreePath.push(0);
|
||||
} else if (jobTreePath.length >= depth) {
|
||||
var node = jobsRoot;
|
||||
for (var n = 0; n < (depth - 1); n++) {
|
||||
newItem.path += (n > 0 ? "." : "") + node[jobTreePath[n]].name
|
||||
node = node[jobTreePath[n]].subNode
|
||||
}
|
||||
|
||||
newNodeFunctor(newItem)
|
||||
node.push((newItem))
|
||||
numJobs++
|
||||
jobTreePath[depth-1] = index;
|
||||
while (jobTreePath.length > depth) {
|
||||
jobTreePath.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function job_tree_model_functor(jobTreeModel, maxLevel, newNodeFunctor) {
|
||||
var jobsRoot;
|
||||
var numJobs = 0;
|
||||
var jobTreePath = []
|
||||
if (newNodeFunctor === undefined) newNodeFunctor = function (node) {}
|
||||
|
||||
return function (job, depth, index) {
|
||||
var id = numJobs
|
||||
var newItem = {"name": job.objectName, "level": depth, "index": index, "id": id, "subNode": [], "path": "", "init": (depth < maxLevel), "ud": {}}
|
||||
if (depth == 0) {
|
||||
newNodeFunctor(newItem)
|
||||
jobTreeModel.append(newItem)
|
||||
numJobs++
|
||||
jobsRoot = jobTreeModel.get(0).subNode;
|
||||
} else {
|
||||
if (jobTreePath.length < depth) {
|
||||
var node = jobsRoot;
|
||||
var path;
|
||||
for (var n = 0; n < jobTreePath.length; n++) {
|
||||
newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name
|
||||
node = node.get(jobTreePath[n]).subNode
|
||||
}
|
||||
|
||||
newNodeFunctor(newItem)
|
||||
node.append((newItem))
|
||||
numJobs++
|
||||
jobTreePath.push(0);
|
||||
} else if (jobTreePath.length >= depth) {
|
||||
var node = jobsRoot;
|
||||
for (var n = 0; n < (depth - 1); n++) {
|
||||
newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name
|
||||
node = node.get(jobTreePath[n]).subNode
|
||||
}
|
||||
|
||||
newNodeFunctor(newItem)
|
||||
node.append((newItem))
|
||||
numJobs++
|
||||
jobTreePath[depth-1] = index;
|
||||
while (jobTreePath.length > depth) {
|
||||
jobTreePath.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Traverse the jobTreenode data structure created above
|
||||
function job_traverseTreeNode(root, functor, depth) {
|
||||
// if (root.subNode.length) {
|
||||
depth++;
|
||||
for (var i = 0; i <root.subNode.length; i++) {
|
||||
var sub = root.subNode[i];
|
||||
if (functor(sub, depth, i)) {
|
||||
job_traverseTreeNode(sub, functor, depth, 0)
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
function job_traverseTreeNodeRoot(root, functor) {
|
||||
if (functor(root, 0, 0)) {
|
||||
job_traverseTreeNode(root, functor, 0)
|
||||
}
|
||||
}
|
||||
// Expose functions for regular js including this files through the 'Jet' object
|
||||
/*Jet = {}
|
||||
Jet.task_traverse = task_traverse
|
||||
|
|
|
@ -23,52 +23,39 @@ Rectangle {
|
|||
id: root;
|
||||
|
||||
property var rootConfig : Workload
|
||||
property var myArray : []
|
||||
|
||||
|
||||
Component.onCompleted: {
|
||||
var message = ""
|
||||
var maxDepth = 3;
|
||||
|
||||
var jobTreePath = []
|
||||
var jobsRoot;
|
||||
|
||||
var functor = function (job, depth, index) {
|
||||
var newItem = {"name": job.objectName, "level": depth, "index": index, "subNode": [], "init": depth < maxDepth, "path": ""}
|
||||
if (depth == 0) {
|
||||
jobsModel.append(newItem)
|
||||
jobsRoot = jobsModel.get(0).subNode;
|
||||
} else {
|
||||
if (jobTreePath.length < depth) {
|
||||
var node = jobsRoot;
|
||||
var path;
|
||||
for (var n = 0; n < jobTreePath.length; n++) {
|
||||
newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name
|
||||
node = node.get(jobTreePath[n]).subNode
|
||||
}
|
||||
node.append(newItem)
|
||||
jobTreePath.push(0);
|
||||
} else if (jobTreePath.length >= depth) {
|
||||
var node = jobsRoot;
|
||||
for (var n = 0; n < (depth - 1); n++) {
|
||||
newItem.path += (n > 0 ? "." : "") + node.get(jobTreePath[n]).name
|
||||
node = node.get(jobTreePath[n]).subNode
|
||||
}
|
||||
node.append(newItem)
|
||||
jobTreePath[depth-1] = index;
|
||||
while (jobTreePath.length > depth) {
|
||||
jobTreePath.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//var functor = Jet.job_tree_model_functor(jobsModel)
|
||||
/* var functor = Jet.job_tree_model_functor(jobsModel, 1, function(node) {
|
||||
node["cpuT"] = 0.0
|
||||
})
|
||||
Jet.task_traverseTree(rootConfig, functor);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
var tfunctor = Jet.job_tree_model_array_functor(jobsModel.engineJobItemModel, function(node) {
|
||||
node["init"] = (node.level < 3)
|
||||
node["fullpath"] = (node.path + "." + node.name)
|
||||
node["cpuT"] = 0.0
|
||||
})
|
||||
|
||||
Jet.task_traverseTree(rootConfig, tfunctor);
|
||||
|
||||
// var currentParentStach = []
|
||||
// currentParentStach.push(jobsModel);
|
||||
|
||||
|
||||
Jet.job_traverseTreeNodeRoot(jobsModel.engineJobItemModel[0], function(node, depth, index) {
|
||||
print(node.name + depth + " - " + index)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
ListModel {
|
||||
id: jobsModel
|
||||
property var engineJobItemModel : []
|
||||
}
|
||||
|
||||
Component {
|
||||
|
@ -77,30 +64,49 @@ Rectangle {
|
|||
id: objRecursiveColumn
|
||||
clip: true
|
||||
visible: model.init
|
||||
|
||||
MouseArea {
|
||||
width: objRow.implicitWidth
|
||||
height: objRow.implicitHeight
|
||||
onDoubleClicked: {
|
||||
for(var i = 1; i < parent.children.length - 1; ++i) {
|
||||
parent.children[i].visible = !parent.children[i].visible
|
||||
}
|
||||
}
|
||||
Row {
|
||||
id: objRow
|
||||
Item {
|
||||
height: 1
|
||||
width: model.level * 15
|
||||
}
|
||||
HifiControls.CheckBox {
|
||||
property var config: root.rootConfig.getConfig(model.path + "." + model.name);
|
||||
text: (objRecursiveColumn.children.length > 2 ?
|
||||
objRecursiveColumn.children[1].visible ?
|
||||
qsTr("- ") : qsTr("+ ") : qsTr(" ")) + model.name + " ms=" + config.cpuRunTime.toFixed(2)
|
||||
checked: config.enabled
|
||||
}
|
||||
// visible: (node.level < 2)
|
||||
|
||||
function switchFold() {
|
||||
for(var i = 1; i < children.length - 1; ++i) {
|
||||
children[i].visible = !children[i].visible
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: objRow
|
||||
Item {
|
||||
height: 1
|
||||
width: model.level * 15
|
||||
}
|
||||
|
||||
HifiControls.CheckBox {
|
||||
id: objCheck
|
||||
property var config: root.rootConfig.getConfig(model.path + "." + model.name);
|
||||
text: " "
|
||||
checked: config.enabled
|
||||
onCheckedChanged: { config.enabled = checked }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
width: objLabel.implicitWidth
|
||||
height: objLabel.implicitHeight
|
||||
onDoubleClicked: {
|
||||
parent.parent.switchFold()
|
||||
}
|
||||
|
||||
HifiControls.Label {
|
||||
id: objLabel
|
||||
colorScheme: hifi.colorSchemes.dark
|
||||
// property var config: root.rootConfig.getConfig(model.path + "." + model.name);
|
||||
text: (objRecursiveColumn.children.length > 2 ?
|
||||
objRecursiveColumn.children[1].visible ?
|
||||
qsTr("- ") : qsTr("+ ") : qsTr(" ")) + model.name
|
||||
+ " ms=" + root.rootConfig.getConfig(model.path + "." + model.name).cpuRunTime.toFixed(3)
|
||||
+ " id=" + model.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: subNode
|
||||
delegate: objRecursiveDelegate
|
||||
|
|
141
scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml
Normal file
141
scripts/developer/utilities/lib/jet/qml/TaskTimeFrameView.qml
Normal file
|
@ -0,0 +1,141 @@
|
|||
//
|
||||
// jet/TaskTimeFrameView.qml
|
||||
//
|
||||
// Created by Sam Gateau, 2018/06/15
|
||||
// Copyright 2018 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4 as Original
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import "qrc:///qml/styles-uit"
|
||||
import "qrc:///qml/controls-uit" as HifiControls
|
||||
|
||||
import "../jet.js" as Jet
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi;}
|
||||
color: hifi.colors.baseGray;
|
||||
id: root;
|
||||
|
||||
property var rootConfig : Workload
|
||||
|
||||
property var jobsTree
|
||||
property var jobsArray
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!jobsTree) { jobsTree = new Array(); }
|
||||
if (!jobsArray) { jobsArray = new Array(); }
|
||||
|
||||
var tfunctor = Jet.job_tree_model_array_functor(jobsTree, function(node) {
|
||||
var job = { "fullpath": (node.path + "." + node.name), "cpuT": 0.0, "depth": node.level }
|
||||
jobsArray.push(job)
|
||||
})
|
||||
Jet.task_traverseTree(rootConfig, tfunctor);
|
||||
|
||||
for (var j = 0; j <jobsArray.length; j++) {
|
||||
jobsArray[j].cpuT = Render.getConfig(jobsArray[j].fullpath).cpuRunTime
|
||||
print("job" + j + ": " + jobsArray[j].cpuT)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Timer {
|
||||
interval: 500; running: true; repeat: true
|
||||
onTriggered: pullFreshValues()
|
||||
}
|
||||
|
||||
function pullFreshValues() {
|
||||
|
||||
for (var j = 0; j <jobsArray.length; j++) {
|
||||
jobsArray[j].cpuT = root.rootConfig.getConfig(jobsArray[j].fullpath).cpuRunTime
|
||||
}
|
||||
mycanvas.requestPaint()
|
||||
}
|
||||
Canvas {
|
||||
id: mycanvas
|
||||
anchors.fill:parent
|
||||
|
||||
onPaint: {
|
||||
print("mycanvasOnPaint " + jobsArray.length)
|
||||
var lineHeight = 12;
|
||||
var frameWidth = width;
|
||||
|
||||
|
||||
function displayBackground(ctx) {
|
||||
ctx.fillStyle = Qt.rgba(0, 0, 0, root.backgroundOpacity);
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
|
||||
ctx.strokeStyle= "grey";
|
||||
ctx.lineWidth="2";
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, lineHeight + 1);
|
||||
ctx.lineTo(width, lineHeight + 1);
|
||||
ctx.moveTo(0, height);
|
||||
ctx.lineTo(width, height);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
function drawJob(ctx, depth, index, duration, timeOffset, timeScale) {
|
||||
//print(root.jobsArray[index].cpuT)
|
||||
// ctx.fillStyle = Qt.rgba(255, 255, 0, root.backgroundOpacity);
|
||||
ctx.fillStyle = ( depth % 2 ? ( index % 2 ? "blue" : "yellow") : ( index % 2 ? "green" : "red"))
|
||||
ctx.fillRect(timeOffset * timeScale, lineHeight * depth, duration * timeScale, lineHeight * 0.6);
|
||||
|
||||
}
|
||||
|
||||
var ctx = getContext("2d");
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
ctx.font="12px Verdana";
|
||||
|
||||
displayBackground(ctx);
|
||||
if (jobsArray.length > 0) {
|
||||
|
||||
var rangeStack =new Array()
|
||||
var frameDuration = Math.max(jobsArray[0].cpuT, 1)
|
||||
rangeStack.push( { "b": 0.0, "e": frameDuration } )
|
||||
var timeScale = width * 0.9 / frameDuration;
|
||||
|
||||
drawJob(ctx, 0, 0, jobsArray[0].cpuT, 0, timeScale)
|
||||
|
||||
for (var i = 1; i <jobsArray.length; i++) {
|
||||
//for (var i = 1; i <20; i++) {
|
||||
var lastDepth = rangeStack.length - 1;
|
||||
var depth = jobsArray[i].depth;
|
||||
var timeOffset = 0.0
|
||||
var duration = jobsArray[i].cpuT;
|
||||
if (depth < 4) {
|
||||
|
||||
if (depth > lastDepth) {
|
||||
timeOffset = rangeStack[lastDepth].b
|
||||
while(rangeStack.length <= depth) {
|
||||
rangeStack.push( { "b": timeOffset, "e": duration } )
|
||||
}
|
||||
|
||||
} else {
|
||||
if (depth < lastDepth) {
|
||||
while(rangeStack.length != (depth + 1)) {
|
||||
rangeStack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
timeOffset = rangeStack[depth].e
|
||||
rangeStack[depth].b = timeOffset
|
||||
rangeStack[depth].e = timeOffset + duration
|
||||
}
|
||||
|
||||
print("j " + i + " depth " + depth + " lastDepth " + lastDepth + " off " + timeOffset + " dur " + duration)
|
||||
drawJob(ctx, depth, i, duration, timeOffset, timeScale)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
TaskList 1.0 TaskList.qml
|
||||
TaskViewList 1.0 TaskViewList.qml
|
||||
TaskViewList 1.0 TaskViewList.qml
|
||||
TaskTimeFrameView 1.0 TaskTimeFrameView.qml
|
|
@ -4,10 +4,12 @@
|
|||
var window = new OverlayWindow({
|
||||
title: 'Render Engine',
|
||||
source: qml,
|
||||
width: 300,
|
||||
height: 400
|
||||
width: 500,
|
||||
height: 100
|
||||
});
|
||||
window.setPosition(200, 50);
|
||||
//window.closed.connect(function() { Script.stop(); });
|
||||
window.closed.connect(function() { Script.stop(); });
|
||||
}
|
||||
openEngineTaskView();
|
||||
openEngineTaskView();
|
||||
|
||||
|
|
@ -23,7 +23,8 @@ Item {
|
|||
|
||||
property var mainViewTask: Render.getConfig("RenderMainView")
|
||||
|
||||
Jet.TaskListView {
|
||||
//Jet.TaskListView {
|
||||
Jet.TaskTimeFrameView {
|
||||
rootConfig: Render
|
||||
anchors.fill: render
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue