direct_composition_child_surface_win.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef UI_GL_DIRECT_COMPOSITION_CHILD_SURFACE_WIN_H_
  5. #define UI_GL_DIRECT_COMPOSITION_CHILD_SURFACE_WIN_H_
  6. #include <windows.h>
  7. #include <d3d11.h>
  8. #include <dcomp.h>
  9. #include <wrl/client.h>
  10. #include "base/callback.h"
  11. #include "base/containers/circular_deque.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/memory/weak_ptr.h"
  14. #include "base/synchronization/lock.h"
  15. #include "base/time/time.h"
  16. #include "ui/gl/gl_export.h"
  17. #include "ui/gl/gl_surface_egl.h"
  18. #include "ui/gl/vsync_observer.h"
  19. namespace base {
  20. class SequencedTaskRunner;
  21. } // namespace base
  22. namespace gl {
  23. class VSyncThreadWin;
  24. class GL_EXPORT DirectCompositionChildSurfaceWin : public GLSurfaceEGL,
  25. public VSyncObserver {
  26. public:
  27. using VSyncCallback =
  28. base::RepeatingCallback<void(base::TimeTicks, base::TimeDelta)>;
  29. DirectCompositionChildSurfaceWin(GLDisplayEGL* display,
  30. VSyncCallback vsync_callback,
  31. bool use_angle_texture_offset,
  32. size_t max_pending_frames,
  33. bool force_full_damage,
  34. bool force_full_damage_always);
  35. DirectCompositionChildSurfaceWin(const DirectCompositionChildSurfaceWin&) =
  36. delete;
  37. DirectCompositionChildSurfaceWin& operator=(
  38. const DirectCompositionChildSurfaceWin&) = delete;
  39. // GLSurfaceEGL implementation.
  40. bool Initialize(GLSurfaceFormat format) override;
  41. void Destroy() override;
  42. gfx::Size GetSize() override;
  43. bool IsOffscreen() override;
  44. void* GetHandle() override;
  45. gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
  46. gfx::SurfaceOrigin GetOrigin() const override;
  47. bool SupportsPostSubBuffer() override;
  48. bool OnMakeCurrent(GLContext* context) override;
  49. bool SupportsDCLayers() const override;
  50. bool SetDrawRectangle(const gfx::Rect& rect) override;
  51. gfx::Vector2d GetDrawOffset() const override;
  52. void SetVSyncEnabled(bool enabled) override;
  53. bool Resize(const gfx::Size& size,
  54. float scale_factor,
  55. const gfx::ColorSpace& color_space,
  56. bool has_alpha) override;
  57. bool SetEnableDCLayers(bool enable) override;
  58. gfx::VSyncProvider* GetVSyncProvider() override;
  59. bool SupportsGpuVSync() const override;
  60. void SetGpuVSyncEnabled(bool enabled) override;
  61. // VSyncObserver implementation.
  62. void OnVSync(base::TimeTicks vsync_time, base::TimeDelta interval) override;
  63. static bool IsDirectCompositionSwapChainFailed();
  64. const Microsoft::WRL::ComPtr<IDCompositionSurface>& dcomp_surface() const {
  65. return dcomp_surface_;
  66. }
  67. const Microsoft::WRL::ComPtr<IDXGISwapChain1>& swap_chain() const {
  68. return swap_chain_;
  69. }
  70. uint64_t dcomp_surface_serial() const { return dcomp_surface_serial_; }
  71. void SetDCompSurfaceForTesting(
  72. Microsoft::WRL::ComPtr<IDCompositionSurface> surface);
  73. protected:
  74. ~DirectCompositionChildSurfaceWin() override;
  75. private:
  76. struct PendingFrame {
  77. PendingFrame(Microsoft::WRL::ComPtr<ID3D11Query> query,
  78. PresentationCallback callback);
  79. PendingFrame(PendingFrame&& other);
  80. ~PendingFrame();
  81. PendingFrame& operator=(PendingFrame&& other);
  82. // Event query issued after frame is presented.
  83. Microsoft::WRL::ComPtr<ID3D11Query> query;
  84. // Presentation callback enqueued in SwapBuffers().
  85. PresentationCallback callback;
  86. };
  87. void EnqueuePendingFrame(PresentationCallback callback);
  88. void CheckPendingFrames();
  89. void StartOrStopVSyncThread();
  90. bool VSyncCallbackEnabled() const;
  91. void HandleVSyncOnMainThread(base::TimeTicks vsync_time,
  92. base::TimeDelta interval);
  93. // Release the texture that's currently being drawn to. If will_discard is
  94. // true then the surface should be discarded without swapping any contents
  95. // to it. Returns false if this fails.
  96. bool ReleaseDrawTexture(bool will_discard);
  97. Microsoft::WRL::ComPtr<ID3D11Texture2D> GetOffscreenTexture();
  98. void CopyOffscreenTextureToDrawTexture();
  99. gfx::Size size_ = gfx::Size(1, 1);
  100. bool enable_dc_layers_ = false;
  101. bool has_alpha_ = true;
  102. bool vsync_enabled_ = true;
  103. gfx::ColorSpace color_space_;
  104. // This is a placeholder surface used when not rendering to the
  105. // DirectComposition surface.
  106. EGLSurface default_surface_ = 0;
  107. // This is the real surface representing the backbuffer. It may be null
  108. // outside of a BeginDraw/EndDraw pair.
  109. EGLSurface real_surface_ = 0;
  110. bool first_swap_ = true;
  111. gfx::Rect swap_rect_;
  112. gfx::Vector2d draw_offset_;
  113. // This is a number that increments once for every EndDraw on a surface, and
  114. // is used to determine when the contents have changed so Commit() needs to
  115. // be called on the device.
  116. uint64_t dcomp_surface_serial_ = 0;
  117. Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
  118. Microsoft::WRL::ComPtr<IDCompositionDevice2> dcomp_device_;
  119. Microsoft::WRL::ComPtr<IDCompositionSurface> dcomp_surface_;
  120. Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain_;
  121. Microsoft::WRL::ComPtr<ID3D11Texture2D> draw_texture_;
  122. POINT dcomp_update_offset_ = {};
  123. // Used only for kDirectCompositionVerifyDrawOffset to
  124. // verify a draw offset bug.
  125. Microsoft::WRL::ComPtr<ID3D11Texture2D> offscreen_texture_;
  126. const VSyncCallback vsync_callback_;
  127. const bool use_angle_texture_offset_;
  128. const size_t max_pending_frames_;
  129. const bool force_full_damage_;
  130. const bool force_full_damage_always_;
  131. const raw_ptr<VSyncThreadWin> vsync_thread_;
  132. scoped_refptr<base::SequencedTaskRunner> task_runner_;
  133. bool vsync_thread_started_ = false;
  134. bool vsync_callback_enabled_ GUARDED_BY(vsync_callback_enabled_lock_) = false;
  135. mutable base::Lock vsync_callback_enabled_lock_;
  136. // Queue of pending presentation callbacks.
  137. base::circular_deque<PendingFrame> pending_frames_;
  138. base::TimeTicks last_vsync_time_;
  139. base::TimeDelta last_vsync_interval_;
  140. base::WeakPtrFactory<DirectCompositionChildSurfaceWin> weak_factory_{this};
  141. };
  142. } // namespace gl
  143. #endif // UI_GL_DIRECT_COMPOSITION_CHILD_SURFACE_WIN_H_