# 機能設計書 9-Metalレンダラー

## 概要

本ドキュメントは、GhosttyターミナルエミュレータにおけるmacOS向けのMetalを使用した高性能GPUレンダリング「Metalレンダラー」機能の設計を記述する。

### 本機能の処理概要

Metalレンダラーは、AppleのMetalグラフィックスAPIを使用して端末画面を高速にGPU描画する。トリプルバッファリング、IOSurfaceLayerによる効率的な画面更新、sRGBガンマ補正による正確な色再現、カスタムシェーダーサポートを提供する。

**業務上の目的・背景**：macOSにおいて最高のレンダリングパフォーマンスを実現するためには、ネイティブのMetalAPIを使用する必要がある。OpenGLは非推奨となっており、MetalによるGPU直接アクセスにより低レイテンシで高フレームレートの描画が可能となる。

**機能の利用シーン**：
- 大量のテキスト出力を高速に表示する場面
- アニメーションやカーソル点滅を滑らかに表示する場面
- 高DPIディスプレイ（Retina）で鮮明に表示する場面
- カスタムシェーダーで視覚効果を適用する場面

**主要な処理内容**：
1. MTLDevice/MTLCommandQueueの初期化
2. IOSurfaceLayerによるレイヤーホスティング
3. トリプルバッファリングによるスワップチェーン管理
4. シェーダーのコンパイルとパイプライン構築
5. セルグリッドの効率的な描画
6. sRGBガンマ補正によるリニアアルファブレンディング

**関連システム・外部連携**：
- macOS Metal Framework
- IOSurface Framework
- フォントアトラス
- カスタムシェーダー（Shadertoy形式）

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインターミナルウィンドウ | 主画面 | macOS向けMetalを使用した高性能GPUレンダリング |

## 機能種別

レンダリング / GPU処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| rt_surface | Surface | Yes | レンダリングターゲットサーフェス | 有効なサーフェス |
| config | Config | Yes | レンダリング設定 | - |

### 入力データソース

- Terminal/Screen構造体からのセルデータ
- フォントアトラスからのグリフテクスチャ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| rendered_frame | IOSurface | 描画されたフレーム |

### 出力先

- NSView/UIViewのレイヤー

## 処理フロー

### 処理シーケンス

```
1. Metal初期化
   └─ chooseDevice()でMTLDevice選択
   └─ newCommandQueue()でキュー作成
   └─ IOSurfaceLayer作成とビューへの設定

2. シェーダー初期化
   └─ initShaders()でシェーダーコンパイル
   └─ パイプライン構築

3. フレーム描画
   └─ drawFrameStart()でAutoreleasePool開始
   └─ セルデータをバッファに転送
   └─ レンダーパスで描画
   └─ present()でIOSurfaceを設定
   └─ drawFrameEnd()でプール解放

4. リソース管理
   └─ 統一メモリ（shared）または管理メモリ（managed）
   └─ 最大テクスチャサイズの考慮
```

### フローチャート

```mermaid
flowchart TD
    A[Metal.init] --> B[chooseDevice]
    B --> C[newCommandQueue]
    C --> D[IOSurfaceLayer作成]
    D --> E[ビューにレイヤー設定]

    F[drawFrame] --> G[drawFrameStart]
    G --> H[AutoreleasePool開始]
    H --> I[バッファ更新]
    I --> J[RenderPass実行]
    J --> K[present]
    K --> L[drawFrameEnd]
    L --> M[AutoreleasePool解放]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | トリプルバッファリング | swap_chain_count=3でトリプルバッファ | 常時 |
| BR-002 | 統一メモリ優先 | hasUnifiedMemoryならsharedモード使用 | デバイス判定時 |
| BR-003 | sRGBピクセルフォーマット | リニアブレンディング時はbgra8unorm_srgb | blending.isLinear時 |
| BR-004 | 最大テクスチャサイズ制限 | サーフェスサイズを制限 | surfaceSize時 |

### 計算ロジック

- contentsScale: ビュー座標をピクセル座標に変換
- サーフェスサイズ: bounds.size * scale、max_texture_sizeでクランプ

## データベース操作仕様

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-001 | デバイス取得失敗 | Metal非サポート環境 | エラーを伝播 |
| E-002 | シェーダーコンパイル失敗 | 不正なシェーダーコード | エラーログ出力 |

### リトライ仕様

リトライ機構は使用しない。

## トランザクション仕様

トランザクション処理は使用しない。

## パフォーマンス要件

- フレームレート: 60fps以上
- レイテンシ: 16ms以下（vsync同期）
- メモリ効率: 統一メモリによるゼロコピー（可能な場合）

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

特になし。

## 備考

- macOSとiOSの両方をサポート
- ディスクリートGPUはmanagedモードを使用

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Metal.zig | `src/renderer/Metal.zig` | Metal構造体、フィールド定義 |
| 1-2 | metal/Target.zig | `src/renderer/metal/Target.zig` | レンダーターゲット |
| 1-3 | metal/IOSurfaceLayer.zig | `src/renderer/metal/IOSurfaceLayer.zig` | IOSurfaceレイヤー |

**読解のコツ**: `Metal`構造体はlayer、device、queue、blending、default_storage_mode等を持つ。`IOSurfaceLayer`がビューへの描画を担当。

#### Step 2: 初期化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Metal.zig | `src/renderer/Metal.zig` | init()関数 |
| 2-2 | Metal.zig | `src/renderer/Metal.zig` | chooseDevice()（非表示だが内部で呼び出し） |

**主要処理フロー**:
- **64-156行目**: `init()` - MTLDevice選択、IOSurfaceLayer作成、ビュー設定
- **79-84行目**: default_storage_mode決定（unified memory判定）
- **111-134行目**: レイヤーをビューに設定

#### Step 3: 描画処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Metal.zig | `src/renderer/Metal.zig` | drawFrameStart/End |
| 3-2 | Metal.zig | `src/renderer/Metal.zig` | present()関数 |

**主要処理フロー**:
- **181-184行目**: `drawFrameStart()` - AutoreleasePool開始
- **188-192行目**: `drawFrameEnd()` - AutoreleasePool解放
- **253-259行目**: `present()` - IOSurfaceを設定

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

```
Metal
    |
    +-- init()
    |      +-- chooseDevice()
    |      +-- newCommandQueue()
    |      +-- IOSurfaceLayer.init()
    |      +-- view.setProperty("layer", ...)
    |
    +-- initShaders()
    |      +-- shaders.Shaders.init()
    |
    +-- drawFrameStart()
    |      +-- AutoreleasePool.init()
    |
    +-- present()
    |      +-- layer.setSurface() / setSurfaceSync()
    |
    +-- drawFrameEnd()
           +-- autorelease_pool.deinit()
```

### データフロー図

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

セルデータ ──────────> Buffer更新
                           |
                           v
フォントアトラス ─────> RenderPass
                           |
                           v
                    描画コマンド ────────> IOSurface
                           |
                           v
                    present() ──────────> NSView/UIView
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Metal.zig | `src/renderer/Metal.zig` | ソース | Metalレンダラーのメインロジック |
| metal/Target.zig | `src/renderer/metal/Target.zig` | ソース | レンダーターゲット |
| metal/IOSurfaceLayer.zig | `src/renderer/metal/IOSurfaceLayer.zig` | ソース | IOSurfaceレイヤー管理 |
| metal/Frame.zig | `src/renderer/metal/Frame.zig` | ソース | フレーム管理 |
| metal/Pipeline.zig | `src/renderer/metal/Pipeline.zig` | ソース | レンダーパイプライン |
| metal/shaders.zig | `src/renderer/metal/shaders.zig` | ソース | シェーダー管理 |
| metal/buffer.zig | `src/renderer/metal/buffer.zig` | ソース | バッファ管理 |
| metal/Texture.zig | `src/renderer/metal/Texture.zig` | ソース | テクスチャ管理 |
