Dirty Rows
PlaydateにおけるDirty Rowsとは、ディスプレイの描画更新を最適化するための行単位の管理フラグのことです。
Playdateが採用している「
Sharp Memory LCD」のハードウェア特性を最大限に活かし、
CPU負荷と消費電力を抑えるための非常に重要な仕組みです。
概要
1. なぜ「行(Row)」単位なのか
- SPI通信の節約
- 画面全体(240行)を毎回送ると通信量が増えますが、変更があった数行だけを送れば、通信時間を大幅に短縮できます。
- 省電力
- 通信時間が減ることは、そのままバッテリー消費の抑制に直結します。
- CPU負荷の軽減
- 描画(レンダリング)自体を「変化があった行」だけに限定することで、描画処理の高速化が図れます。
2. 仕組み:Dirty Flag
Playdate OSは、画面の縦方向(240ピクセル)に対応する240個のフラグ(Dirty Flags)を内部で保持しています。
- 1. 描画時
- スプライトが動いたり、図形を描画したりすると、その描画範囲が含まれる行のフラグが「Dirty(汚れている=更新が必要)」にセットされます。
- 2. 転送時
- `playdate.display.flush()`(通常は毎フレームの最後)が呼ばれると、システムはフラグをチェックし、Dirtyな行のデータだけを液晶にSPI転送します。
- 3. 完了後
- 転送が終わると、すべてのフラグが「Clean(更新済み)」にリセットされます。
3. 開発における「Dirty Rows」の扱い
- Lua SDKの場合
- Luaを使用している場合、playdate.graphics.sprite システムを使っていれば、システムがスプライトの移動範囲を自動計算してDirty Rowsをマークしてくれるため、開発者は意識する必要がありません。
- C API / Rust 等で低レイヤー操作をする場合
- playdate->graphics->getFrame() を使用して、フレームバッファのメモリを直接書き換える場合は注意が必要です。
- メモリを直接いじっただけでは、システムは「どの行が変更されたか」を知ることができません。そのため、手動で「ここを書き換えたぞ」と教える必要があります。
playdate->graphics->markUpdatedRows(int start, int end)
- start: 更新を開始した行のインデックス(0-239)
- end: 更新を終了した行のインデックス
- この関数を呼ばないと、バッファの中身を書き換えても画面に反映されません(または古い内容が表示され続けます)。
4. 最適化のアドバイス
- 縦長のオブジェクトに注意
- Dirty Rowsは「横一行」が単位です。
- たとえ1ピクセル幅の細い線であっても、それが画面の一番上から下まで伸びていれば、240行すべてがDirtyとなり、全画面更新と同等の負荷がかかります。
- 横方向の移動は効率的
- 横に長いスプライトが上下に動かない場合、更新される行数は最小限(スプライトの高さ分)で済みます。
- 全画面描画のコスト
- gfx.clear() を毎フレーム呼ぶと、全240行がDirtyになります。
- 背景が変わらないゲームであれば、スプライトが動いた跡だけを描き直す(Dirty Rectsによる管理)ことで、Dirty Rowsを劇的に減らせます。
関連ページ
最終更新:2026年04月29日 07:30