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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_GL_DIRECT_COMPOSITION_SUPPORT_H_
#define UI_GL_DIRECT_COMPOSITION_SUPPORT_H_
#include <windows.h>
#include <d3d11.h>
#include <dcomp.h>
#include <wrl/client.h>
#include "base/no_destructor.h"
#include "base/observer_list_threadsafe.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/mojom/dxgi_info.mojom.h"
#include "ui/gl/gl_export.h"
#include "ui/gl/gpu_switching_observer.h"
namespace gl {
// Wrapper for DCompositionWaitForCompositorClock Win32 dcomp.h function
HRESULT DCompositionWaitForCompositorClock(UINT count,
const HANDLE* handles,
DWORD timeoutInMs);
// Wrapper for DcompositionGetFrameId Win32 dcomp.h function
HRESULT DCompositionGetFrameId(COMPOSITION_FRAME_ID_TYPE frameIdType,
COMPOSITION_FRAME_ID* frameId);
// Wrapper for DCompositionGetStatistics Win32 dcomp.h function
HRESULT DCompositionGetStatistics(COMPOSITION_FRAME_ID frameId,
COMPOSITION_FRAME_STATS* frameStats,
UINT targetIdCount,
COMPOSITION_TARGET_ID* targetIds,
UINT* actualTargetIdCount);
// Initialize direct composition with the given d3d11 device.
GL_EXPORT void InitializeDirectComposition(
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device);
GL_EXPORT void ShutdownDirectComposition();
// Retrieves the global direct composition device. InitializeDirectComposition
// must be called on GPU process startup before the device is retrieved, and
// ShutdownDirectComposition must be called at process shutdown.
GL_EXPORT IDCompositionDevice3* GetDirectCompositionDevice();
// Retrieves the global d3d11 device used by direct composition.
// InitializeDirectComposition must be called on GPU process startup before the
// device is retrieved, and ShutdownDirectComposition must be called at process
// shutdown.
GL_EXPORT ID3D11Device* GetDirectCompositionD3D11Device();
// Returns true if direct composition is supported. We prefer to use direct
// composition even without hardware overlays, because it allows us to bypass
// blitting by DWM to the window redirection surface by using a flip mode swap
// chain. Overridden with --disable-direct-composition.
GL_EXPORT bool DirectCompositionSupported();
// Returns true if video overlays are supported and should be used. Overridden
// with --enable-direct-composition-video-overlays and
// --disable-direct-composition-video-overlays. This function is thread safe.
GL_EXPORT bool DirectCompositionOverlaysSupported();
// Returns true if hardware overlays are supported. This function is thread
// safe.
GL_EXPORT bool DirectCompositionHardwareOverlaysSupported();
// After this is called, overlay support is disabled during the current GPU
// process' lifetime.
GL_EXPORT void DisableDirectCompositionOverlays();
// Returns true if zero copy decode swap chain is supported.
GL_EXPORT bool DirectCompositionDecodeSwapChainSupported();
// Returns true if scaled hardware overlays are supported.
GL_EXPORT bool DirectCompositionScaledOverlaysSupported();
// Returns preferred overlay format set when detecting overlay support.
GL_EXPORT DXGI_FORMAT GetDirectCompositionSDROverlayFormat();
// Returns true if video processor auto HDR feature is supported.
GL_EXPORT bool VideoProcessorAutoHDRSupported();
// Returns true if video processor support handling the given format.
GL_EXPORT bool CheckVideoProcessorFormatSupport(DXGI_FORMAT format);
// Returns overlay support flags for the given format.
// Caller should check for DXGI_OVERLAY_SUPPORT_FLAG_DIRECT and
// DXGI_OVERLAY_SUPPORT_FLAG_SCALING bits.
// This function is thread safe.
GL_EXPORT UINT GetDirectCompositionOverlaySupportFlags(DXGI_FORMAT format);
// Returns HDR HW capabilities information.
GL_EXPORT void GetDirectCompositionMaxAMDHDRHwOffloadResolution(
bool* amd_hdr_hw_offload_supported,
bool* amd_platform_detected,
int* amd_hdr_hw_offload_max_width,
int* amd_hdr_hw_offload_max_height);
// Returns true if swap chain tearing flag is supported.
GL_EXPORT bool DXGISwapChainTearingSupported();
// Returns true if tearing should be used for dcomp root and video swap chains.
GL_EXPORT bool DirectCompositionSwapChainTearingEnabled();
// Returns true if waitable swap chain should be used to reduce display latency.
GL_EXPORT bool DXGIWaitableSwapChainEnabled();
// Returns the value passed to SetMaximumFrameLatency for waitable swap chains.
GL_EXPORT UINT GetDXGIWaitableSwapChainMaxQueuedFrames();
// Returns true if there is an HDR capable display connected.
GL_EXPORT bool DirectCompositionSystemHDREnabled();
// Returns true if the window is displayed on an HDR capable display.
GL_EXPORT bool DirectCompositionMonitorHDREnabled(HWND window);
// Returns the collected DXGI information.
GL_EXPORT gfx::mojom::DXGIInfoPtr GetDirectCompositionHDRMonitorDXGIInfo();
// Returns true if there is support for |IDCompositionTexture|.
GL_EXPORT bool DirectCompositionTextureSupported();
struct DirectCompositionOverlayWorkarounds {
// Whether software video overlays i.e. swap chains used without hardware
// overlay/MPO support are used or not.
bool disable_sw_video_overlays = false;
// Whether decode swap chains i.e. zero copy swap chains created from video
// decoder textures are used or not.
bool disable_decode_swap_chain = false;
// On Intel GPUs where YUV overlays are supported, BGRA8 overlays are
// supported as well but IDXGIOutput3::CheckOverlaySupport() returns
// unsupported. So allow manually enabling BGRA8 overlay support.
bool enable_bgra8_overlays_with_yuv_overlay_support = false;
// Forces to enable NV12 overlay support regardless of the query results from
// IDXGIOutput3::CheckOverlaySupport().
bool force_nv12_overlay_support = false;
// Forces to enable RGBA101010A2 overlay support regardless of the query
// results from IDXGIOutput3::CheckOverlaySupport().
bool force_rgb10a2_overlay_support = false;
// Enable NV12 overlay support only when
// DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 is supported.
bool check_ycbcr_studio_g22_left_p709_for_nv12_support = false;
// Before 10.0.26100.3624, Windows could return PRESENTATION_ERROR_LOST in
// some cases that are potentially recoverable by destroying all the DComp
// textures associated with our DComp device. However, Viz is not
// well-equipped to do this since most DComp textures are owned by pools in
// the renderer processes. This version and beyond, Windows has a fix to only
// return PRESENTATION_ERROR_LOST in truly unrecoverable cases, which we will
// treat the same as context loss.
bool disable_dcomp_texture = false;
};
GL_EXPORT void SetDirectCompositionOverlayWorkarounds(
const DirectCompositionOverlayWorkarounds& workarounds);
// Returns monitor size.
GL_EXPORT gfx::Size GetDirectCompositionPrimaryMonitorSize();
// Get the current number of all visible display monitors on the desktop.
GL_EXPORT int GetDirectCompositionNumMonitors();
// Testing helpers.
GL_EXPORT void SetDirectCompositionScaledOverlaysSupportedForTesting(
bool value);
GL_EXPORT void SetDirectCompositionOverlayFormatUsedForTesting(
DXGI_FORMAT format);
GL_EXPORT void SetDirectCompositionMonitorInfoForTesting(
int num_monitors,
const gfx::Size& primary_monitor_size);
GL_EXPORT void SetSupportsAMDHwOffloadHDRCapsForTesting(
bool amd_hdr_hw_offload_supported,
bool amd_platform_detected,
INT32 amd_hdr_hw_offload_max_width,
INT32 amd_hdr_hw_offload_max_height);
GL_EXPORT UINT
GetDirectCompositionOverlaySupportFlagsForTesting(DXGI_FORMAT format);
class GL_EXPORT DirectCompositionOverlayCapsObserver
: public base::CheckedObserver {
public:
virtual void OnOverlayCapsChanged() = 0;
protected:
DirectCompositionOverlayCapsObserver() = default;
~DirectCompositionOverlayCapsObserver() override = default;
};
// Upon receiving display notifications from ui::GpuSwitchingManager,
// DirectCompositionOverlayCapsMonitor updates its overlay caps with the new
// display setting and notifies DirectCompositionOverlayCapsObserver for the
// overlay cap change.
class GL_EXPORT DirectCompositionOverlayCapsMonitor
: public ui::GpuSwitchingObserver {
public:
DirectCompositionOverlayCapsMonitor(
const DirectCompositionOverlayCapsMonitor&) = delete;
DirectCompositionOverlayCapsMonitor& operator=(
const DirectCompositionOverlayCapsMonitor&) = delete;
static DirectCompositionOverlayCapsMonitor* GetInstance();
// DirectCompositionOverlayCapsMonitor is running on GpuMain thread.
// AddObserver()/RemoveObserver() are thread safe.
void AddObserver(DirectCompositionOverlayCapsObserver* observer);
void RemoveObserver(DirectCompositionOverlayCapsObserver* observer);
// Called when the overlay caps have changed.
void NotifyOverlayCapsChanged();
// Implements GpuSwitchingObserver.
void OnGpuSwitched(gl::GpuPreference active_gpu_heuristic) override;
void OnDisplayAdded() override;
void OnDisplayRemoved() override;
void OnDisplayMetricsChanged() override;
private:
friend class base::NoDestructor<DirectCompositionOverlayCapsMonitor>;
DirectCompositionOverlayCapsMonitor();
~DirectCompositionOverlayCapsMonitor() override;
scoped_refptr<
base::ObserverListThreadSafe<DirectCompositionOverlayCapsObserver>>
observer_list_;
};
} // namespace gl
#endif // UI_GL_DIRECT_COMPOSITION_SUPPORT_H_
|