| OLD | NEW | 
|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "gpu/ipc/service/direct_composition_surface_win.h" | 5 #include "gpu/ipc/service/direct_composition_surface_win.h" | 
| 6 | 6 | 
| 7 #include <d3d11_1.h> | 7 #include <d3d11_1.h> | 
| 8 #include <dcomptypes.h> | 8 #include <dcomptypes.h> | 
| 9 | 9 | 
| 10 #include <deque> | 10 #include <deque> | 
| 11 | 11 | 
| 12 #include "base/feature_list.h" | 12 #include "base/feature_list.h" | 
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" | 
| 14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" | 
| 15 #include "base/optional.h" |  | 
| 16 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" | 
| 17 #include "base/trace_event/trace_event.h" | 16 #include "base/trace_event/trace_event.h" | 
| 18 #include "base/win/scoped_handle.h" | 17 #include "base/win/scoped_handle.h" | 
| 19 #include "base/win/windows_version.h" | 18 #include "base/win/windows_version.h" | 
| 20 #include "gpu/command_buffer/service/feature_info.h" | 19 #include "gpu/command_buffer/service/feature_info.h" | 
|  | 20 #include "gpu/ipc/service/direct_composition_child_surface_win.h" | 
| 21 #include "gpu/ipc/service/gpu_channel_manager.h" | 21 #include "gpu/ipc/service/gpu_channel_manager.h" | 
| 22 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" | 22 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" | 
| 23 #include "gpu/ipc/service/switches.h" | 23 #include "gpu/ipc/service/switches.h" | 
| 24 #include "ui/display/display_switches.h" | 24 #include "ui/display/display_switches.h" | 
| 25 #include "ui/gfx/color_space_win.h" | 25 #include "ui/gfx/color_space_win.h" | 
| 26 #include "ui/gfx/geometry/size_conversions.h" | 26 #include "ui/gfx/geometry/size_conversions.h" | 
| 27 #include "ui/gfx/native_widget_types.h" | 27 #include "ui/gfx/native_widget_types.h" | 
| 28 #include "ui/gfx/transform.h" | 28 #include "ui/gfx/transform.h" | 
| 29 #include "ui/gl/dc_renderer_layer_params.h" | 29 #include "ui/gl/dc_renderer_layer_params.h" | 
| 30 #include "ui/gl/egl_util.h" | 30 #include "ui/gl/egl_util.h" | 
| 31 #include "ui/gl/gl_angle_util_win.h" | 31 #include "ui/gl/gl_angle_util_win.h" | 
| 32 #include "ui/gl/gl_context.h" | 32 #include "ui/gl/gl_context.h" | 
| 33 #include "ui/gl/gl_image_dxgi.h" | 33 #include "ui/gl/gl_image_dxgi.h" | 
| 34 #include "ui/gl/gl_image_memory.h" | 34 #include "ui/gl/gl_image_memory.h" | 
| 35 #include "ui/gl/gl_surface_egl.h" | 35 #include "ui/gl/gl_surface_egl.h" | 
| 36 #include "ui/gl/scoped_make_current.h" | 36 #include "ui/gl/scoped_make_current.h" | 
| 37 | 37 | 
| 38 #ifndef EGL_ANGLE_flexible_surface_compatibility | 38 #ifndef EGL_ANGLE_flexible_surface_compatibility | 
| 39 #define EGL_ANGLE_flexible_surface_compatibility 1 | 39 #define EGL_ANGLE_flexible_surface_compatibility 1 | 
| 40 #define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6 | 40 #define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6 | 
| 41 #endif /* EGL_ANGLE_flexible_surface_compatibility */ | 41 #endif /* EGL_ANGLE_flexible_surface_compatibility */ | 
| 42 | 42 | 
| 43 #ifndef EGL_ANGLE_d3d_texture_client_buffer |  | 
| 44 #define EGL_ANGLE_d3d_texture_client_buffer 1 |  | 
| 45 #define EGL_D3D_TEXTURE_ANGLE 0x33A3 |  | 
| 46 #endif /* EGL_ANGLE_d3d_texture_client_buffer */ |  | 
| 47 |  | 
| 48 namespace gpu { | 43 namespace gpu { | 
| 49 namespace { | 44 namespace { | 
| 50 | 45 | 
| 51 // Some drivers fail to correctly handle BT.709 video in overlays. This flag | 46 // Some drivers fail to correctly handle BT.709 video in overlays. This flag | 
| 52 // converts them to BT.601 in the video processor. | 47 // converts them to BT.601 in the video processor. | 
| 53 const base::Feature kFallbackBT709VideoToBT601{ | 48 const base::Feature kFallbackBT709VideoToBT601{ | 
| 54     "FallbackBT709VideoToBT601", base::FEATURE_DISABLED_BY_DEFAULT}; | 49     "FallbackBT709VideoToBT601", base::FEATURE_DISABLED_BY_DEFAULT}; | 
| 55 | 50 | 
| 56 // This class is used to make sure a specified surface isn't current, and upon |  | 
| 57 // destruction it will make the surface current again if it had been before. |  | 
| 58 class ScopedReleaseCurrent { |  | 
| 59  public: |  | 
| 60   explicit ScopedReleaseCurrent(gl::GLSurface* this_surface) { |  | 
| 61     gl::GLContext* current_context = gl::GLContext::GetCurrent(); |  | 
| 62     bool was_current = |  | 
| 63         current_context && current_context->IsCurrent(this_surface); |  | 
| 64     if (was_current) { |  | 
| 65       make_current_.emplace(current_context, this_surface); |  | 
| 66       current_context->ReleaseCurrent(this_surface); |  | 
| 67     } |  | 
| 68   } |  | 
| 69 |  | 
| 70  private: |  | 
| 71   base::Optional<ui::ScopedMakeCurrent> make_current_; |  | 
| 72 }; |  | 
| 73 |  | 
| 74 bool SizeContains(const gfx::Size& a, const gfx::Size& b) { | 51 bool SizeContains(const gfx::Size& a, const gfx::Size& b) { | 
| 75   return gfx::Rect(a).Contains(gfx::Rect(b)); | 52   return gfx::Rect(a).Contains(gfx::Rect(b)); | 
| 76 } | 53 } | 
| 77 | 54 | 
| 78 // This keeps track of whether the previous 30 frames used Overlays or GPU | 55 // This keeps track of whether the previous 30 frames used Overlays or GPU | 
| 79 // composition to present. | 56 // composition to present. | 
| 80 class PresentationHistory { | 57 class PresentationHistory { | 
| 81  public: | 58  public: | 
| 82   static const int kPresentsToStore = 30; | 59   static const int kPresentsToStore = 30; | 
| 83 | 60 | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 168       g_overlay_monitor_size = | 145       g_overlay_monitor_size = | 
| 169           gfx::Rect(monitor_desc.DesktopCoordinates).size(); | 146           gfx::Rect(monitor_desc.DesktopCoordinates).size(); | 
| 170       g_supports_scaled_overlays = | 147       g_supports_scaled_overlays = | 
| 171           !!(flags & DXGI_OVERLAY_SUPPORT_FLAG_SCALING); | 148           !!(flags & DXGI_OVERLAY_SUPPORT_FLAG_SCALING); | 
| 172       return true; | 149       return true; | 
| 173     } | 150     } | 
| 174   } | 151   } | 
| 175   return false; | 152   return false; | 
| 176 } | 153 } | 
| 177 | 154 | 
| 178 // Only one DirectComposition surface can be rendered into at a time. Track |  | 
| 179 // here which IDCompositionSurface is being rendered into. If another context |  | 
| 180 // is made current, then this surface will be suspended. |  | 
| 181 IDCompositionSurface* g_current_surface; |  | 
| 182 |  | 
| 183 }  // namespace | 155 }  // namespace | 
| 184 | 156 | 
| 185 class DCLayerTree { | 157 class DCLayerTree { | 
| 186  public: | 158  public: | 
| 187   DCLayerTree(DirectCompositionSurfaceWin* surface, | 159   DCLayerTree(DirectCompositionSurfaceWin* surface, | 
| 188               const base::win::ScopedComPtr<ID3D11Device>& d3d11_device, | 160               const base::win::ScopedComPtr<ID3D11Device>& d3d11_device, | 
| 189               const base::win::ScopedComPtr<IDCompositionDevice2>& dcomp_device) | 161               const base::win::ScopedComPtr<IDCompositionDevice2>& dcomp_device) | 
| 190       : surface_(surface), | 162       : surface_(surface), | 
| 191         d3d11_device_(d3d11_device), | 163         d3d11_device_(d3d11_device), | 
| 192         dcomp_device_(dcomp_device) {} | 164         dcomp_device_(dcomp_device) {} | 
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1051   pbuffer_attribs.push_back(EGL_WIDTH); | 1023   pbuffer_attribs.push_back(EGL_WIDTH); | 
| 1052   pbuffer_attribs.push_back(1); | 1024   pbuffer_attribs.push_back(1); | 
| 1053   pbuffer_attribs.push_back(EGL_HEIGHT); | 1025   pbuffer_attribs.push_back(EGL_HEIGHT); | 
| 1054   pbuffer_attribs.push_back(1); | 1026   pbuffer_attribs.push_back(1); | 
| 1055 | 1027 | 
| 1056   pbuffer_attribs.push_back(EGL_NONE); | 1028   pbuffer_attribs.push_back(EGL_NONE); | 
| 1057   default_surface_ = | 1029   default_surface_ = | 
| 1058       eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]); | 1030       eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]); | 
| 1059   CHECK(!!default_surface_); | 1031   CHECK(!!default_surface_); | 
| 1060 | 1032 | 
| 1061   return true; | 1033   return RecreateRootSurface(); | 
| 1062 } |  | 
| 1063 |  | 
| 1064 void DirectCompositionSurfaceWin::ReleaseCurrentSurface() { |  | 
| 1065   ReleaseDrawTexture(true); |  | 
| 1066   dcomp_surface_.Reset(); |  | 
| 1067   swap_chain_.Reset(); |  | 
| 1068 } |  | 
| 1069 |  | 
| 1070 void DirectCompositionSurfaceWin::InitializeSurface() { |  | 
| 1071   TRACE_EVENT1("gpu", "DirectCompositionSurfaceWin::InitializeSurface()", |  | 
| 1072                "enable_dc_layers_", enable_dc_layers_); |  | 
| 1073   DCHECK(!dcomp_surface_); |  | 
| 1074   DCHECK(!swap_chain_); |  | 
| 1075   DXGI_FORMAT output_format = |  | 
| 1076       base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableHDR) |  | 
| 1077           ? DXGI_FORMAT_R16G16B16A16_FLOAT |  | 
| 1078           : DXGI_FORMAT_B8G8R8A8_UNORM; |  | 
| 1079   if (enable_dc_layers_) { |  | 
| 1080     // Always treat as premultiplied, because an underlay could cause it to |  | 
| 1081     // become transparent. |  | 
| 1082     HRESULT hr = dcomp_device_->CreateSurface( |  | 
| 1083         size_.width(), size_.height(), output_format, |  | 
| 1084         DXGI_ALPHA_MODE_PREMULTIPLIED, dcomp_surface_.GetAddressOf()); |  | 
| 1085     has_been_rendered_to_ = false; |  | 
| 1086     CHECK(SUCCEEDED(hr)); |  | 
| 1087   } else { |  | 
| 1088     DXGI_ALPHA_MODE alpha_mode = |  | 
| 1089         has_alpha_ ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE; |  | 
| 1090     base::win::ScopedComPtr<IDXGIDevice> dxgi_device; |  | 
| 1091     d3d11_device_.CopyTo(dxgi_device.GetAddressOf()); |  | 
| 1092     base::win::ScopedComPtr<IDXGIAdapter> dxgi_adapter; |  | 
| 1093     dxgi_device->GetAdapter(dxgi_adapter.GetAddressOf()); |  | 
| 1094     base::win::ScopedComPtr<IDXGIFactory2> dxgi_factory; |  | 
| 1095     dxgi_adapter->GetParent(IID_PPV_ARGS(dxgi_factory.GetAddressOf())); |  | 
| 1096 |  | 
| 1097     DXGI_SWAP_CHAIN_DESC1 desc = {}; |  | 
| 1098     desc.Width = size_.width(); |  | 
| 1099     desc.Height = size_.height(); |  | 
| 1100     desc.Format = output_format; |  | 
| 1101     desc.Stereo = FALSE; |  | 
| 1102     desc.SampleDesc.Count = 1; |  | 
| 1103     desc.BufferCount = 2; |  | 
| 1104     desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; |  | 
| 1105     desc.Scaling = DXGI_SCALING_STRETCH; |  | 
| 1106     desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; |  | 
| 1107     desc.AlphaMode = alpha_mode; |  | 
| 1108     desc.Flags = 0; |  | 
| 1109     HRESULT hr = dxgi_factory->CreateSwapChainForComposition( |  | 
| 1110         d3d11_device_.Get(), &desc, nullptr, swap_chain_.GetAddressOf()); |  | 
| 1111     has_been_rendered_to_ = false; |  | 
| 1112     first_swap_ = true; |  | 
| 1113     CHECK(SUCCEEDED(hr)); |  | 
| 1114   } |  | 
| 1115 } |  | 
| 1116 |  | 
| 1117 void DirectCompositionSurfaceWin::ReleaseDrawTexture(bool will_discard) { |  | 
| 1118   if (real_surface_) { |  | 
| 1119     eglDestroySurface(GetDisplay(), real_surface_); |  | 
| 1120     real_surface_ = nullptr; |  | 
| 1121   } |  | 
| 1122   if (draw_texture_) { |  | 
| 1123     draw_texture_.Reset(); |  | 
| 1124     if (dcomp_surface_) { |  | 
| 1125       HRESULT hr = dcomp_surface_->EndDraw(); |  | 
| 1126       CHECK(SUCCEEDED(hr)); |  | 
| 1127     } else if (!will_discard) { |  | 
| 1128       DXGI_PRESENT_PARAMETERS params = {}; |  | 
| 1129       RECT dirty_rect = swap_rect_.ToRECT(); |  | 
| 1130       params.DirtyRectsCount = 1; |  | 
| 1131       params.pDirtyRects = &dirty_rect; |  | 
| 1132       swap_chain_->Present1(first_swap_ ? 0 : 1, 0, ¶ms); |  | 
| 1133       if (first_swap_) { |  | 
| 1134         // Wait for the GPU to finish executing its commands before |  | 
| 1135         // committing the DirectComposition tree, or else the swapchain |  | 
| 1136         // may flicker black when it's first presented. |  | 
| 1137         base::win::ScopedComPtr<IDXGIDevice2> dxgi_device2; |  | 
| 1138         HRESULT hr = d3d11_device_.CopyTo(dxgi_device2.GetAddressOf()); |  | 
| 1139         DCHECK(SUCCEEDED(hr)); |  | 
| 1140         base::WaitableEvent event( |  | 
| 1141             base::WaitableEvent::ResetPolicy::AUTOMATIC, |  | 
| 1142             base::WaitableEvent::InitialState::NOT_SIGNALED); |  | 
| 1143         dxgi_device2->EnqueueSetEvent(event.handle()); |  | 
| 1144         event.Wait(); |  | 
| 1145         first_swap_ = false; |  | 
| 1146       } |  | 
| 1147     } |  | 
| 1148   } |  | 
| 1149   if (dcomp_surface_ == g_current_surface) |  | 
| 1150     g_current_surface = nullptr; |  | 
| 1151 } | 1034 } | 
| 1152 | 1035 | 
| 1153 void DirectCompositionSurfaceWin::Destroy() { | 1036 void DirectCompositionSurfaceWin::Destroy() { | 
| 1154   if (default_surface_) { | 1037   if (default_surface_) { | 
| 1155     if (!eglDestroySurface(GetDisplay(), default_surface_)) { | 1038     if (!eglDestroySurface(GetDisplay(), default_surface_)) { | 
| 1156       DLOG(ERROR) << "eglDestroySurface failed with error " | 1039       DLOG(ERROR) << "eglDestroySurface failed with error " | 
| 1157                   << ui::GetLastEGLErrorString(); | 1040                   << ui::GetLastEGLErrorString(); | 
| 1158     } | 1041     } | 
| 1159     default_surface_ = nullptr; | 1042     default_surface_ = nullptr; | 
| 1160   } | 1043   } | 
| 1161   if (real_surface_) { | 1044   if (root_surface_) | 
| 1162     if (!eglDestroySurface(GetDisplay(), real_surface_)) { | 1045     root_surface_->Destroy(); | 
| 1163       DLOG(ERROR) << "eglDestroySurface failed with error " |  | 
| 1164                   << ui::GetLastEGLErrorString(); |  | 
| 1165     } |  | 
| 1166     real_surface_ = nullptr; |  | 
| 1167   } |  | 
| 1168   if (dcomp_surface_ && (dcomp_surface_ == g_current_surface)) { |  | 
| 1169     HRESULT hr = dcomp_surface_->EndDraw(); |  | 
| 1170     CHECK(SUCCEEDED(hr)); |  | 
| 1171     g_current_surface = nullptr; |  | 
| 1172   } |  | 
| 1173   draw_texture_.Reset(); |  | 
| 1174   dcomp_surface_.Reset(); |  | 
| 1175 } | 1046 } | 
| 1176 | 1047 | 
| 1177 gfx::Size DirectCompositionSurfaceWin::GetSize() { | 1048 gfx::Size DirectCompositionSurfaceWin::GetSize() { | 
| 1178   return size_; | 1049   return size_; | 
| 1179 } | 1050 } | 
| 1180 | 1051 | 
| 1181 bool DirectCompositionSurfaceWin::IsOffscreen() { | 1052 bool DirectCompositionSurfaceWin::IsOffscreen() { | 
| 1182   return false; | 1053   return false; | 
| 1183 } | 1054 } | 
| 1184 | 1055 | 
| 1185 void* DirectCompositionSurfaceWin::GetHandle() { | 1056 void* DirectCompositionSurfaceWin::GetHandle() { | 
| 1186   return real_surface_ ? real_surface_ : default_surface_; | 1057   return root_surface_ ? root_surface_->GetHandle() : default_surface_; | 
| 1187 } | 1058 } | 
| 1188 | 1059 | 
| 1189 bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size, | 1060 bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size, | 
| 1190                                          float scale_factor, | 1061                                          float scale_factor, | 
| 1191                                          bool has_alpha) { | 1062                                          bool has_alpha) { | 
| 1192   if ((size == GetSize()) && (has_alpha == has_alpha_)) | 1063   if ((size == GetSize()) && (has_alpha == has_alpha_)) | 
| 1193     return true; | 1064     return true; | 
| 1194 | 1065 | 
| 1195   // Force a resize and redraw (but not a move, activate, etc.). | 1066   // Force a resize and redraw (but not a move, activate, etc.). | 
| 1196   if (!SetWindowPos(window_, nullptr, 0, 0, size.width(), size.height(), | 1067   if (!SetWindowPos(window_, nullptr, 0, 0, size.width(), size.height(), | 
| 1197                     SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 1068                     SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 
| 1198                         SWP_NOOWNERZORDER | SWP_NOZORDER)) { | 1069                         SWP_NOOWNERZORDER | SWP_NOZORDER)) { | 
| 1199     return false; | 1070     return false; | 
| 1200   } | 1071   } | 
| 1201   size_ = size; | 1072   size_ = size; | 
| 1202   has_alpha_ = has_alpha; | 1073   has_alpha_ = has_alpha; | 
| 1203   ScopedReleaseCurrent release_current(this); | 1074   ui::ScopedReleaseCurrent release_current(this); | 
| 1204   // New surface will be initialized in SetDrawRectangle. | 1075   return RecreateRootSurface(); | 
| 1205   ReleaseCurrentSurface(); |  | 
| 1206 |  | 
| 1207   return true; |  | 
| 1208 } | 1076 } | 
| 1209 | 1077 | 
| 1210 gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers() { | 1078 gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers() { | 
| 1211   { | 1079   { | 
| 1212     ScopedReleaseCurrent release_current(this); | 1080     ui::ScopedReleaseCurrent release_current(this); | 
| 1213     ReleaseDrawTexture(false); | 1081     root_surface_->SwapBuffers(); | 
| 1214 | 1082 | 
| 1215     layer_tree_->CommitAndClearPendingOverlays(); | 1083     layer_tree_->CommitAndClearPendingOverlays(); | 
| 1216   } | 1084   } | 
| 1217   child_window_.ClearInvalidContents(); | 1085   child_window_.ClearInvalidContents(); | 
| 1218   return gfx::SwapResult::SWAP_ACK; | 1086   return gfx::SwapResult::SWAP_ACK; | 
| 1219 } | 1087 } | 
| 1220 | 1088 | 
| 1221 gfx::SwapResult DirectCompositionSurfaceWin::PostSubBuffer(int x, | 1089 gfx::SwapResult DirectCompositionSurfaceWin::PostSubBuffer(int x, | 
| 1222                                                            int y, | 1090                                                            int y, | 
| 1223                                                            int width, | 1091                                                            int width, | 
| 1224                                                            int height) { | 1092                                                            int height) { | 
| 1225   // The arguments are ignored because SetDrawRectangle specified the area to | 1093   // The arguments are ignored because SetDrawRectangle specified the area to | 
| 1226   // be swapped. | 1094   // be swapped. | 
| 1227   return SwapBuffers(); | 1095   return SwapBuffers(); | 
| 1228 } | 1096 } | 
| 1229 | 1097 | 
| 1230 gfx::VSyncProvider* DirectCompositionSurfaceWin::GetVSyncProvider() { | 1098 gfx::VSyncProvider* DirectCompositionSurfaceWin::GetVSyncProvider() { | 
| 1231   return vsync_provider_.get(); | 1099   return vsync_provider_.get(); | 
| 1232 } | 1100 } | 
| 1233 | 1101 | 
| 1234 bool DirectCompositionSurfaceWin::ScheduleDCLayer( | 1102 bool DirectCompositionSurfaceWin::ScheduleDCLayer( | 
| 1235     const ui::DCRendererLayerParams& params) { | 1103     const ui::DCRendererLayerParams& params) { | 
| 1236   return layer_tree_->ScheduleDCLayer(params); | 1104   return layer_tree_->ScheduleDCLayer(params); | 
| 1237 } | 1105 } | 
| 1238 | 1106 | 
| 1239 bool DirectCompositionSurfaceWin::SetEnableDCLayers(bool enable) { | 1107 bool DirectCompositionSurfaceWin::SetEnableDCLayers(bool enable) { | 
|  | 1108   if (enable_dc_layers_ == enable) | 
|  | 1109     return true; | 
|  | 1110   ui::ScopedReleaseCurrent release_current(this); | 
| 1240   enable_dc_layers_ = enable; | 1111   enable_dc_layers_ = enable; | 
| 1241   return true; | 1112   return RecreateRootSurface(); | 
| 1242 } | 1113 } | 
| 1243 | 1114 | 
| 1244 | 1115 | 
| 1245 bool DirectCompositionSurfaceWin::FlipsVertically() const { | 1116 bool DirectCompositionSurfaceWin::FlipsVertically() const { | 
| 1246   return true; | 1117   return true; | 
| 1247 } | 1118 } | 
| 1248 | 1119 | 
| 1249 bool DirectCompositionSurfaceWin::SupportsPostSubBuffer() { | 1120 bool DirectCompositionSurfaceWin::SupportsPostSubBuffer() { | 
| 1250   return true; | 1121   return true; | 
| 1251 } | 1122 } | 
| 1252 | 1123 | 
| 1253 bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) { | 1124 bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) { | 
| 1254   if (g_current_surface != dcomp_surface_) { | 1125   if (root_surface_) | 
| 1255     if (g_current_surface) { | 1126     return root_surface_->OnMakeCurrent(context); | 
| 1256       HRESULT hr = g_current_surface->SuspendDraw(); |  | 
| 1257       CHECK(SUCCEEDED(hr)); |  | 
| 1258       g_current_surface = nullptr; |  | 
| 1259     } |  | 
| 1260     if (draw_texture_) { |  | 
| 1261       HRESULT hr = dcomp_surface_->ResumeDraw(); |  | 
| 1262       CHECK(SUCCEEDED(hr)); |  | 
| 1263       g_current_surface = dcomp_surface_.Get(); |  | 
| 1264     } |  | 
| 1265   } |  | 
| 1266   return true; | 1127   return true; | 
| 1267 } | 1128 } | 
| 1268 | 1129 | 
| 1269 bool DirectCompositionSurfaceWin::SupportsDCLayers() const { | 1130 bool DirectCompositionSurfaceWin::SupportsDCLayers() const { | 
| 1270   return true; | 1131   return true; | 
| 1271 } | 1132 } | 
| 1272 | 1133 | 
| 1273 bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) { | 1134 bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) { | 
| 1274   if (draw_texture_) | 1135   if (root_surface_) | 
| 1275     return false; | 1136     return root_surface_->SetDrawRectangle(rectangle); | 
| 1276   DCHECK(!real_surface_); | 1137   return false; | 
| 1277   ScopedReleaseCurrent release_current(this); |  | 
| 1278 |  | 
| 1279   if ((enable_dc_layers_ && !dcomp_surface_) || |  | 
| 1280       (!enable_dc_layers_ && !swap_chain_)) { |  | 
| 1281     ReleaseCurrentSurface(); |  | 
| 1282     InitializeSurface(); |  | 
| 1283   } |  | 
| 1284 |  | 
| 1285   if (!gfx::Rect(size_).Contains(rectangle)) { |  | 
| 1286     DLOG(ERROR) << "Draw rectangle must be contained within size of surface"; |  | 
| 1287     return false; |  | 
| 1288   } |  | 
| 1289   if (gfx::Rect(size_) != rectangle && !has_been_rendered_to_) { |  | 
| 1290     DLOG(ERROR) << "First draw to surface must draw to everything"; |  | 
| 1291     return false; |  | 
| 1292   } |  | 
| 1293 |  | 
| 1294   CHECK(!g_current_surface); |  | 
| 1295 |  | 
| 1296   RECT rect = rectangle.ToRECT(); |  | 
| 1297   if (dcomp_surface_) { |  | 
| 1298     POINT update_offset; |  | 
| 1299     HRESULT hr = dcomp_surface_->BeginDraw( |  | 
| 1300         &rect, IID_PPV_ARGS(draw_texture_.GetAddressOf()), &update_offset); |  | 
| 1301     draw_offset_ = gfx::Point(update_offset) - gfx::Rect(rect).origin(); |  | 
| 1302     CHECK(SUCCEEDED(hr)); |  | 
| 1303   } else { |  | 
| 1304     HRESULT hr = |  | 
| 1305         swap_chain_->GetBuffer(0, IID_PPV_ARGS(draw_texture_.GetAddressOf())); |  | 
| 1306     swap_rect_ = rectangle; |  | 
| 1307     draw_offset_ = gfx::Vector2d(); |  | 
| 1308     CHECK(SUCCEEDED(hr)); |  | 
| 1309   } |  | 
| 1310   has_been_rendered_to_ = true; |  | 
| 1311 |  | 
| 1312   g_current_surface = dcomp_surface_.Get(); |  | 
| 1313 |  | 
| 1314   std::vector<EGLint> pbuffer_attribs{ |  | 
| 1315       EGL_WIDTH, |  | 
| 1316       size_.width(), |  | 
| 1317       EGL_HEIGHT, |  | 
| 1318       size_.height(), |  | 
| 1319       EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, |  | 
| 1320       EGL_TRUE, |  | 
| 1321       EGL_NONE}; |  | 
| 1322 |  | 
| 1323   EGLClientBuffer buffer = |  | 
| 1324       reinterpret_cast<EGLClientBuffer>(draw_texture_.Get()); |  | 
| 1325   real_surface_ = eglCreatePbufferFromClientBuffer( |  | 
| 1326       GetDisplay(), EGL_D3D_TEXTURE_ANGLE, buffer, GetConfig(), |  | 
| 1327       &pbuffer_attribs[0]); |  | 
| 1328 |  | 
| 1329   return true; |  | 
| 1330 } | 1138 } | 
| 1331 | 1139 | 
| 1332 gfx::Vector2d DirectCompositionSurfaceWin::GetDrawOffset() const { | 1140 gfx::Vector2d DirectCompositionSurfaceWin::GetDrawOffset() const { | 
| 1333   return draw_offset_; | 1141   if (root_surface_) | 
|  | 1142     return root_surface_->GetDrawOffset(); | 
|  | 1143   return gfx::Vector2d(); | 
| 1334 } | 1144 } | 
| 1335 | 1145 | 
| 1336 void DirectCompositionSurfaceWin::WaitForSnapshotRendering() { | 1146 void DirectCompositionSurfaceWin::WaitForSnapshotRendering() { | 
| 1337   DCHECK(gl::GLContext::GetCurrent()->IsCurrent(this)); | 1147   DCHECK(gl::GLContext::GetCurrent()->IsCurrent(this)); | 
| 1338   glFinish(); | 1148   glFinish(); | 
| 1339 } | 1149 } | 
| 1340 | 1150 | 
|  | 1151 bool DirectCompositionSurfaceWin::RecreateRootSurface() { | 
|  | 1152   root_surface_ = new DirectCompositionChildSurfaceWin(size_, has_alpha_, | 
|  | 1153                                                        enable_dc_layers_); | 
|  | 1154   return root_surface_->Initialize(); | 
|  | 1155 } | 
|  | 1156 | 
|  | 1157 const base::win::ScopedComPtr<IDCompositionSurface> | 
|  | 1158 DirectCompositionSurfaceWin::dcomp_surface() const { | 
|  | 1159   return root_surface_ ? root_surface_->dcomp_surface() : nullptr; | 
|  | 1160 } | 
|  | 1161 | 
|  | 1162 const base::win::ScopedComPtr<IDXGISwapChain1> | 
|  | 1163 DirectCompositionSurfaceWin::swap_chain() const { | 
|  | 1164   return root_surface_ ? root_surface_->swap_chain() : nullptr; | 
|  | 1165 } | 
|  | 1166 | 
| 1341 scoped_refptr<base::TaskRunner> | 1167 scoped_refptr<base::TaskRunner> | 
| 1342 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 1168 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 
| 1343   return child_window_.GetTaskRunnerForTesting(); | 1169   return child_window_.GetTaskRunnerForTesting(); | 
| 1344 } | 1170 } | 
| 1345 | 1171 | 
| 1346 base::win::ScopedComPtr<IDXGISwapChain1> | 1172 base::win::ScopedComPtr<IDXGISwapChain1> | 
| 1347 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 1173 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 
| 1348   return layer_tree_->GetLayerSwapChainForTesting(index); | 1174   return layer_tree_->GetLayerSwapChainForTesting(index); | 
| 1349 } | 1175 } | 
| 1350 | 1176 | 
| 1351 }  // namespace gpu | 1177 }  // namespace gpu | 
| OLD | NEW | 
|---|