未验证 提交 16f75cd6 编写于 作者: A Ashish Kumar Singh 提交者: GitHub

Port dirty-rectangle opt-out from 4.8 (#5837) (#6062)

* disable d3d dirty rectangle optimization

* fix build break - 'processed' file needs to be copied from .NETFx, where it is generated during the build
Co-authored-by: NSam Bent <sambent@microsoft.com>
上级 81508c8c
......@@ -2253,6 +2253,11 @@ Channel channel
}
}
if (CoreAppContextSwitches.DisableDirtyRectangles)
{
command.flags |= (UInt32)MILRTInitializationFlags.MIL_RT_DISABLE_DIRTY_RECTANGLES;
}
command.hBitmap = DUCE.ResourceHandle.Null;
command.stride = 0;
command.ePixelFormat = 0;
......
......@@ -170,6 +170,12 @@ internal enum MILRTInitializationFlags
//
MIL_RT_IS_DISABLE_MULTIMON_DISPLAY_CLIPPING_VALID = 0x00008000,
//
// This flag directs the render target to render the full scene,
// bypassing D3D's dirty-rectangle optimizations.
//
MIL_RT_DISABLE_DIRTY_RECTANGLES = 0x00010000,
//
// UCE only flags
//
......
......@@ -337,6 +337,49 @@ public static bool AllowExternalProcessToBlockAccessToTemporaryFiles
#endregion
#region DisableDirtyRectangles
internal const string DisableDirtyRectanglesSwitchName = "Switch.System.Windows.Media.MediaContext.DisableDirtyRectangles";
private static int _DisableDirtyRectangles;
public static bool DisableDirtyRectangles
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
/// <summary>
/// Due to a limitation of D3D's implementation of
/// dirty-rectangle processing, images occasionally render incorrectly.
/// An app can disable dirty-rectangle processing by setting this switch to true.
/// This will cause more work for the GPU, but the results will be better.
/// </summary>
if (EnableDynamicDirtyRectangles)
{
bool disableDirtyRectangles;
AppContext.TryGetSwitch(DisableDirtyRectanglesSwitchName, out disableDirtyRectangles);
return disableDirtyRectangles;
}
return LocalAppContext.GetCachedSwitchValue(DisableDirtyRectanglesSwitchName, ref _DisableDirtyRectangles);
}
}
internal const string EnableDynamicDirtyRectanglesSwitchName = "Switch.System.Windows.Media.MediaContext.EnableDynamicDirtyRectangles";
private static int _EnableDynamicDirtyRectangles;
public static bool EnableDynamicDirtyRectangles
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
/// <summary>
/// Setting this switch to true causes the DisableDirtyRectangles
/// switch to be re-evaluated before each render.
/// </summary>
return LocalAppContext.GetCachedSwitchValue(EnableDynamicDirtyRectanglesSwitchName, ref _EnableDynamicDirtyRectangles);
}
}
#endregion
}
#pragma warning restore 436
}
......@@ -48,6 +48,7 @@ internal enum RenderingMode
HardwareReference = MILRTInitializationFlags.MIL_RT_HARDWARE_ONLY | MILRTInitializationFlags.MIL_RT_USE_REF_RAST,
DisableMultimonDisplayClipping = MILRTInitializationFlags.MIL_RT_DISABLE_MULTIMON_DISPLAY_CLIPPING,
IsDisableMultimonDisplayClippingValid = MILRTInitializationFlags.MIL_RT_IS_DISABLE_MULTIMON_DISPLAY_CLIPPING_VALID,
DisableDirtyRectangles = MILRTInitializationFlags.MIL_RT_DISABLE_DIRTY_RECTANGLES,
}
// This is the public, more limited, enum exposed for use with the RenderMode property.
......@@ -621,6 +622,11 @@ internal void InvalidateRenderMode()
}
}
if (MediaSystem.DisableDirtyRectangles)
{
mode |= RenderingMode.DisableDirtyRectangles;
}
// Select the render target initialization flags based on the requested
// rendering mode.
......
......@@ -1860,6 +1860,8 @@ private object InputMarkerMessageHandler(object arg)
_timeManager.UnlockTickTime();
MediaSystem.PropagateDirtyRectangleSettings();
// Invalidate the input devices on the InputManager
InputManager.UnsecureCurrent.InvalidateInputDevices();
......
......@@ -149,6 +149,28 @@ internal static void Shutdown(MediaContext mc)
}
}
/// <summary>
/// If the app has asked to disable dirty-rect processing, notify the graphics engine
/// </summary>
internal static void PropagateDirtyRectangleSettings()
{
int oldValue = s_DisableDirtyRectangles;
int disableDirtyRectangles = CoreAppContextSwitches.DisableDirtyRectangles ? 1 : 0;
if (disableDirtyRectangles != oldValue)
{
if (System.Threading.Interlocked.CompareExchange(ref s_DisableDirtyRectangles, disableDirtyRectangles, oldValue) == oldValue)
{
NotifyRedirectionEnvironmentChanged();
}
}
}
internal static bool DisableDirtyRectangles
{
get { return (s_DisableDirtyRectangles != 0); }
}
/// <summary>
/// Handle DWM messages that indicate that the state of the connection needs to change.
/// </summary>
......@@ -342,6 +364,10 @@ internal static bool AnimationSmoothing
/// we drop back to sw rendering to enable the Vista magnifier.
/// </summary>
private static bool s_forceSoftareForGraphicsStreamMagnifier;
// 1 if app is requesting to disable D3D dirty rectangle work, 0 otherwise.
// We use Interlocked.CompareExchange to change this, which supports int but not bool.
private static int s_DisableDirtyRectangles = 0;
}
}
......@@ -654,6 +654,10 @@
that the user set it to false explicitly, versus when the user didn't set it
and the DisableMultimonDisplayClipping bit happens to be implicitly set to 0" />
<Field Name="DisableDirtyRectangles" Value="0x00010000"
Comment ="This flag directs the render target to render the full scene,
bypassing D3D's dirty-rectangle optimizations." />
<BlockCommentedFields Comment="Test only / internal flags">
<Field Name="UseRefRast" Value="0x01000000"
Comment="This flag forces the render target to use the d3d9 reference raster
......
......@@ -70,6 +70,7 @@ HRESULT HrValidateInitializeCall(
MilRTInitialization::DisableDisplayClipping |
MilRTInitialization::DisableMultimonDisplayClipping |
MilRTInitialization::IsDisableMultimonDisplayClippingValid |
MilRTInitialization::DisableDirtyRectangles |
MilRTInitialization::UseRefRast |
MilRTInitialization::UseRgbRast |
MilRTInitialization::PresentUsingMask
......
......@@ -164,6 +164,8 @@ CHwDisplayRenderTarget::Init(
dwFlags
);
m_fDisableDirtyRectangles = (dwFlags & MilRTInitialization::DisableDirtyRectangles) != 0;
#if DBG_STEP_RENDERING
m_fDbgClearOnPresent = !(dwFlags & MilRTInitialization::PresentRetainContents);
#endif DBG_STEP_RENDERING
......@@ -378,6 +380,12 @@ CHwDisplayRenderTarget::Present(
goto Cleanup;
}
if (m_fDisableDirtyRectangles)
{
// invalidating the empty rect tells ShouldPresent to present everything
InvalidateRect(reinterpret_cast<const CMILSurfaceRect *>(&CMILSurfaceRect::sc_rcEmpty));
}
bool fPresent = false;
RGNDATA *pDirtyRegion = NULL;
IFC(ShouldPresent(
......
......@@ -186,6 +186,7 @@ protected:
protected:
BOOL m_fEnableRendering; // Rendering is disabled during resize
BOOL m_fDisableDirtyRectangles; // app wants to skip D3D dirty-rect optimization
CD3DSwapChain *m_pD3DSwapChain;
D3DPRESENT_PARAMETERS m_D3DPresentParams;
UINT const m_AdapterOrdinalInGroup;
......
......@@ -219,6 +219,7 @@ private:
HWND m_hwnd;
CSwPresenter32bppGDI *m_pPresenter;
BOOL m_fDisableDirtyRectangles; // app wants to skip dirty-rect optimization
};
......
......@@ -336,6 +336,7 @@ HRESULT CSwRenderTargetHWND::Init(
);
m_hwnd = hwnd;
m_fDisableDirtyRectangles = (nFlags & MilRTInitialization::DisableDirtyRectangles) != 0;
#if DBG_STEP_RENDERING
m_fDbgClearOnPresent = !(nFlags & MilRTInitialization::PresentRetainContents);
......@@ -371,6 +372,12 @@ STDMETHODIMP CSwRenderTargetHWND::Present(
RGNDATA *pDirtyRegion = NULL;
if (m_fDisableDirtyRectangles)
{
// invalidating the empty rect tells ShouldPresent to present everything
InvalidateRect(reinterpret_cast<const CMILSurfaceRect *>(&CMILSurfaceRect::sc_rcEmpty));
}
IFC(ShouldPresent(
pRect,
&presentRect,
......
......@@ -694,7 +694,7 @@ CSlaveHWndRenderTarget::ProcessSetFlags(
HRESULT hr = S_OK;
const MilRTInitialization::Flags c_dwAllowedFlags =
(MilRTInitialization::TypeMask | MilRTInitialization::UseRefRast | MilRTInitialization::UseRgbRast);
(MilRTInitialization::TypeMask | MilRTInitialization::UseRefRast | MilRTInitialization::UseRgbRast | MilRTInitialization::DisableDirtyRectangles);
MilRTInitialization::Flags dwNewInitializationFlags;
......
......@@ -771,6 +771,12 @@ BEGIN_MILFLAGENUM( MilRTInitialization )
//
IsDisableMultimonDisplayClippingValid = 0x00008000,
//
// This flag directs the render target to render the full scene,
// bypassing D3D's dirty-rectangle optimizations.
//
DisableDirtyRectangles = 0x00010000,
//
// Test only / internal flags
......
......@@ -2548,6 +2548,11 @@ Channel channel
}
}
if (CoreAppContextSwitches.DisableDirtyRectangles)
{
command.flags |= (UInt32)MILRTInitializationFlags.MIL_RT_DISABLE_DIRTY_RECTANGLES;
}
command.hBitmap = DUCE.ResourceHandle.Null;
command.stride = 0;
command.ePixelFormat = 0;
......
......@@ -858,6 +858,12 @@ BEGIN_MILFLAGENUM( MilRTInitialization )
//
IsDisableMultimonDisplayClippingValid = 0x00008000,
//
// This flag directs the render target to render the full scene,
// bypassing D3D's dirty-rectangle optimizations.
//
DisableDirtyRectangles = 0x00010000,
//
// Test only / internal flags
......
......@@ -180,6 +180,12 @@ internal enum MILRTInitializationFlags
//
MIL_RT_IS_DISABLE_MULTIMON_DISPLAY_CLIPPING_VALID = 0x00008000,
//
// This flag directs the render target to render the full scene,
// bypassing D3D's dirty-rectangle optimizations.
//
MIL_RT_DISABLE_DIRTY_RECTANGLES = 0x00010000,
//
// UCE only flags
//
......@@ -276,4 +282,3 @@ internal enum MILWindowLayerType
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册