From e19ea5f987fd6157a0f2fb85f87006cfeedb111c Mon Sep 17 00:00:00 2001 From: ALTaleX <2368730049@qq.com> Date: Thu, 2 May 2024 13:34:18 +0800 Subject: [PATCH] improve aero shader and fix config reading problems --- DWMBlurGlassExt/Backdrops/AcrylicBackdrop.hpp | 320 +++++++++++++++++- DWMBlurGlassExt/Backdrops/AeroBackdrop.hpp | 270 +++++++++++++-- DWMBlurGlassExt/Backdrops/BlurBackdrop.hpp | 153 ++++++++- 3 files changed, 714 insertions(+), 29 deletions(-) diff --git a/DWMBlurGlassExt/Backdrops/AcrylicBackdrop.hpp b/DWMBlurGlassExt/Backdrops/AcrylicBackdrop.hpp index 24b6f01..58209de 100644 --- a/DWMBlurGlassExt/Backdrops/AcrylicBackdrop.hpp +++ b/DWMBlurGlassExt/Backdrops/AcrylicBackdrop.hpp @@ -186,6 +186,322 @@ namespace MDWMBlurGlassExt::AcrylicBackdrop effectBrush.SetSourceParameter(L"Noise", noiceBrush); effectBrush.SetSourceParameter(L"Backdrop", compositor.CreateBackdropBrush()); - return effectBrush; - } + return effectBrush; + } + catch (...) { return nullptr; } + + static winrt::Windows::UI::Composition::CompositionSurfaceBrush CreateNoiceSurfaceBrush( + const winrt::Windows::UI::Composition::Compositor& compositor, + ID2D1Device* d2dDevice + ) try + { + winrt::Windows::UI::Composition::CompositionGraphicsDevice graphicsDevice{ nullptr }; + THROW_IF_FAILED( + compositor.as()->CreateGraphicsDevice( + d2dDevice, + reinterpret_cast(winrt::put_abi(graphicsDevice)) + ) + ); + auto compositionSurface + { + graphicsDevice.CreateDrawingSurface( + { 256.f, 256.f }, + winrt::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16Float, + winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied + ) + }; + auto noiceBrush{ compositor.CreateSurfaceBrush(compositionSurface) }; + + wil::unique_hmodule wuxcModule{ LoadLibraryExW(L"Windows.UI.Xaml.Controls.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE) }; + THROW_LAST_ERROR_IF_NULL(wuxcModule); + auto resourceHandle{ FindResourceW(wuxcModule.get(), MAKEINTRESOURCE(2000), RT_RCDATA) }; + THROW_LAST_ERROR_IF_NULL(resourceHandle); + auto globalHandle{ LoadResource(wuxcModule.get(), resourceHandle) }; + THROW_LAST_ERROR_IF_NULL(globalHandle); + auto cleanUp = wil::scope_exit([&] + { + if (globalHandle) + { + UnlockResource(globalHandle); + FreeResource(globalHandle); + } + }); + DWORD resourceSize{ SizeofResource(wuxcModule.get(), resourceHandle) }; + THROW_LAST_ERROR_IF(resourceSize == 0); + auto resourceAddress{ reinterpret_cast(LockResource(globalHandle)) }; + winrt::com_ptr stream{ SHCreateMemStream(resourceAddress, resourceSize), winrt::take_ownership_from_abi }; + THROW_LAST_ERROR_IF_NULL(stream); + + winrt::com_ptr wicFactory{ nullptr }; + wicFactory.copy_from(DWM::CDesktopManager::s_pDesktopManagerInstance->GetWICFactory()); + winrt::com_ptr wicDecoder{ nullptr }; + THROW_IF_FAILED(wicFactory->CreateDecoderFromStream(stream.get(), &GUID_VendorMicrosoft, WICDecodeMetadataCacheOnDemand, wicDecoder.put())); + winrt::com_ptr wicFrame{ nullptr }; + THROW_IF_FAILED(wicDecoder->GetFrame(0, wicFrame.put())); + winrt::com_ptr wicConverter{ nullptr }; + THROW_IF_FAILED(wicFactory->CreateFormatConverter(wicConverter.put())); + winrt::com_ptr wicPalette{ nullptr }; + THROW_IF_FAILED( + wicConverter->Initialize( + wicFrame.get(), + GUID_WICPixelFormat32bppPBGRA, + WICBitmapDitherTypeNone, + wicPalette.get(), + 0, WICBitmapPaletteTypeCustom + ) + ); + winrt::com_ptr wicBitmap{ nullptr }; + THROW_IF_FAILED(wicFactory->CreateBitmapFromSource(wicConverter.get(), WICBitmapCreateCacheOption::WICBitmapNoCache, wicBitmap.put())); + + auto drawingSurfaceInterop{ compositionSurface.as() }; + POINT offset = { 0, 0 }; + winrt::com_ptr d2dContext{ nullptr }; + THROW_IF_FAILED( + drawingSurfaceInterop->BeginDraw(nullptr, IID_PPV_ARGS(d2dContext.put()), &offset) + ); + d2dContext->Clear(); + winrt::com_ptr d2dBitmap{ nullptr }; + d2dContext->CreateBitmapFromWicBitmap( + wicBitmap.get(), + D2D1::BitmapProperties1( + D2D1_BITMAP_OPTIONS_NONE, + D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED) + ), + d2dBitmap.put() + ); + d2dContext->DrawBitmap(d2dBitmap.get()); + THROW_IF_FAILED( + drawingSurfaceInterop->EndDraw() + ); + + return noiceBrush; + } + catch (...) { return nullptr; } + + void STDMETHODCALLTYPE ReloadParameters() + { + crossfadeTime = std::chrono::milliseconds{ g_configData.crossfadeTime }; + + if(g_configData.useAccentColor) + { + darkMode_Active_Color = MakeWinrtColor(g_accentColor); + darkMode_Inactive_Color = darkMode_Active_Color; + lightMode_Active_Color = darkMode_Inactive_Color; + lightMode_Inactive_Color = lightMode_Active_Color; + } + else + { + darkMode_Active_Color = MakeWinrtColor(g_configData.activeBlendColorDark); + darkMode_Inactive_Color = MakeWinrtColor(g_configData.inactiveBlendColorDark); + lightMode_Active_Color = MakeWinrtColor(g_configData.activeBlendColor); + lightMode_Inactive_Color = MakeWinrtColor(g_configData.inactiveBlendColor); + } + lightMode_Active_TintOpacity = GetFloatAlpha(g_configData.activeBlendColor); + lightMode_Inactive_TintOpacity = GetFloatAlpha(g_configData.inactiveBlendColor); + darkMode_Active_TintOpacity = GetFloatAlpha(g_configData.activeBlendColorDark); + darkMode_Inactive_TintOpacity = GetFloatAlpha(g_configData.inactiveBlendColorDark); + + lightMode_Active_LuminosityOpacity = g_configData.luminosityOpacity; + lightMode_Inactive_LuminosityOpacity = g_configData.luminosityOpacity; + darkMode_Active_LuminosityOpacity = g_configData.luminosityOpacity; + darkMode_Inactive_LuminosityOpacity = g_configData.luminosityOpacity; + + blurAmount = g_configData.customBlurAmount; + } + winrt::Windows::UI::Composition::CompositionBrush STDMETHODCALLTYPE GetBrush(bool useDarkMode, bool windowActivated) override try + { + auto is_device_valid = [&]() + { + if (!interopDCompDevice) return false; + + BOOL valid{ FALSE }; + THROW_IF_FAILED( + interopDCompDevice.as()->CheckDeviceState( + &valid + ) + ); + + return valid == TRUE; + }; + if (!is_device_valid()) + { + interopDCompDevice.copy_from( + DWM::CDesktopManager::s_pDesktopManagerInstance->GetDCompositionInteropDevice() + ); + ReloadParameters(); + auto compositor{ interopDCompDevice.as() }; + auto noiceBrush{ CreateNoiceSurfaceBrush(compositor, DWM::CDesktopManager::s_pDesktopManagerInstance->GetD2DDevice()) }; + + lightMode_Active_Brush = CreateBrush( + compositor, + noiceBrush, + GetEffectiveTintColor(lightMode_Active_Color, lightMode_Active_TintOpacity, lightMode_Active_LuminosityOpacity), + GetEffectiveLuminosityColor(lightMode_Active_Color, lightMode_Active_TintOpacity, lightMode_Active_LuminosityOpacity), + blurAmount, + hostBackdrop + ); + lightMode_Inactive_Brush = CreateBrush( + compositor, + noiceBrush, + GetEffectiveTintColor(lightMode_Inactive_Color, lightMode_Inactive_TintOpacity, lightMode_Inactive_LuminosityOpacity), + GetEffectiveLuminosityColor(lightMode_Inactive_Color, lightMode_Inactive_TintOpacity, lightMode_Inactive_LuminosityOpacity), + blurAmount, + hostBackdrop + ); + darkMode_Active_Brush = CreateBrush( + compositor, + noiceBrush, + GetEffectiveTintColor(darkMode_Active_Color, darkMode_Active_TintOpacity, darkMode_Active_LuminosityOpacity), + GetEffectiveLuminosityColor(darkMode_Active_Color, darkMode_Active_TintOpacity, darkMode_Active_LuminosityOpacity), + blurAmount, + hostBackdrop + ); + darkMode_Inactive_Brush = CreateBrush( + compositor, + noiceBrush, + GetEffectiveTintColor(darkMode_Inactive_Color, darkMode_Inactive_TintOpacity, darkMode_Inactive_LuminosityOpacity), + GetEffectiveLuminosityColor(darkMode_Inactive_Color, darkMode_Inactive_TintOpacity, darkMode_Inactive_LuminosityOpacity), + blurAmount, + hostBackdrop + ); + } + + return CDCompResources::GetBrush(useDarkMode, windowActivated); + } + catch (...) { return nullptr; } + }; + + struct CAcrylicBackdrop : CDCompBackdrop + { + inline static CAcrylicResources s_sharedResources{}; + + STDMETHOD(UpdateColorizationColor)( + bool useDarkMode, + bool windowActivated + ) override + { + if (useDarkMode) + { + if (windowActivated) { currentColor = s_sharedResources.darkMode_Active_Color; } + else { currentColor = s_sharedResources.darkMode_Inactive_Color; } + } + else + { + if (windowActivated) { currentColor = s_sharedResources.lightMode_Active_Color; } + else { currentColor = s_sharedResources.lightMode_Inactive_Color; } + } + + return S_OK; + } + HRESULT STDMETHODCALLTYPE Update( + bool useDarkMode, + bool windowActivated + ) try + { + THROW_IF_FAILED(UpdateColorizationColor(useDarkMode, windowActivated)); + THROW_IF_FAILED( + TryCrossFadeToNewBrush( + spriteVisual.Compositor(), + s_sharedResources.GetBrush(useDarkMode, windowActivated), + s_sharedResources.crossfadeTime + ) + ); + + return S_OK; + } + CATCH_RETURN() + }; + + struct CAccentAcrylicResources : CDCompResourcesBase + { + winrt::Windows::UI::Composition::CompositionSurfaceBrush noiceBrush{ nullptr }; + + HRESULT STDMETHODCALLTYPE EnsureNoiceSurfaceBrush() try + { + auto is_device_valid = [&]() + { + if (!interopDCompDevice) return false; + + BOOL valid{ FALSE }; + THROW_IF_FAILED( + interopDCompDevice.as()->CheckDeviceState( + &valid + ) + ); + + return valid == TRUE; + }; + if (!is_device_valid()) + { + interopDCompDevice.copy_from( + DWM::CDesktopManager::s_pDesktopManagerInstance->GetDCompositionInteropDevice() + ); + noiceBrush = CAcrylicResources::CreateNoiceSurfaceBrush( + interopDCompDevice.as(), + DWM::CDesktopManager::s_pDesktopManagerInstance->GetD2DDevice() + ); + } + + return S_OK; + } + CATCH_RETURN() + }; + struct CAccentAcrylicBackdrop : CAccentDCompBackdrop + { + inline static CAccentAcrylicResources s_sharedResources{}; + bool usingLuminosity{ false }; + winrt::Windows::UI::Color currenTintColor{}; + + HRESULT STDMETHODCALLTYPE UpdateBrush(const DWM::ACCENT_POLICY& policy) try + { + s_sharedResources.ReloadParameters(); + THROW_IF_FAILED(s_sharedResources.EnsureNoiceSurfaceBrush()); + + auto compositor{ spriteVisual.Compositor() }; + auto useLuminosity + { + MDWMBlurGlass::os::buildNumber >= 22000 && + (policy.nFlags & 2) != 0 && + ( + (policy.nAccentState == 3 && MDWMBlurGlass::os::buildNumber > 22000) || + (policy.nAccentState == 4) + ) + }; + auto tintColor{ FromAbgr(policy.nColor) }; + if ( + usingLuminosity != useLuminosity || + currenTintColor != tintColor || + interopDCompDevice != s_sharedResources.interopDCompDevice + ) + { + interopDCompDevice = s_sharedResources.interopDCompDevice; + usingLuminosity = useLuminosity; + currenTintColor = tintColor; + + auto tintOpacity{ static_cast(tintColor.A) / 255.f }; + tintColor.A = 255; + spriteVisual.Brush( + CAcrylicResources::CreateBrush( + compositor, + s_sharedResources.noiceBrush, + CAcrylicResources::GetEffectiveTintColor(tintColor, tintOpacity, useLuminosity ? std::optional{ 1.03f } : std::nullopt), + CAcrylicResources::GetEffectiveLuminosityColor(tintColor, tintOpacity, useLuminosity ? std::optional{ 1.03f } : std::nullopt), + CAcrylicBackdrop::s_sharedResources.blurAmount, + CAcrylicBackdrop::s_sharedResources.hostBackdrop + ) + ); + } + + return S_OK; + } + CATCH_RETURN() + + HRESULT STDMETHODCALLTYPE Update(const DWM::ACCENT_POLICY& policy) override try + { + THROW_IF_FAILED(UpdateBrush(policy)); + + return S_OK; + } + CATCH_RETURN() + }; } \ No newline at end of file diff --git a/DWMBlurGlassExt/Backdrops/AeroBackdrop.hpp b/DWMBlurGlassExt/Backdrops/AeroBackdrop.hpp index 93aa953..0988f5f 100644 --- a/DWMBlurGlassExt/Backdrops/AeroBackdrop.hpp +++ b/DWMBlurGlassExt/Backdrops/AeroBackdrop.hpp @@ -41,9 +41,20 @@ namespace MDWMBlurGlassExt::AeroBackdrop } (compositor, blurAmount) }; - // the current recipe is modified from @kfh83, @TorutheRedFox, @aubymori - auto fallbackTintSource{ winrt::make_self() }; - fallbackTintSource->SetColor(wu::Color + static winrt::Windows::UI::Composition::CompositionBrush CreateBrush( + const winrt::Windows::UI::Composition::Compositor& compositor, + const winrt::Windows::UI::Color& mainColor, + const winrt::Windows::UI::Color& glowColor, + float colorBalance, + float glowBalance, + float blurAmount, + float blurBalance, + bool hostBackdrop + ) try + { + // the current recipe is modified from @kfh83, @TorutheRedFox, @aubymori + auto fallbackTintSource{ winrt::make_self() }; + fallbackTintSource->SetColor(winrt::Windows::UI::Color { 255, static_cast(min(blurBalance + 0.1f, 1.f) * 255.f), @@ -64,25 +75,25 @@ namespace MDWMBlurGlassExt::AeroBackdrop colorOpacityEffect->SetInput(*colorEffect); colorOpacityEffect->SetOpacity(colorBalance); - auto blurredBackdropBalanceEffect{ winrt::make_self() }; - blurredBackdropBalanceEffect->SetName(L"BlurBalance"); - blurredBackdropBalanceEffect->SetOpacity(blurBalance); - blurredBackdropBalanceEffect->SetInput(wuc::CompositionEffectSourceParameter{ L"BlurredBackdrop" }); + auto backdropBalanceEffect{ winrt::make_self() }; + backdropBalanceEffect->SetName(L"BlurBalance"); + backdropBalanceEffect->SetOpacity(blurBalance); + backdropBalanceEffect->SetInput(winrt::Windows::UI::Composition::CompositionEffectSourceParameter{ L"Backdrop" }); - auto actualBackdropEffect{ winrt::make_self() }; - actualBackdropEffect->SetCompositeMode(D2D1_COMPOSITE_MODE_PLUS); - actualBackdropEffect->SetDestination(*blackOrTransparentSource); - actualBackdropEffect->SetSource(*blurredBackdropBalanceEffect); + auto actualBackdropEffect{ winrt::make_self() }; + actualBackdropEffect->SetCompositeMode(D2D1_COMPOSITE_MODE_PLUS); + actualBackdropEffect->SetDestination(*blackOrTransparentSource); + actualBackdropEffect->SetSource(*backdropBalanceEffect); - auto desaturatedBlurredBackdrop{ winrt::make_self() }; - desaturatedBlurredBackdrop->SetSaturation(0.f); - desaturatedBlurredBackdrop->SetInput(wuc::CompositionEffectSourceParameter{ L"BlurredBackdrop" }); + auto desaturatedBackdrop{ winrt::make_self() }; + desaturatedBackdrop->SetSaturation(0.f); + desaturatedBackdrop->SetInput(winrt::Windows::UI::Composition::CompositionEffectSourceParameter{ L"Backdrop" }); - // make animation feel better... - auto backdropNotTransparentPromised{ winrt::make_self() }; - backdropNotTransparentPromised->SetCompositeMode(D2D1_COMPOSITE_MODE_SOURCE_OVER); - backdropNotTransparentPromised->SetDestination(*fallbackTintSource); - backdropNotTransparentPromised->SetSource(*desaturatedBlurredBackdrop); + // make animation feel better... + auto backdropNotTransparentPromised{ winrt::make_self() }; + backdropNotTransparentPromised->SetCompositeMode(D2D1_COMPOSITE_MODE_SOURCE_OVER); + backdropNotTransparentPromised->SetDestination(*fallbackTintSource); + backdropNotTransparentPromised->SetSource(*desaturatedBackdrop); // if the afterglowColor is black, then it will produce a completely transparent surface auto tintEffect{ winrt::make_self() }; @@ -99,9 +110,222 @@ namespace MDWMBlurGlassExt::AeroBackdrop compositeEffect->SetDestination(*backdropWithAfterGlow); compositeEffect->SetSource(*colorOpacityEffect); - auto effectBrush{ compositor.CreateEffectFactory(*compositeEffect).CreateBrush() }; - effectBrush.SetSourceParameter(L"BlurredBackdrop", blurredBackdropBrush); + auto gaussianBlurEffect{ winrt::make_self() }; + gaussianBlurEffect->SetName(L"Blur"); + gaussianBlurEffect->SetBorderMode(D2D1_BORDER_MODE_HARD); + gaussianBlurEffect->SetBlurAmount(blurAmount); + gaussianBlurEffect->SetInput(*compositeEffect); + + auto effectBrush{ compositor.CreateEffectFactory(*gaussianBlurEffect).CreateBrush() }; + effectBrush.SetSourceParameter(L"Backdrop", compositor.CreateBackdropBrush()); + + return effectBrush; + } + catch (...) { return nullptr; } + + void STDMETHODCALLTYPE ReloadParameters() override + { + crossfadeTime = std::chrono::milliseconds{ g_configData.crossfadeTime }; + + if (g_configData.useAccentColor) + { + darkMode_Active_Color = MakeWinrtColor(g_accentColor); + darkMode_Inactive_Color = darkMode_Active_Color; + lightMode_Active_Color = darkMode_Inactive_Color; + lightMode_Inactive_Color = lightMode_Active_Color; + } + else + { + darkMode_Active_Color = MakeWinrtColor(g_configData.activeBlendColorDark); + darkMode_Inactive_Color = MakeWinrtColor(g_configData.inactiveBlendColorDark); + lightMode_Active_Color = MakeWinrtColor(g_configData.activeBlendColor); + lightMode_Inactive_Color = MakeWinrtColor(g_configData.inactiveBlendColor); + } + + darkMode_Active_GlowColor = darkMode_Active_Color; + darkMode_Inactive_GlowColor = darkMode_Inactive_Color; + lightMode_Active_GlowColor = lightMode_Active_Color; + lightMode_Inactive_GlowColor = lightMode_Inactive_Color; + + // please altalex keep this as is or atleast try to keep this behavior + + lightMode_Active_ColorBalance = g_configData.aeroColorBalance; + lightMode_Inactive_ColorBalance = lightMode_Active_ColorBalance * 0.4f; + darkMode_Active_ColorBalance = g_configData.aeroColorBalance; + darkMode_Inactive_ColorBalance = darkMode_Active_ColorBalance * 0.4f; + + lightMode_Active_GlowBalance = g_configData.aeroAfterglowBalance; + lightMode_Inactive_GlowBalance = g_configData.aeroAfterglowBalance; + darkMode_Active_GlowBalance = g_configData.aeroAfterglowBalance; + darkMode_Inactive_GlowBalance = g_configData.aeroAfterglowBalance; + + Active_BlurBalance = g_configData.aeroBlurBalance; + Inactive_BlurBalance = (Active_BlurBalance * 0.4f) + 0.6f; + + blurAmount = g_configData.customBlurAmount; + } + + winrt::Windows::UI::Composition::CompositionBrush STDMETHODCALLTYPE GetBrush(bool useDarkMode, bool windowActivated) override try + { + auto is_device_valid = [&]() + { + if (!interopDCompDevice) return false; + + BOOL valid{ FALSE }; + THROW_IF_FAILED( + interopDCompDevice.as()->CheckDeviceState( + &valid + ) + ); + + return valid == TRUE; + }; + if (!is_device_valid()) + { + interopDCompDevice.copy_from( + DWM::CDesktopManager::s_pDesktopManagerInstance->GetDCompositionInteropDevice() + ); + ReloadParameters(); + auto compositor{ interopDCompDevice.as() }; + + lightMode_Active_Brush = CreateBrush( + compositor, + lightMode_Active_Color, + lightMode_Active_GlowColor, + lightMode_Active_ColorBalance, + lightMode_Active_GlowBalance, + blurAmount, + Active_BlurBalance, + hostBackdrop + ); + lightMode_Inactive_Brush = CreateBrush( + compositor, + lightMode_Inactive_Color, + lightMode_Inactive_GlowColor, + lightMode_Inactive_ColorBalance, + lightMode_Inactive_GlowBalance, + blurAmount, + Inactive_BlurBalance, + hostBackdrop + ); + darkMode_Active_Brush = CreateBrush( + compositor, + darkMode_Active_Color, + darkMode_Active_GlowColor, + darkMode_Active_ColorBalance, + darkMode_Active_GlowBalance, + blurAmount, + Active_BlurBalance, + hostBackdrop + ); + darkMode_Inactive_Brush = CreateBrush( + compositor, + darkMode_Inactive_Color, + darkMode_Inactive_GlowColor, + darkMode_Inactive_ColorBalance, + darkMode_Inactive_GlowBalance, + blurAmount, + Inactive_BlurBalance, + hostBackdrop + ); + } + + return CDCompResources::GetBrush(useDarkMode, windowActivated); + } + catch (...) { return nullptr; } + }; + + struct CAeroBackdrop : CDCompBackdrop + { + inline static CAeroResources s_sharedResources{}; + + STDMETHOD(UpdateColorizationColor)( + bool useDarkMode, + bool windowActivated + ) override + { + if (useDarkMode) + { + if (windowActivated) { currentColor = s_sharedResources.darkMode_Active_Color; } + else { currentColor = s_sharedResources.darkMode_Inactive_Color; } + } + else + { + if (windowActivated) { currentColor = s_sharedResources.lightMode_Active_Color; } + else { currentColor = s_sharedResources.lightMode_Inactive_Color; } + } + + return S_OK; + } + + HRESULT STDMETHODCALLTYPE Update( + bool useDarkMode, + bool windowActivated + ) override try + { + THROW_IF_FAILED(UpdateColorizationColor(useDarkMode, windowActivated)); + THROW_IF_FAILED( + TryCrossFadeToNewBrush( + spriteVisual.Compositor(), + s_sharedResources.GetBrush(useDarkMode, windowActivated), + s_sharedResources.crossfadeTime + ) + ); + + return S_OK; + } + CATCH_RETURN() + }; + + struct CAccentAeroResources : CDCompResourcesBase + { + + }; + struct CAccentAeroBackdrop : CAccentDCompBackdrop + { + inline static CAccentAeroResources s_sharedResources{}; + winrt::Windows::UI::Color currenGlowColor{}; + + HRESULT STDMETHODCALLTYPE UpdateBrush(const DWM::ACCENT_POLICY& policy) try + { + s_sharedResources.ReloadParameters(); + s_sharedResources.interopDCompDevice.copy_from( + DWM::CDesktopManager::s_pDesktopManagerInstance->GetDCompositionInteropDevice() + ); + auto compositor{ spriteVisual.Compositor() }; + auto glowColor{ FromAbgr(policy.nColor) }; + if ( + currenGlowColor != glowColor || + interopDCompDevice != s_sharedResources.interopDCompDevice + ) + { + interopDCompDevice = s_sharedResources.interopDCompDevice; + currenGlowColor = glowColor; + + spriteVisual.Brush( + CAeroResources::CreateBrush( + compositor, + CAeroBackdrop::s_sharedResources.lightMode_Active_Color, + { 255, currenGlowColor.R, currenGlowColor.G, currenGlowColor.B }, + CAeroBackdrop::s_sharedResources.lightMode_Active_ColorBalance, + CAeroBackdrop::s_sharedResources.lightMode_Active_GlowBalance, + CAeroBackdrop::s_sharedResources.blurAmount, + CAeroBackdrop::s_sharedResources.Active_BlurBalance, + CAeroBackdrop::s_sharedResources.hostBackdrop + ) + ); + } + + return S_OK; + } + CATCH_RETURN() + + HRESULT STDMETHODCALLTYPE Update(const DWM::ACCENT_POLICY& policy) override try + { + THROW_IF_FAILED(UpdateBrush(policy)); - return effectBrush; - } + return S_OK; + } + CATCH_RETURN() + }; } diff --git a/DWMBlurGlassExt/Backdrops/BlurBackdrop.hpp b/DWMBlurGlassExt/Backdrops/BlurBackdrop.hpp index 5569c8d..d8d1b00 100644 --- a/DWMBlurGlassExt/Backdrops/BlurBackdrop.hpp +++ b/DWMBlurGlassExt/Backdrops/BlurBackdrop.hpp @@ -49,8 +49,153 @@ namespace MDWMBlurGlassExt::BlurBackdrop compositeStepEffect->SetDestination(*gaussianBlurEffect); compositeStepEffect->SetSource(*tintOpacityEffect); - auto effectBrush{ compositor.CreateEffectFactory(*compositeStepEffect).CreateBrush() }; - effectBrush.SetSourceParameter(L"Backdrop", compositor.CreateBackdropBrush()); - return effectBrush; - } + blurAmount = g_configData.customBlurAmount; + } + winrt::Windows::UI::Composition::CompositionBrush STDMETHODCALLTYPE GetBrush(bool useDarkMode, bool windowActivated) override try + { + auto is_device_valid = [&]() + { + if (!interopDCompDevice) return false; + + BOOL valid{ FALSE }; + THROW_IF_FAILED( + interopDCompDevice.as()->CheckDeviceState( + &valid + ) + ); + + return valid == TRUE; + }; + if (!is_device_valid()) + { + interopDCompDevice.copy_from( + DWM::CDesktopManager::s_pDesktopManagerInstance->GetDCompositionInteropDevice() + ); + ReloadParameters(); + auto compositor{ interopDCompDevice.as() }; + + lightMode_Active_Brush = CreateBrush( + compositor, + lightMode_Active_Color, + lightMode_Active_TintOpacity, + blurAmount, + hostBackdrop + ); + lightMode_Inactive_Brush = CreateBrush( + compositor, + lightMode_Inactive_Color, + lightMode_Inactive_TintOpacity, + blurAmount, + hostBackdrop + ); + darkMode_Active_Brush = CreateBrush( + compositor, + darkMode_Active_Color, + darkMode_Active_TintOpacity, + blurAmount, + hostBackdrop + ); + darkMode_Inactive_Brush = CreateBrush( + compositor, + darkMode_Inactive_Color, + darkMode_Inactive_TintOpacity, + blurAmount, + hostBackdrop + ); + } + + return CDCompResources::GetBrush(useDarkMode, windowActivated); + } + catch (...) { return nullptr; } + }; + + struct CBlurBackdrop : CDCompBackdrop + { + inline static CBlurResources s_sharedResources{}; + + STDMETHOD(UpdateColorizationColor)( + bool useDarkMode, + bool windowActivated + ) override + { + if (useDarkMode) + { + if (windowActivated) { currentColor = s_sharedResources.darkMode_Active_Color; } + else { currentColor = s_sharedResources.darkMode_Inactive_Color; } + } + else + { + if (windowActivated) { currentColor = s_sharedResources.lightMode_Active_Color; } + else { currentColor = s_sharedResources.lightMode_Inactive_Color; } + } + + return S_OK; + } + HRESULT STDMETHODCALLTYPE Update( + bool useDarkMode, + bool windowActivated + ) try + { + THROW_IF_FAILED(UpdateColorizationColor(useDarkMode, windowActivated)); + THROW_IF_FAILED( + TryCrossFadeToNewBrush( + spriteVisual.Compositor(), + s_sharedResources.GetBrush(useDarkMode, windowActivated), + s_sharedResources.crossfadeTime + ) + ); + + return S_OK; + } + CATCH_RETURN() + }; + + struct CAccentBlurResources : CDCompResourcesBase + { + + }; + struct CAccentBlurBackdrop : CAccentDCompBackdrop + { + inline static CAccentBlurResources s_sharedResources{}; + winrt::Windows::UI::Color currenTintColor{}; + + HRESULT STDMETHODCALLTYPE UpdateBrush(const DWM::ACCENT_POLICY& policy) try + { + s_sharedResources.ReloadParameters(); + s_sharedResources.interopDCompDevice.copy_from( + DWM::CDesktopManager::s_pDesktopManagerInstance->GetDCompositionInteropDevice() + ); + auto compositor{ spriteVisual.Compositor() }; + auto tintColor{ FromAbgr(policy.nColor) }; + if ( + currenTintColor != tintColor || + interopDCompDevice != s_sharedResources.interopDCompDevice + ) + { + interopDCompDevice = s_sharedResources.interopDCompDevice; + currenTintColor = tintColor; + + spriteVisual.Brush( + CBlurResources::CreateBrush( + compositor, + tintColor, + 1.f, + CBlurBackdrop::s_sharedResources.blurAmount, + CBlurBackdrop::s_sharedResources.hostBackdrop + ) + ); + } + + return S_OK; + } + CATCH_RETURN() + + HRESULT STDMETHODCALLTYPE Update(const DWM::ACCENT_POLICY& policy) override try + { + THROW_IF_FAILED(UpdateBrush(policy)); + + return S_OK; + } + CATCH_RETURN() + }; } \ No newline at end of file