direct_composition_surface_win.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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. #include "ui/gl/direct_composition_surface_win.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/trace_event/trace_event.h"
  9. #include "ui/gl/dc_layer_tree.h"
  10. #include "ui/gl/direct_composition_child_surface_win.h"
  11. #include "ui/gl/direct_composition_support.h"
  12. namespace gl {
  13. DirectCompositionSurfaceWin::DirectCompositionSurfaceWin(
  14. GLDisplayEGL* display,
  15. HWND parent_window,
  16. VSyncCallback vsync_callback,
  17. const Settings& settings)
  18. : GLSurfaceEGL(display),
  19. child_window_(parent_window),
  20. root_surface_(new DirectCompositionChildSurfaceWin(
  21. display,
  22. std::move(vsync_callback),
  23. settings.use_angle_texture_offset,
  24. settings.max_pending_frames,
  25. settings.force_root_surface_full_damage,
  26. settings.force_root_surface_full_damage_always)),
  27. layer_tree_(std::make_unique<DCLayerTree>(
  28. settings.disable_nv12_dynamic_textures,
  29. settings.disable_vp_scaling,
  30. settings.disable_vp_super_resolution,
  31. settings.no_downscaled_overlay_promotion)) {}
  32. DirectCompositionSurfaceWin::~DirectCompositionSurfaceWin() {
  33. Destroy();
  34. }
  35. bool DirectCompositionSurfaceWin::Initialize(GLSurfaceFormat format) {
  36. if (!DirectCompositionSupported()) {
  37. DLOG(ERROR) << "Direct composition not supported";
  38. return false;
  39. }
  40. child_window_.Initialize();
  41. window_ = child_window_.window();
  42. if (!layer_tree_->Initialize(window_))
  43. return false;
  44. if (!root_surface_->Initialize(GLSurfaceFormat()))
  45. return false;
  46. return true;
  47. }
  48. void DirectCompositionSurfaceWin::Destroy() {
  49. root_surface_->Destroy();
  50. // Freeing DComp resources such as visuals and surfaces causes the
  51. // device to become 'dirty'. We must commit the changes to the device
  52. // in order for the objects to actually be destroyed.
  53. // Leaving the device in the dirty state for long periods of time means
  54. // that if DWM.exe crashes, the Chromium window will become black until
  55. // the next Commit.
  56. layer_tree_.reset();
  57. if (auto* dcomp_device = GetDirectCompositionDevice())
  58. dcomp_device->Commit();
  59. }
  60. gfx::Size DirectCompositionSurfaceWin::GetSize() {
  61. return root_surface_->GetSize();
  62. }
  63. bool DirectCompositionSurfaceWin::IsOffscreen() {
  64. return false;
  65. }
  66. void* DirectCompositionSurfaceWin::GetHandle() {
  67. return root_surface_->GetHandle();
  68. }
  69. bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size,
  70. float scale_factor,
  71. const gfx::ColorSpace& color_space,
  72. bool has_alpha) {
  73. // Force a resize and redraw (but not a move, activate, etc.).
  74. if (!SetWindowPos(window_, nullptr, 0, 0, size.width(), size.height(),
  75. SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS |
  76. SWP_NOOWNERZORDER | SWP_NOZORDER)) {
  77. return false;
  78. }
  79. return root_surface_->Resize(size, scale_factor, color_space, has_alpha);
  80. }
  81. gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers(
  82. PresentationCallback callback) {
  83. TRACE_EVENT0("gpu", "DirectCompositionSurfaceWin::SwapBuffers");
  84. if (root_surface_->SwapBuffers(std::move(callback)) !=
  85. gfx::SwapResult::SWAP_ACK)
  86. return gfx::SwapResult::SWAP_FAILED;
  87. if (!layer_tree_->CommitAndClearPendingOverlays(root_surface_.get()))
  88. return gfx::SwapResult::SWAP_FAILED;
  89. return gfx::SwapResult::SWAP_ACK;
  90. }
  91. gfx::SwapResult DirectCompositionSurfaceWin::PostSubBuffer(
  92. int x,
  93. int y,
  94. int width,
  95. int height,
  96. PresentationCallback callback) {
  97. // The arguments are ignored because SetDrawRectangle specified the area to
  98. // be swapped.
  99. return SwapBuffers(std::move(callback));
  100. }
  101. gfx::VSyncProvider* DirectCompositionSurfaceWin::GetVSyncProvider() {
  102. return root_surface_->GetVSyncProvider();
  103. }
  104. void DirectCompositionSurfaceWin::SetVSyncEnabled(bool enabled) {
  105. root_surface_->SetVSyncEnabled(enabled);
  106. }
  107. bool DirectCompositionSurfaceWin::ScheduleDCLayer(
  108. std::unique_ptr<ui::DCRendererLayerParams> params) {
  109. return layer_tree_->ScheduleDCLayer(std::move(params));
  110. }
  111. void DirectCompositionSurfaceWin::SetFrameRate(float frame_rate) {
  112. // Only try to reduce vsync frequency through the video swap chain.
  113. // This allows us to experiment UseSetPresentDuration optimization to
  114. // fullscreen video overlays only and avoid compromising
  115. // UsePreferredIntervalForVideo optimization where we skip compositing
  116. // every other frame when fps <= half the vsync frame rate.
  117. layer_tree_->SetFrameRate(frame_rate);
  118. }
  119. bool DirectCompositionSurfaceWin::SetEnableDCLayers(bool enable) {
  120. return root_surface_->SetEnableDCLayers(enable);
  121. }
  122. gfx::SurfaceOrigin DirectCompositionSurfaceWin::GetOrigin() const {
  123. return gfx::SurfaceOrigin::kTopLeft;
  124. }
  125. bool DirectCompositionSurfaceWin::SupportsPostSubBuffer() {
  126. return true;
  127. }
  128. bool DirectCompositionSurfaceWin::OnMakeCurrent(GLContext* context) {
  129. return root_surface_->OnMakeCurrent(context);
  130. }
  131. bool DirectCompositionSurfaceWin::SupportsDCLayers() const {
  132. return true;
  133. }
  134. bool DirectCompositionSurfaceWin::SupportsProtectedVideo() const {
  135. // TODO(magchen): Check the gpu driver date (or a function) which we know this
  136. // new support is enabled.
  137. return DirectCompositionOverlaysSupported();
  138. }
  139. bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rect) {
  140. return root_surface_->SetDrawRectangle(rect);
  141. }
  142. gfx::Vector2d DirectCompositionSurfaceWin::GetDrawOffset() const {
  143. return root_surface_->GetDrawOffset();
  144. }
  145. bool DirectCompositionSurfaceWin::SupportsGpuVSync() const {
  146. return true;
  147. }
  148. void DirectCompositionSurfaceWin::SetGpuVSyncEnabled(bool enabled) {
  149. root_surface_->SetGpuVSyncEnabled(enabled);
  150. }
  151. bool DirectCompositionSurfaceWin::SupportsDelegatedInk() {
  152. return layer_tree_->SupportsDelegatedInk();
  153. }
  154. void DirectCompositionSurfaceWin::SetDelegatedInkTrailStartPoint(
  155. std::unique_ptr<gfx::DelegatedInkMetadata> metadata) {
  156. layer_tree_->SetDelegatedInkTrailStartPoint(std::move(metadata));
  157. }
  158. void DirectCompositionSurfaceWin::InitDelegatedInkPointRendererReceiver(
  159. mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer>
  160. pending_receiver) {
  161. layer_tree_->InitDelegatedInkPointRendererReceiver(
  162. std::move(pending_receiver));
  163. }
  164. scoped_refptr<base::TaskRunner>
  165. DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() {
  166. return child_window_.GetTaskRunnerForTesting();
  167. }
  168. Microsoft::WRL::ComPtr<IDXGISwapChain1>
  169. DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const {
  170. return layer_tree_->GetLayerSwapChainForTesting(index);
  171. }
  172. Microsoft::WRL::ComPtr<IDXGISwapChain1>
  173. DirectCompositionSurfaceWin::GetBackbufferSwapChainForTesting() const {
  174. return root_surface_->swap_chain();
  175. }
  176. scoped_refptr<DirectCompositionChildSurfaceWin>
  177. DirectCompositionSurfaceWin::GetRootSurfaceForTesting() const {
  178. return root_surface_;
  179. }
  180. void DirectCompositionSurfaceWin::GetSwapChainVisualInfoForTesting(
  181. size_t index,
  182. gfx::Transform* transform,
  183. gfx::Point* offset,
  184. gfx::Rect* clip_rect) const {
  185. layer_tree_->GetSwapChainVisualInfoForTesting( // IN-TEST
  186. index, transform, offset, clip_rect);
  187. }
  188. } // namespace gl