Skip to content

Commit c9fb1d9

Browse files
committed
Fix GPU driver deadlock by implementing static cache for HDR luminance hardware detection
1 parent 8f420a3 commit c9fb1d9

4 files changed

Lines changed: 26 additions & 4 deletions

File tree

QuickView/DisplayColorInfo.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,14 @@ float QueryIccPeakLuminance(const std::wstring& gdiDeviceName) {
137137
}
138138

139139
} // namespace
140+
141+
static float s_cachedHardwarePeakNits = -1.0f;
142+
static float s_cachedSdrWhiteLevel = -1.0f;
140143

141-
144+
void DisplayColorInfo::InvalidateHardwareCache() {
145+
s_cachedHardwarePeakNits = -1.0f;
146+
s_cachedSdrWhiteLevel = -1.0f;
147+
}
142148

143149
float DisplayColorState::GetEffectivePeakNits(float peakNitsOverride) const {
144150
float peak = (maxLuminanceNits > sdrWhiteLevelNits) ? maxLuminanceNits : sdrWhiteLevelNits;
@@ -264,6 +270,12 @@ bool DisplayColorInfo::QueryForMonitor(HMONITOR monitor, DisplayColorState* stat
264270
// [Logging] Capture Level 3 detection (Raw DXGI/EDID)
265271
float dxgiPeak = stateOut->maxLuminanceNits;
266272

273+
if (s_cachedHardwarePeakNits > 0.0f) {
274+
stateOut->maxLuminanceNits = s_cachedHardwarePeakNits;
275+
stateOut->sdrWhiteLevelNits = s_cachedSdrWhiteLevel;
276+
return true;
277+
}
278+
267279
// Get accurate Peak Luminance and SDR white via a multi-tier fallback pipeline.
268280
float winrtMaxNits = 0.0f;
269281
float winrtSdrWhite = 0.0f;
@@ -293,6 +305,9 @@ bool DisplayColorInfo::QueryForMonitor(HMONITOR monitor, DisplayColorState* stat
293305
} else {
294306
stateOut->sdrWhiteLevelNits = QuerySdrWhiteLevelNits(stateOut->gdiDeviceName);
295307
}
308+
309+
s_cachedHardwarePeakNits = stateOut->maxLuminanceNits;
310+
s_cachedSdrWhiteLevel = stateOut->sdrWhiteLevelNits;
296311

297312
return true;
298313
}

QuickView/DisplayColorInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ class DisplayColorInfo {
112112
public:
113113
bool Refresh(HWND hwnd, bool forceHdrSimulation = false);
114114
static bool QueryMonitorState(HMONITOR monitor, DisplayColorState* stateOut);
115+
static void InvalidateHardwareCache();
115116
const DisplayColorState& GetState() const { return m_state; }
116117

117118
private:

QuickView/ImageLoader.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5369,7 +5369,7 @@ namespace QuickView {
53695369
// [Ultra HDR] Phase 2: Extract MPF Gain Map (uses pBuf which
53705370
// is still alive — it's the original file buffer)
53715371
// ============================================================
5372-
if (hasUltraHdr) {
5372+
if (hasUltraHdr && !PrefersSdrTarget(ctx)) {
53735373
result.metadata.hdrMetadata.hasGainMap = true;
53745374
result.metadata.hdrMetadata.isValid = true;
53755375
result.metadata.hdrMetadata.transfer = QuickView::TransferFunction::SRGB;
@@ -6021,7 +6021,9 @@ namespace QuickView {
60216021
avifDecoder* decoder = avifDecoderCreate();
60226022
if (!decoder) return E_OUTOFMEMORY;
60236023

6024-
decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_GAIN_MAP;
6024+
if (!PrefersSdrTarget(ctx)) {
6025+
decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_GAIN_MAP;
6026+
}
60256027

60266028
decoder->strictFlags = AVIF_STRICT_DISABLED;
60276029
const unsigned int threads = std::thread::hardware_concurrency();
@@ -7156,7 +7158,7 @@ HRESULT CImageLoader::LoadImageUnified(LPCWSTR filePath, const DecodeContext& ct
71567158
HRESULT hr = WIC_HEIC::Load(filePath, ctx, result, m_wicFactory.Get());
71577159
if (SUCCEEDED(hr)) {
71587160
// [v10.3] Async Gain Map Decode for HEIC
7159-
if (result.metadata.hdrMetadata.hasGainMap && ctx.onAuxLayerReady) {
7161+
if (result.metadata.hdrMetadata.hasGainMap && ctx.onAuxLayerReady && !PrefersSdrTarget(ctx)) {
71607162
// Copy necessary data to pass to thread
71617163
std::vector<uint8_t> threadData(mappedData, mappedData + mappedSize);
71627164
float headroom = result.metadata.hdrMetadata.gainMapAlternateHeadroom;

QuickView/main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6362,6 +6362,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
63626362
HMONITOR hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
63636363
if (hMon != s_lastCmsMonitor) {
63646364
s_lastCmsMonitor = hMon;
6365+
QuickView::DisplayColorInfo::InvalidateHardwareCache();
63656366
RefreshDisplayColorPipeline(hwnd, false);
63666367
// Trigger CMS update (All managed modes now depend on the current monitor profile)
63676368
extern AppConfig g_config;
@@ -6376,11 +6377,13 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
63766377
}
63776378
case WM_DISPLAYCHANGE: {
63786379
// [CMS] System/Monitor profile changed
6380+
QuickView::DisplayColorInfo::InvalidateHardwareCache();
63796381
RefreshDisplayColorPipeline(hwnd, true);
63806382
break;
63816383
}
63826384
case WM_SETTINGCHANGE:
63836385
case WM_THEMECHANGED: {
6386+
QuickView::DisplayColorInfo::InvalidateHardwareCache();
63846387
if (g_config.ThemeMode == 0) {
63856388
ApplyWindowTheme(hwnd);
63866389
RequestRepaint(PaintLayer::All);
@@ -6801,6 +6804,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
68016804
// wParam: LOWORD = new X DPI, HIWORD = new Y DPI
68026805
// lParam: pointer to RECT with suggested new window size/position
68036806
const UINT newDpiX = LOWORD(wParam);
6807+
QuickView::DisplayColorInfo::InvalidateHardwareCache();
68046808
RefreshWindowDpi(hwnd, newDpiX);
68056809

68066810
RECT* pNewRect = (RECT*)lParam;

0 commit comments

Comments
 (0)