Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
254 changes: 127 additions & 127 deletions viewer/assets/qml/Profiler.qml
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,133 @@ Item {
}
}

/* Spacer before Node Statistics (only visible in PAGX mode) */
Item {
width: 1
height: sectionSpacing
visible: nodeStatistics.visible
}

/* Node Statistics for PAGX */
Rectangle {
id: nodeStatistics
visible: runTimeDataModel && runTimeDataModel.nodeStatsModel.totalCount > 0
height: visible ? nodeStatsContent.height : 0
width: parent.width
color: "#00000000"

Column {
id: nodeStatsContent
width: parent.width
spacing: 1

// Title row
Rectangle {
height: 24
width: parent.width
color: "#2D2D37"
Text {
text: qsTr("Node Distribution")
font.pixelSize: 11
font.bold: true
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 8
color: "#FFFFFF"
renderType: Text.NativeRendering
}
Text {
text: runTimeDataModel && runTimeDataModel.nodeStatsModel ? runTimeDataModel.nodeStatsModel.totalCount + " " + qsTr("nodes") : ""
font.pixelSize: 11
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 8
color: "#9B9B9B"
renderType: Text.NativeRendering
}
}

// Stacked bar showing distribution
Rectangle {
height: 20
width: parent.width
color: "#2D2D37"

Row {
id: nodeBarRow
anchors.fill: parent
anchors.margins: 4
spacing: 1

Repeater {
model: runTimeDataModel ? runTimeDataModel.nodeStatsModel : null
Rectangle {
height: parent.height
width: {
var total = runTimeDataModel && runTimeDataModel.nodeStatsModel ? Math.max(runTimeDataModel.nodeStatsModel.totalCount, 1) : 1;
return Math.max((nodeBarRow.width - 10) * count / total, 0);
}
color: colorCode
radius: 2
}
}
}
}

// Detail rows
Repeater {
model: runTimeDataModel ? runTimeDataModel.nodeStatsModel : null
Rectangle {
height: 20
width: nodeStatsContent.width
color: "#2D2D37"

Rectangle {
width: 4
height: 12
radius: 2
color: colorCode
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 8
}

Text {
text: name
font.pixelSize: 10
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 18
color: "#9B9B9B"
renderType: Text.NativeRendering
}

Text {
text: {
var total = runTimeDataModel && runTimeDataModel.nodeStatsModel ? Math.max(runTimeDataModel.nodeStatsModel.totalCount, 1) : 1;
return Math.round(count * 100 / total) + "%";
}
font.pixelSize: 10
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
color: "#9B9B9B"
renderType: Text.NativeRendering
}

Text {
text: count
font.pixelSize: 11
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 8
color: "#FFFFFF"
renderType: Text.NativeRendering
}
}
}
}
}

/* Spacer before Performance Chart (only visible in PAG mode) */
Item {
width: 1
Expand Down Expand Up @@ -663,133 +790,6 @@ Item {
}
}

/* Spacer before Node Statistics (only visible in PAGX mode) */
Item {
width: 1
height: sectionSpacing
visible: nodeStatistics.visible
}

/* Node Statistics for PAGX */
Rectangle {
id: nodeStatistics
visible: runTimeDataModel && runTimeDataModel.nodeStatsModel.totalCount > 0
height: visible ? nodeStatsContent.height : 0
width: parent.width
color: "#00000000"

Column {
id: nodeStatsContent
width: parent.width
spacing: 1

// Title row
Rectangle {
height: 24
width: parent.width
color: "#2D2D37"
Text {
text: qsTr("Node Distribution")
font.pixelSize: 11
font.bold: true
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 8
color: "#FFFFFF"
renderType: Text.NativeRendering
}
Text {
text: runTimeDataModel && runTimeDataModel.nodeStatsModel ? runTimeDataModel.nodeStatsModel.totalCount + " " + qsTr("nodes") : ""
font.pixelSize: 11
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 8
color: "#9B9B9B"
renderType: Text.NativeRendering
}
}

// Stacked bar showing distribution
Rectangle {
height: 20
width: parent.width
color: "#2D2D37"

Row {
id: nodeBarRow
anchors.fill: parent
anchors.margins: 4
spacing: 1

Repeater {
model: runTimeDataModel ? runTimeDataModel.nodeStatsModel : null
Rectangle {
height: parent.height
width: {
var total = runTimeDataModel && runTimeDataModel.nodeStatsModel ? Math.max(runTimeDataModel.nodeStatsModel.totalCount, 1) : 1;
return Math.max((nodeBarRow.width - 10) * count / total, 0);
}
color: colorCode
radius: 2
}
}
}
}

// Detail rows
Repeater {
model: runTimeDataModel ? runTimeDataModel.nodeStatsModel : null
Rectangle {
height: 20
width: nodeStatsContent.width
color: "#2D2D37"

Rectangle {
width: 4
height: 12
radius: 2
color: colorCode
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 8
}

Text {
text: name
font.pixelSize: 10
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 18
color: "#9B9B9B"
renderType: Text.NativeRendering
}

Text {
text: {
var total = runTimeDataModel && runTimeDataModel.nodeStatsModel ? Math.max(runTimeDataModel.nodeStatsModel.totalCount, 1) : 1;
return Math.round(count * 100 / total) + "%";
}
font.pixelSize: 10
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
color: "#9B9B9B"
renderType: Text.NativeRendering
}

Text {
text: count
font.pixelSize: 11
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 8
color: "#FFFFFF"
renderType: Text.NativeRendering
}
}
}
}
}

/* Spacer before FPS Info (only visible in PAGX mode) */
Item {
width: 1
Expand Down
20 changes: 12 additions & 8 deletions viewer/assets/translation/Chinese.ts
Original file line number Diff line number Diff line change
Expand Up @@ -449,12 +449,12 @@
<translation>建议将视频序列帧数量控制在两个以内</translation>
</message>
<message>
<location filename="../qml/Profiler.qml" line="692"/>
<location filename="../qml/Profiler.qml" line="246"/>
<source>Node Distribution</source>
<translation>节点分布</translation>
</message>
<message>
<location filename="../qml/Profiler.qml" line="702"/>
<location filename="../qml/Profiler.qml" line="256"/>
<source>nodes</source>
<translation>个节点</translation>
</message>
Expand Down Expand Up @@ -602,27 +602,31 @@
<context>
<name>pag::PAGXViewModel</name>
<message>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="315"/>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="387"/>
<source>Failed to parse XML: invalid syntax or structure</source>
<translation>解析 XML 失败:语法或结构无效</translation>
</message>
<message>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="321"/>
<source>Failed to build layer from XML document</source>
<translation>从 XML 文档构建图层失败</translation>
<translation type="vanished">从 XML 文档构建图层失败</translation>
</message>
<message>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="352"/>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="393"/>
<source>Failed to build PAGScene from XML document</source>
<translation>从 XML 文档构建 PAGScene 失败</translation>
</message>
<message>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="419"/>
<source>No file path specified</source>
<translation>未指定文件路径</translation>
</message>
<message>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="356"/>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="423"/>
<source>Failed to open file for writing: %1</source>
<translation>无法打开文件进行写入:%1</translation>
</message>
<message>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="361"/>
<location filename="../../src/rendering/pagx/PAGXViewModel.cpp" line="428"/>
<source>Failed to write all data to file</source>
<translation>写入文件数据不完整</translation>
</message>
Expand Down
35 changes: 33 additions & 2 deletions viewer/src/profiling/PAGRunTimeDataModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////////

#include "PAGRunTimeDataModel.h"
#include <cmath>
#include "base/utils/TimeUtil.h"
#include "pag/pag.h"

Expand Down Expand Up @@ -128,8 +129,38 @@ void PAGRunTimeDataModel::setPAGFile(std::shared_ptr<PAGFile> pagFile) {
}

void PAGRunTimeDataModel::setPAGXDocument(std::shared_ptr<pagx::PAGXDocument> pagxDocument) {
frameModeEnabled = false;
totalFrame = pagxDocument ? 1 : 0;
if (pagxDocument != nullptr && !pagxDocument->animations.empty()) {
// The animations vector may contain Animation or StateMachine entries; only Animation exposes
// frameRate and duration fields.
auto* firstAnim = pagxDocument->animations[0];
if (firstAnim != nullptr && firstAnim->nodeType() == pagx::NodeType::Animation) {
auto* anim = static_cast<pagx::Animation*>(firstAnim);
// Derive totalFrame from the microsecond duration using the same two-step rounding as the
// render path (PAGTimeline::duration truncates frames→microseconds, then frames are recovered
// via round). Using anim->duration directly would diverge by up to one frame at non-integer
// frame rates, causing the render-side clamped last frame to be dropped by updateData's guard.
if (anim->frameRate > 0.0f && anim->duration > 0) {
auto durationUs = static_cast<int64_t>(static_cast<double>(anim->duration) * 1000000.0 /
static_cast<double>(anim->frameRate));
totalFrame = static_cast<int64_t>(std::round(
static_cast<double>(durationUs) * static_cast<double>(anim->frameRate) / 1000000.0));
} else {
totalFrame = 0;
}
if (totalFrame < 1) {
totalFrame = 1;
}
} else {
// A StateMachine-first document has no single duration/frameRate to derive a frame count
// from; fall back to a single frame so frame mode does not run with a stale/invalid value,
// matching PAGXViewModel::updateAnimationState()'s no-animation fallback.
totalFrame = 1;
}
frameModeEnabled = true;
} else {
totalFrame = pagxDocument ? 1 : 0;
frameModeEnabled = false;
}
currentFrame = pagxDocument ? 0 : -1;
lastUpdatedFrame = -1;
chartDataModel.clearItems();
Expand Down
Loading
Loading