1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//! WicCore - WIC関連リソース(Device Lostの影響を受けない)
//!
//! WICはCPUベースのイメージ処理のため、GPUのDevice Lostとは独立。
//! GraphicsCore.invalidate()時もWicCoreは有効なまま。
use *;
use OnceLock;
use D2D::*;
use *;
use *;
use Result;
/// プロセス寿命の暗黙 MTA を一度だけ確立するためのガード(cookie は保持しない=leak)。
static MTA_KEEPER: = new;
/// WIC factory 生成に先立ち、本プロセスに **プロセス寿命の暗黙 MTA** を確立する(DD-9)。
///
/// 背景(根本原因): layout 等のテストバイナリは `CoInitializeEx` を呼ばないため、
/// `WicCore::new()` の `CoCreateInstance` が「たまたま並走テストの副作用で立っている
/// 一時的 MTA」の窓で成功しうる。その借り物 MTA が解体されると COM ランタイムごと
/// factory が解放され、`EcsWorld` drop 時の `IUnknown::Release` が use-after-free
/// (0xC0000005)を起こす。
///
/// 処方(interest-keeper と同型): `CoIncrementMTAUsage` で暗黙 MTA を**自ら**常駐させる。
/// 返る `CO_MTA_USAGE_COOKIE` は保持せず意図的に leak する(`CoDecrementMTAUsage` は
/// 呼ばない)=MTA をプロセス寿命で生かし続けるのが目的。`OnceLock` で初回のみ確立し、
/// 以降は no-op。`CoIncrementMTAUsage` の失敗(極稀)は `?` で `Err` 伝播し、
/// panic しない(縮退は呼び元 `world/mod.rs` の log-first が担う)。
/// WIC関連リソース
///
/// WICファクトリを保持し、画像デコード機能を提供する。
/// Device Lostの影響を受けない独立リソース。
// SAFETY 条件: windows-rs 0.62.2 は WIC インターフェイス(`IWICImagingFactory2` 等)に
// Send/Sync を自動生成しない(Imaging モジュールに `unsafe impl Send` が存在しない)ため、
// この手動 impl は必須である。健全性は WIC の free-threaded(thread-free marshaling)特性に
// 依拠する: ファクトリは `CLSCTX_INPROC_SERVER` で生成され、跨スレッドで直接アクセス可能。
// 呼び元スレッドの apartment 状態に依存しない: `WicCore::new` は `CoCreateInstance` の前に
// `ensure_process_mta`(`CoIncrementMTAUsage`)を呼び、**自ら**プロセス寿命の暗黙 MTA を
// 強制する(cookie を leak=decrement しない)。これにより factory は「呼び元が
// `CoInitializeEx(COINIT_MULTITHREADED)` 済みである前提」に依存せず、**常に生存する COM
// ランタイム上に在る**。借り物 MTA(並走テストの副作用で立つ一時的 MTA)の解体で COM が
// factory ごと解放され、drop 時の `IUnknown::Release` が use-after-free(0xC0000005)を
// 起こす経路を構造的に根絶する(DD-9)。実利用上、`WicCore` は clone されて `WintfTaskPool`
// のバックグラウンドワーカーへ move され(Send)、`factory()` の読み取り参照でデコードに
// 用いられる(Sync)。
unsafe
unsafe