 Chromium Code Reviews
 Chromium Code Reviews Issue 2926763002:
  Split DirectCompositionSurfaceWin into two parts.  (Closed)
    
  
    Issue 2926763002:
  Split DirectCompositionSurfaceWin into two parts.  (Closed) 
  | 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" | 15 #include "base/optional.h" | 
| 16 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" | 
| 17 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" | 
| 18 #include "base/win/scoped_handle.h" | 18 #include "base/win/scoped_handle.h" | 
| 19 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" | 
| 20 #include "gpu/command_buffer/service/feature_info.h" | 20 #include "gpu/command_buffer/service/feature_info.h" | 
| 21 #include "gpu/ipc/service/direct_composition_child_surface_win.h" | |
| 21 #include "gpu/ipc/service/gpu_channel_manager.h" | 22 #include "gpu/ipc/service/gpu_channel_manager.h" | 
| 22 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" | 23 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" | 
| 23 #include "gpu/ipc/service/switches.h" | 24 #include "gpu/ipc/service/switches.h" | 
| 24 #include "ui/display/display_switches.h" | 25 #include "ui/display/display_switches.h" | 
| 25 #include "ui/gfx/color_space_win.h" | 26 #include "ui/gfx/color_space_win.h" | 
| 26 #include "ui/gfx/geometry/size_conversions.h" | 27 #include "ui/gfx/geometry/size_conversions.h" | 
| 27 #include "ui/gfx/native_widget_types.h" | 28 #include "ui/gfx/native_widget_types.h" | 
| 28 #include "ui/gfx/transform.h" | 29 #include "ui/gfx/transform.h" | 
| 29 #include "ui/gl/dc_renderer_layer_params.h" | 30 #include "ui/gl/dc_renderer_layer_params.h" | 
| 30 #include "ui/gl/egl_util.h" | 31 #include "ui/gl/egl_util.h" | 
| 31 #include "ui/gl/gl_angle_util_win.h" | 32 #include "ui/gl/gl_angle_util_win.h" | 
| 32 #include "ui/gl/gl_context.h" | 33 #include "ui/gl/gl_context.h" | 
| 33 #include "ui/gl/gl_image_dxgi.h" | 34 #include "ui/gl/gl_image_dxgi.h" | 
| 34 #include "ui/gl/gl_image_memory.h" | 35 #include "ui/gl/gl_image_memory.h" | 
| 35 #include "ui/gl/gl_surface_egl.h" | 36 #include "ui/gl/gl_surface_egl.h" | 
| 36 #include "ui/gl/scoped_make_current.h" | 37 #include "ui/gl/scoped_make_current.h" | 
| 37 | 38 | 
| 38 #ifndef EGL_ANGLE_flexible_surface_compatibility | 39 #ifndef EGL_ANGLE_flexible_surface_compatibility | 
| 39 #define EGL_ANGLE_flexible_surface_compatibility 1 | 40 #define EGL_ANGLE_flexible_surface_compatibility 1 | 
| 40 #define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6 | 41 #define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6 | 
| 41 #endif /* EGL_ANGLE_flexible_surface_compatibility */ | 42 #endif /* EGL_ANGLE_flexible_surface_compatibility */ | 
| 42 | 43 | 
| 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 { | 44 namespace gpu { | 
| 49 namespace { | 45 namespace { | 
| 50 | 46 | 
| 51 // Some drivers fail to correctly handle BT.709 video in overlays. This flag | 47 // Some drivers fail to correctly handle BT.709 video in overlays. This flag | 
| 52 // converts them to BT.601 in the video processor. | 48 // converts them to BT.601 in the video processor. | 
| 53 const base::Feature kFallbackBT709VideoToBT601{ | 49 const base::Feature kFallbackBT709VideoToBT601{ | 
| 54 "FallbackBT709VideoToBT601", base::FEATURE_DISABLED_BY_DEFAULT}; | 50 "FallbackBT709VideoToBT601", base::FEATURE_DISABLED_BY_DEFAULT}; | 
| 55 | 51 | 
| 56 // This class is used to make sure a specified surface isn't current, and upon | 52 // 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. | 53 // destruction it will make the surface current again if it had been before. | 
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 g_overlay_monitor_size = | 164 g_overlay_monitor_size = | 
| 169 gfx::Rect(monitor_desc.DesktopCoordinates).size(); | 165 gfx::Rect(monitor_desc.DesktopCoordinates).size(); | 
| 170 g_supports_scaled_overlays = | 166 g_supports_scaled_overlays = | 
| 171 !!(flags & DXGI_OVERLAY_SUPPORT_FLAG_SCALING); | 167 !!(flags & DXGI_OVERLAY_SUPPORT_FLAG_SCALING); | 
| 172 return true; | 168 return true; | 
| 173 } | 169 } | 
| 174 } | 170 } | 
| 175 return false; | 171 return false; | 
| 176 } | 172 } | 
| 177 | 173 | 
| 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 | 174 } // namespace | 
| 184 | 175 | 
| 185 class DCLayerTree { | 176 class DCLayerTree { | 
| 186 public: | 177 public: | 
| 187 DCLayerTree(DirectCompositionSurfaceWin* surface, | 178 DCLayerTree(DirectCompositionSurfaceWin* surface, | 
| 188 const base::win::ScopedComPtr<ID3D11Device>& d3d11_device, | 179 const base::win::ScopedComPtr<ID3D11Device>& d3d11_device, | 
| 189 const base::win::ScopedComPtr<IDCompositionDevice2>& dcomp_device) | 180 const base::win::ScopedComPtr<IDCompositionDevice2>& dcomp_device) | 
| 190 : surface_(surface), | 181 : surface_(surface), | 
| 191 d3d11_device_(d3d11_device), | 182 d3d11_device_(d3d11_device), | 
| 192 dcomp_device_(dcomp_device) {} | 183 dcomp_device_(dcomp_device) {} | 
| (...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1051 pbuffer_attribs.push_back(EGL_WIDTH); | 1042 pbuffer_attribs.push_back(EGL_WIDTH); | 
| 1052 pbuffer_attribs.push_back(1); | 1043 pbuffer_attribs.push_back(1); | 
| 1053 pbuffer_attribs.push_back(EGL_HEIGHT); | 1044 pbuffer_attribs.push_back(EGL_HEIGHT); | 
| 1054 pbuffer_attribs.push_back(1); | 1045 pbuffer_attribs.push_back(1); | 
| 1055 | 1046 | 
| 1056 pbuffer_attribs.push_back(EGL_NONE); | 1047 pbuffer_attribs.push_back(EGL_NONE); | 
| 1057 default_surface_ = | 1048 default_surface_ = | 
| 1058 eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]); | 1049 eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]); | 
| 1059 CHECK(!!default_surface_); | 1050 CHECK(!!default_surface_); | 
| 1060 | 1051 | 
| 1061 return true; | 1052 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 } | 1053 } | 
| 1152 | 1054 | 
| 1153 void DirectCompositionSurfaceWin::Destroy() { | 1055 void DirectCompositionSurfaceWin::Destroy() { | 
| 1154 if (default_surface_) { | 1056 if (default_surface_) { | 
| 1155 if (!eglDestroySurface(GetDisplay(), default_surface_)) { | 1057 if (!eglDestroySurface(GetDisplay(), default_surface_)) { | 
| 1156 DLOG(ERROR) << "eglDestroySurface failed with error " | 1058 DLOG(ERROR) << "eglDestroySurface failed with error " | 
| 1157 << ui::GetLastEGLErrorString(); | 1059 << ui::GetLastEGLErrorString(); | 
| 1158 } | 1060 } | 
| 1159 default_surface_ = nullptr; | 1061 default_surface_ = nullptr; | 
| 1160 } | 1062 } | 
| 1161 if (real_surface_) { | 1063 if (root_surface_) | 
| 1162 if (!eglDestroySurface(GetDisplay(), real_surface_)) { | 1064 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 } | 1065 } | 
| 1176 | 1066 | 
| 1177 gfx::Size DirectCompositionSurfaceWin::GetSize() { | 1067 gfx::Size DirectCompositionSurfaceWin::GetSize() { | 
| 1178 return size_; | 1068 return size_; | 
| 1179 } | 1069 } | 
| 1180 | 1070 | 
| 1181 bool DirectCompositionSurfaceWin::IsOffscreen() { | 1071 bool DirectCompositionSurfaceWin::IsOffscreen() { | 
| 1182 return false; | 1072 return false; | 
| 1183 } | 1073 } | 
| 1184 | 1074 | 
| 1185 void* DirectCompositionSurfaceWin::GetHandle() { | 1075 void* DirectCompositionSurfaceWin::GetHandle() { | 
| 1186 return real_surface_ ? real_surface_ : default_surface_; | 1076 return root_surface_ ? root_surface_->GetHandle() : default_surface_; | 
| 1187 } | 1077 } | 
| 1188 | 1078 | 
| 1189 bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size, | 1079 bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size, | 
| 1190 float scale_factor, | 1080 float scale_factor, | 
| 1191 bool has_alpha) { | 1081 bool has_alpha) { | 
| 1192 if ((size == GetSize()) && (has_alpha == has_alpha_)) | 1082 if ((size == GetSize()) && (has_alpha == has_alpha_)) | 
| 1193 return true; | 1083 return true; | 
| 1194 | 1084 | 
| 1195 // Force a resize and redraw (but not a move, activate, etc.). | 1085 // Force a resize and redraw (but not a move, activate, etc.). | 
| 1196 if (!SetWindowPos(window_, nullptr, 0, 0, size.width(), size.height(), | 1086 if (!SetWindowPos(window_, nullptr, 0, 0, size.width(), size.height(), | 
| 1197 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 1087 SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOCOPYBITS | | 
| 1198 SWP_NOOWNERZORDER | SWP_NOZORDER)) { | 1088 SWP_NOOWNERZORDER | SWP_NOZORDER)) { | 
| 1199 return false; | 1089 return false; | 
| 1200 } | 1090 } | 
| 1201 size_ = size; | 1091 size_ = size; | 
| 1202 has_alpha_ = has_alpha; | 1092 has_alpha_ = has_alpha; | 
| 1203 ScopedReleaseCurrent release_current(this); | 1093 ScopedReleaseCurrent release_current(this); | 
| 1204 // New surface will be initialized in SetDrawRectangle. | 1094 return RecreateRootSurface(); | 
| 
sunnyps
2017/06/10 00:11:11
nit: This seems like a change in behavior if multi
 | |
| 1205 ReleaseCurrentSurface(); | |
| 1206 | |
| 1207 return true; | |
| 1208 } | 1095 } | 
| 1209 | 1096 | 
| 1210 gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers() { | 1097 gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers() { | 
| 1211 { | 1098 { | 
| 1212 ScopedReleaseCurrent release_current(this); | 1099 ScopedReleaseCurrent release_current(this); | 
| 1213 ReleaseDrawTexture(false); | 1100 root_surface_->SwapBuffers(); | 
| 1214 | 1101 | 
| 1215 layer_tree_->CommitAndClearPendingOverlays(); | 1102 layer_tree_->CommitAndClearPendingOverlays(); | 
| 1216 } | 1103 } | 
| 1217 child_window_.ClearInvalidContents(); | 1104 child_window_.ClearInvalidContents(); | 
| 1218 return gfx::SwapResult::SWAP_ACK; | 1105 return gfx::SwapResult::SWAP_ACK; | 
| 1219 } | 1106 } | 
| 1220 | 1107 | 
| 1221 gfx::SwapResult DirectCompositionSurfaceWin::PostSubBuffer(int x, | 1108 gfx::SwapResult DirectCompositionSurfaceWin::PostSubBuffer(int x, | 
| 1222 int y, | 1109 int y, | 
| 1223 int width, | 1110 int width, | 
| 1224 int height) { | 1111 int height) { | 
| 1225 // The arguments are ignored because SetDrawRectangle specified the area to | 1112 // The arguments are ignored because SetDrawRectangle specified the area to | 
| 1226 // be swapped. | 1113 // be swapped. | 
| 1227 return SwapBuffers(); | 1114 return SwapBuffers(); | 
| 1228 } | 1115 } | 
| 1229 | 1116 | 
| 1230 gfx::VSyncProvider* DirectCompositionSurfaceWin::GetVSyncProvider() { | 1117 gfx::VSyncProvider* DirectCompositionSurfaceWin::GetVSyncProvider() { | 
| 1231 return vsync_provider_.get(); | 1118 return vsync_provider_.get(); | 
| 1232 } | 1119 } | 
| 1233 | 1120 | 
| 1234 bool DirectCompositionSurfaceWin::ScheduleDCLayer( | 1121 bool DirectCompositionSurfaceWin::ScheduleDCLayer( | 
| 1235 const ui::DCRendererLayerParams& params) { | 1122 const ui::DCRendererLayerParams& params) { | 
| 1236 return layer_tree_->ScheduleDCLayer(params); | 1123 return layer_tree_->ScheduleDCLayer(params); | 
| 1237 } | 1124 } | 
| 1238 | 1125 | 
| 1239 bool DirectCompositionSurfaceWin::SetEnableDCLayers(bool enable) { | 1126 bool DirectCompositionSurfaceWin::SetEnableDCLayers(bool enable) { | 
| 1127 if (enable_dc_layers_ == enable) | |
| 1128 return true; | |
| 1129 ScopedReleaseCurrent release_current(this); | |
| 1240 enable_dc_layers_ = enable; | 1130 enable_dc_layers_ = enable; | 
| 1241 return true; | 1131 return RecreateRootSurface(); | 
| 1242 } | 1132 } | 
| 1243 | 1133 | 
| 1244 | 1134 | 
| 1245 bool DirectCompositionSurfaceWin::FlipsVertically() const { | 1135 bool DirectCompositionSurfaceWin::FlipsVertically() const { | 
| 1246 return true; | 1136 return true; | 
| 1247 } | 1137 } | 
| 1248 | 1138 | 
| 1249 bool DirectCompositionSurfaceWin::SupportsPostSubBuffer() { | 1139 bool DirectCompositionSurfaceWin::SupportsPostSubBuffer() { | 
| 1250 return true; | 1140 return true; | 
| 1251 } | 1141 } | 
| 1252 | 1142 | 
| 1253 bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) { | 1143 bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) { | 
| 1254 if (g_current_surface != dcomp_surface_) { | 1144 if (root_surface_) | 
| 1255 if (g_current_surface) { | 1145 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; | 1146 return true; | 
| 1267 } | 1147 } | 
| 1268 | 1148 | 
| 1269 bool DirectCompositionSurfaceWin::SupportsDCLayers() const { | 1149 bool DirectCompositionSurfaceWin::SupportsDCLayers() const { | 
| 1270 return true; | 1150 return true; | 
| 1271 } | 1151 } | 
| 1272 | 1152 | 
| 1273 bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) { | 1153 bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) { | 
| 1274 if (draw_texture_) | 1154 if (root_surface_) | 
| 1275 return false; | 1155 return root_surface_->SetDrawRectangle(rectangle); | 
| 1276 DCHECK(!real_surface_); | 1156 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 } | 1157 } | 
| 1331 | 1158 | 
| 1332 gfx::Vector2d DirectCompositionSurfaceWin::GetDrawOffset() const { | 1159 gfx::Vector2d DirectCompositionSurfaceWin::GetDrawOffset() const { | 
| 1333 return draw_offset_; | 1160 if (root_surface_) | 
| 1161 return root_surface_->GetDrawOffset(); | |
| 1162 return gfx::Vector2d(); | |
| 1334 } | 1163 } | 
| 1335 | 1164 | 
| 1336 void DirectCompositionSurfaceWin::WaitForSnapshotRendering() { | 1165 void DirectCompositionSurfaceWin::WaitForSnapshotRendering() { | 
| 1337 DCHECK(gl::GLContext::GetCurrent()->IsCurrent(this)); | 1166 DCHECK(gl::GLContext::GetCurrent()->IsCurrent(this)); | 
| 1338 glFinish(); | 1167 glFinish(); | 
| 1339 } | 1168 } | 
| 1340 | 1169 | 
| 1170 bool DirectCompositionSurfaceWin::RecreateRootSurface() { | |
| 1171 root_surface_ = new DirectCompositionChildSurfaceWin(size_, has_alpha_, | |
| 1172 enable_dc_layers_); | |
| 1173 return root_surface_->Initialize(); | |
| 1174 } | |
| 1175 | |
| 1176 const base::win::ScopedComPtr<IDCompositionSurface> | |
| 1177 DirectCompositionSurfaceWin::dcomp_surface() const { | |
| 1178 return root_surface_ ? root_surface_->dcomp_surface() : nullptr; | |
| 1179 } | |
| 1180 | |
| 1181 const base::win::ScopedComPtr<IDXGISwapChain1> | |
| 1182 DirectCompositionSurfaceWin::swap_chain() const { | |
| 1183 return root_surface_ ? root_surface_->swap_chain() : nullptr; | |
| 1184 } | |
| 1185 | |
| 1341 scoped_refptr<base::TaskRunner> | 1186 scoped_refptr<base::TaskRunner> | 
| 1342 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 1187 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 
| 1343 return child_window_.GetTaskRunnerForTesting(); | 1188 return child_window_.GetTaskRunnerForTesting(); | 
| 1344 } | 1189 } | 
| 1345 | 1190 | 
| 1346 base::win::ScopedComPtr<IDXGISwapChain1> | 1191 base::win::ScopedComPtr<IDXGISwapChain1> | 
| 1347 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 1192 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 
| 1348 return layer_tree_->GetLayerSwapChainForTesting(index); | 1193 return layer_tree_->GetLayerSwapChainForTesting(index); | 
| 1349 } | 1194 } | 
| 1350 | 1195 | 
| 1351 } // namespace gpu | 1196 } // namespace gpu | 
| OLD | NEW |