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
|
// Copyright 2017 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_SURFACE_WIN_H_
#define UI_GL_DIRECT_COMPOSITION_SURFACE_WIN_H_
#include <windows.h>
#include <d3d11.h>
#include <dcomp.h>
#include <wrl/client.h>
#include "base/containers/circular_deque.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
#include "base/time/time.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "ui/gfx/frame_data.h"
#include "ui/gfx/geometry/transform.h"
#include "ui/gl/child_window_win.h"
#include "ui/gl/gl_export.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/vsync_observer.h"
namespace base {
class SequencedTaskRunner;
} // namespace base
namespace gfx {
namespace mojom {
class DelegatedInkPointRenderer;
} // namespace mojom
class DelegatedInkMetadata;
} // namespace gfx
namespace gl {
class VSyncThreadWin;
class DCLayerTree;
class DirectCompositionChildSurfaceWin;
class GL_EXPORT DirectCompositionSurfaceWin : public GLSurfaceEGL,
public VSyncObserver {
public:
using VSyncCallback =
base::RepeatingCallback<void(base::TimeTicks, base::TimeDelta)>;
using OverlayHDRInfoUpdateCallback = base::RepeatingClosure;
struct Settings {
bool disable_nv12_dynamic_textures = false;
bool disable_vp_auto_hdr = false;
bool disable_vp_scaling = false;
bool disable_vp_super_resolution = false;
bool force_dcomp_triple_buffer_video_swap_chain = false;
size_t max_pending_frames = 2;
bool use_angle_texture_offset = false;
bool no_downscaled_overlay_promotion = false;
};
DirectCompositionSurfaceWin(
GLDisplayEGL* display,
VSyncCallback vsync_callback,
const DirectCompositionSurfaceWin::Settings& settings);
DirectCompositionSurfaceWin(const DirectCompositionSurfaceWin&) = delete;
DirectCompositionSurfaceWin& operator=(const DirectCompositionSurfaceWin&) =
delete;
// GLSurfaceEGL implementation.
bool Initialize(GLSurfaceFormat format) override;
void Destroy() override;
gfx::Size GetSize() override;
bool IsOffscreen() override;
void* GetHandle() override;
bool Resize(const gfx::Size& size,
float scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) override;
gfx::SwapResult SwapBuffers(PresentationCallback callback,
gfx::FrameData data) override;
gfx::SwapResult PostSubBuffer(int x,
int y,
int width,
int height,
PresentationCallback callback,
gfx::FrameData data) override;
gfx::VSyncProvider* GetVSyncProvider() override;
void SetVSyncEnabled(bool enabled) override;
bool SetEnableDCLayers(bool enable) override;
gfx::SurfaceOrigin GetOrigin() const override;
bool SupportsPostSubBuffer() override;
bool OnMakeCurrent(GLContext* context) override;
bool SupportsDCLayers() const override;
bool SupportsProtectedVideo() const override;
bool SetDrawRectangle(const gfx::Rect& rect) override;
gfx::Vector2d GetDrawOffset() const override;
bool SupportsGpuVSync() const override;
void SetGpuVSyncEnabled(bool enabled) override;
// This schedules an overlay plane to be displayed on the next SwapBuffers
// or PostSubBuffer call. Overlay planes must be scheduled before every swap
// to remain in the layer tree. This surface's backbuffer doesn't have to be
// scheduled with ScheduleDCLayer, as it's automatically placed in the layer
// tree at z-order 0.
bool ScheduleDCLayer(std::unique_ptr<DCLayerOverlayParams> params) override;
void SetFrameRate(float frame_rate) override;
// VSyncObserver implementation.
void OnVSync(base::TimeTicks vsync_time, base::TimeDelta interval) override;
bool SupportsDelegatedInk() override;
void SetDelegatedInkTrailStartPoint(
std::unique_ptr<gfx::DelegatedInkMetadata> metadata) override;
void InitDelegatedInkPointRendererReceiver(
mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer>
pending_receiver) override;
HWND window() const { return child_window_.window(); }
scoped_refptr<base::TaskRunner> GetWindowTaskRunnerForTesting();
Microsoft::WRL::ComPtr<IDXGISwapChain1> GetLayerSwapChainForTesting(
size_t index) const;
Microsoft::WRL::ComPtr<IDXGISwapChain1> GetBackbufferSwapChainForTesting()
const;
scoped_refptr<DirectCompositionChildSurfaceWin> GetRootSurfaceForTesting()
const;
void GetSwapChainVisualInfoForTesting(size_t index,
gfx::Transform* transform,
gfx::Point* offset,
gfx::Rect* clip_rect) const;
DCLayerTree* GetLayerTreeForTesting() { return layer_tree_.get(); }
protected:
~DirectCompositionSurfaceWin() override;
private:
struct PendingFrame {
PendingFrame(Microsoft::WRL::ComPtr<ID3D11Query> query,
PresentationCallback callback);
PendingFrame(PendingFrame&& other);
~PendingFrame();
PendingFrame& operator=(PendingFrame&& other);
// Event query issued after frame is presented.
Microsoft::WRL::ComPtr<ID3D11Query> query;
// Presentation callback enqueued in SwapBuffers().
PresentationCallback callback;
};
void EnqueuePendingFrame(PresentationCallback callback, bool create_query);
void CheckPendingFrames();
void StartOrStopVSyncThread();
bool VSyncCallbackEnabled() const;
void HandleVSyncOnMainThread(base::TimeTicks vsync_time,
base::TimeDelta interval);
ChildWindowWin child_window_;
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
const VSyncCallback vsync_callback_;
const raw_ptr<VSyncThreadWin> vsync_thread_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
bool vsync_thread_started_ = false;
bool vsync_callback_enabled_ GUARDED_BY(vsync_callback_enabled_lock_) = false;
mutable base::Lock vsync_callback_enabled_lock_;
// Queue of pending presentation callbacks.
base::circular_deque<PendingFrame> pending_frames_;
const size_t max_pending_frames_;
base::TimeTicks last_vsync_time_;
base::TimeDelta last_vsync_interval_;
scoped_refptr<DirectCompositionChildSurfaceWin> root_surface_;
std::unique_ptr<DCLayerTree> layer_tree_;
base::WeakPtrFactory<DirectCompositionSurfaceWin> weak_factory_{this};
};
} // namespace gl
#endif // UI_GL_DIRECT_COMPOSITION_SURFACE_WIN_H_
|