# 帳票設計書 4-ビジュアルプロファイラーCSV

## 概要

本ドキュメントは、レンダリングパイプラインのプロファイリングデータをCSV形式でエクスポートする帳票の設計書である。

### 本帳票の処理概要

本帳票は、Godotエディタのビジュアルプロファイラーで収集したレンダリング処理の時間データをCSV形式で出力する機能を提供する。各レンダリングステージのCPU時間とGPU時間を記録し、グラフィックスパフォーマンスの分析に使用できる形式で出力する。

**業務上の目的・背景**：ゲームのグラフィックス処理は、パフォーマンスの大きな部分を占めることが多い。レンダリングパイプラインのどのステージがボトルネックになっているかを特定することは、グラフィックス最適化において非常に重要である。本帳票により、CPU/GPU両面からのレンダリング性能分析が可能になる。

**帳票の利用シーン**：主に以下のシーンで利用される。1) グラフィックス最適化のためのボトルネック分析、2) シェーダー変更後の影響評価、3) 異なるプラットフォーム間のレンダリング性能比較、4) ドローコール最適化の効果測定。

**主要な出力内容**：
1. レンダリングステージ名（シグネチャ）
2. 各ステージのCPU処理時間
3. 各ステージのGPU処理時間
4. フレームごとの時系列データ

**帳票の出力タイミング**：現在の実装では、get_data_as_csv()メソッドは定義されているが、内部実装が#if 0でコメントアウトされており、空のVectorを返却する状態である。

**帳票の利用者**：グラフィックスプログラマー、テクニカルアーティスト、最適化担当者

## 帳票種別

データエクスポート / プロファイリングデータ一覧

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| 15 | デバッガ | エディタ内蔵（Debugger Panel） | Visual Profilerタブ（出力機能は未実装） |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | CSV |
| 用紙サイズ | N/A（データファイル） |
| 向き | N/A |
| ファイル名 | 未定（機能未実装） |
| 出力方法 | 未実装（将来的にはファイルダイアログ経由） |
| 文字コード | UTF-8（想定） |

### CSV固有設定（想定仕様）

| 項目 | 内容 |
|-----|------|
| 区切り文字 | カンマ（,） |
| 囲み文字 | ダブルクォート（必要時） |
| ヘッダー行 | あり（1行目にシグネチャ名列挙）（想定） |

## 帳票レイアウト

### レイアウト概要（想定仕様）

コメントアウトされた実装から推測されるレイアウト。

```
┌─────────────────────────────────────────────────────────────┐
│              ヘッダー行（レンダリングステージ名列挙）            │
├─────────────────────────────────────────────────────────────┤
│              データ行（フレームごとの時間値）                   │
│              ...（フレーム数分の行）                          │
└─────────────────────────────────────────────────────────────┘
```

### ヘッダー部（想定）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1〜N | シグネチャ名 | レンダリングステージ/アイテムの識別名 | categories[].signature / items[].signature | 文字列 |

### 明細部（想定）

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1〜N | 時間値 | 対応ステージの処理時間（秒） | Category::total_time / Item::total | 実数 | 可変 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| デバッガ接続 | リモートデバッガがゲームに接続している必要がある | Yes |
| プロファイラーデータ蓄積 | ビジュアルプロファイラーでデータが収集されている必要がある | Yes |
| 機能有効化 | 現在#if 0で無効化されているため、コードの有効化が必要 | Yes |

### ソート順（想定）

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | フレーム順（時系列） | last_metricから循環的に |

### 改ページ条件

N/A（CSVファイルのため改ページなし）

## データベース参照仕様

### 参照テーブル一覧

本帳票はデータベースを参照せず、インメモリのプロファイラーデータを使用する（想定）。

| データソース | 用途 | 取得方法 |
|-----------|------|---------|
| EditorVisualProfiler::frame_metrics | フレームごとのメトリクスデータ | メンバー変数直接アクセス |
| EditorFrameProfiler::Metric::Category | カテゴリ情報 | Vectorイテレーション |
| Category::items | アイテム情報 | Vectorイテレーション |

## 計算仕様

### 計算項目一覧（想定）

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 時間値（カテゴリ） | String::num_real(c.total_time) | なし | 実数をそのまま文字列化 |
| 時間値（アイテム） | String::num_real(c.items[k].total) | なし | 実数をそのまま文字列化 |

## 処理フロー

### 出力フロー（想定）

```mermaid
flowchart TD
    A[get_data_as_csv呼び出し] --> B{frame_metrics空?}
    B -->|Yes| C[空のVectorを返却]
    B -->|No| D[最初のフレームからシグネチャ収集]
    D --> E[categories[j].signatureを追加]
    E --> F[items[k].signatureを追加]
    F --> G[res.push_back signaturesでヘッダー行追加]
    G --> H[last_metricからループ開始]
    H --> I{現在フレーム有効?}
    I -->|No| J[次のフレームへ]
    I -->|Yes| K[categoriesをイテレート]
    K --> L[total_timeを値配列に追加]
    L --> M[itemsをイテレート]
    M --> N[totalを値配列に追加]
    N --> O[res.push_back valuesを追加]
    O --> P{全フレーム処理完了?}
    P -->|No| J
    J --> H
    P -->|Yes| Q[resを返却]
    C --> R[終了]
    Q --> R
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| データなし | frame_metricsが空 | なし | 空のVectorを返却 |
| 無効フレーム | valid == false | なし | 該当フレームをスキップ |
| 機能無効 | #if 0でコメントアウト | なし | 常に空のVectorを返却 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数百〜数千フレーム分 |
| 目標出力時間 | 1秒未満（想定） |
| 同時出力数上限 | 1（シングル処理）（想定） |

## セキュリティ考慮事項

- レンダリングステージ名からエンジン内部構造が推測可能
- 機密性の高いプロジェクトでは出力ファイルの管理に注意

## 備考

- **重要**: 現在のソースコード（editor_visual_profiler.cpp 697-749行目）では、get_data_as_csv()の実装が#if 0 ... #endifでコメントアウトされており、実際には空のVectorを返却するのみ
- 将来的な実装に向けてインターフェースは定義されている
- スクリプトプロファイラーCSV（EditorProfiler::get_data_as_csv()）と類似の構造になると想定される

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、ビジュアルプロファイラーのメトリクス構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | editor_visual_profiler.h | `editor/debugger/editor_visual_profiler.h` | get_data_as_csv()メソッド宣言（151行目） |
| 1-2 | editor_visual_profiler.h | `editor/debugger/editor_visual_profiler.h` | frame_metrics、Metric構造の定義 |

**読解のコツ**: EditorFrameProfiler::Metricは別のクラスで定義されている可能性がある。コメントアウトされたコード内の参照を確認。

#### Step 2: 現在の実装状態を確認する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | editor_visual_profiler.cpp | `editor/debugger/editor_visual_profiler.cpp` | get_data_as_csv()（697-749行目）の現在の実装 |

**主要処理フロー**:
- **697行目**: Vector<Vector<String>> EditorVisualProfiler::get_data_as_csv() constで関数定義
- **698行目**: Vector<Vector<String>> resで結果変数を宣言
- **699行目**: #if 0でコメントアウト開始
- **700-746行目**: コメントアウトされた実装コード
- **747行目**: #endifでコメントアウト終了
- **748行目**: return resで空のVectorを返却

#### Step 3: コメントアウトされた実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | editor_visual_profiler.cpp | `editor/debugger/editor_visual_profiler.cpp` | #if 0内のコード（700-746行目）の実装意図 |

**コメントアウト内の処理フロー**:
- **700-702行目**: frame_metricsが空なら空Vector返却
- **705-715行目**: 最初のフレームからシグネチャを収集
- **716行目**: res.push_back(signatures)でヘッダー行追加
- **722-745行目**: フレームデータ出力ループ

### プログラム呼び出し階層図

```
EditorVisualProfiler::get_data_as_csv()
    │
    ├─ Vector<Vector<String>> res 宣言
    │
    ├─ #if 0 [コメントアウト開始]
    │      │
    │      ├─ frame_metrics.is_empty() チェック
    │      │      └─ [空なら空Vector返却]
    │      │
    │      ├─ シグネチャ収集ループ（frame_metrics[0].categories）
    │      │      │
    │      │      ├─ signatures.push_back(c.signature)
    │      │      │
    │      │      └─ items[k].signature収集
    │      │
    │      ├─ res.push_back(signatures) [ヘッダー行]
    │      │
    │      └─ フレームデータ出力ループ
    │             │
    │             ├─ valid チェック
    │             │
    │             ├─ categories イテレーション
    │             │      └─ values[it++] = num_real(total_time)
    │             │
    │             ├─ items イテレーション
    │             │      └─ values[it++] = num_real(total)
    │             │
    │             └─ res.push_back(values)
    │
    ├─ #endif [コメントアウト終了]
    │
    └─ return res [空のVectorを返却]
```

### データフロー図（想定仕様）

```
[入力]                        [処理]                         [出力]

リモートプロセス ─────────▶ レンダリング ────────────────▶ frame_metrics
                              プロファイリング          (Vector<Metric>)
                                                                │
                                                                │
frame_metrics[0] ────────▶ シグネチャ収集 ─────────────────▶ signatures
.categories                                               (Vector<String>)
                                                                │
                                                                │
                          ヘッダー行生成 ◀─────────────────────┘
                               │
                               ▼
全フレーム ──────────────▶ フレームデータ変換 ──────────────▶ CSVデータ行
                               │
                               ▼
                        Vector<Vector<String>> res
                               │
                               ▼
                    [現在は空のVector返却]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| editor_visual_profiler.h | `editor/debugger/editor_visual_profiler.h` | ヘッダー | EditorVisualProfilerクラス定義 |
| editor_visual_profiler.cpp | `editor/debugger/editor_visual_profiler.cpp` | ソース | get_data_as_csv()の実装（現在コメントアウト） |
| editor_profiler.h | `editor/debugger/editor_profiler.h` | ヘッダー | 参考：類似のスクリプトプロファイラー実装 |
| editor_profiler.cpp | `editor/debugger/editor_profiler.cpp` | ソース | 参考：get_data_as_csv()の実装例 |
