| 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> |
| 11 |
| 10 #include "base/feature_list.h" | 12 #include "base/feature_list.h" |
| 11 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 12 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/optional.h" | 15 #include "base/optional.h" |
| 14 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
| 15 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
| 16 #include "base/win/scoped_handle.h" | 18 #include "base/win/scoped_handle.h" |
| 17 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
| 18 #include "gpu/ipc/service/gpu_channel_manager.h" | 20 #include "gpu/ipc/service/gpu_channel_manager.h" |
| 19 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" | 21 #include "gpu/ipc/service/gpu_channel_manager_delegate.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 } | 66 } |
| 65 | 67 |
| 66 private: | 68 private: |
| 67 base::Optional<ui::ScopedMakeCurrent> make_current_; | 69 base::Optional<ui::ScopedMakeCurrent> make_current_; |
| 68 }; | 70 }; |
| 69 | 71 |
| 70 bool SizeContains(const gfx::Size& a, const gfx::Size& b) { | 72 bool SizeContains(const gfx::Size& a, const gfx::Size& b) { |
| 71 return gfx::Rect(a).Contains(gfx::Rect(b)); | 73 return gfx::Rect(a).Contains(gfx::Rect(b)); |
| 72 } | 74 } |
| 73 | 75 |
| 76 // This keeps track of whether the previous 30 frames used Overlays or GPU |
| 77 // composition to present. |
| 78 class PresentationHistory { |
| 79 public: |
| 80 static const int kPresentsToStore = 30; |
| 81 |
| 82 PresentationHistory() {} |
| 83 |
| 84 void AddSample(DXGI_FRAME_PRESENTATION_MODE mode) { |
| 85 if (mode == DXGI_FRAME_PRESENTATION_MODE_COMPOSED) |
| 86 composed_count_++; |
| 87 |
| 88 presents_.push_back(mode); |
| 89 if (presents_.size() > kPresentsToStore) { |
| 90 DXGI_FRAME_PRESENTATION_MODE first_mode = presents_.front(); |
| 91 if (first_mode == DXGI_FRAME_PRESENTATION_MODE_COMPOSED) |
| 92 composed_count_--; |
| 93 presents_.pop_front(); |
| 94 } |
| 95 } |
| 96 |
| 97 bool valid() const { return presents_.size() >= kPresentsToStore; } |
| 98 int composed_count() const { return composed_count_; } |
| 99 |
| 100 private: |
| 101 std::deque<DXGI_FRAME_PRESENTATION_MODE> presents_; |
| 102 int composed_count_ = 0; |
| 103 |
| 104 DISALLOW_COPY_AND_ASSIGN(PresentationHistory); |
| 105 }; |
| 106 |
| 74 // Only one DirectComposition surface can be rendered into at a time. Track | 107 // Only one DirectComposition surface can be rendered into at a time. Track |
| 75 // here which IDCompositionSurface is being rendered into. If another context | 108 // here which IDCompositionSurface is being rendered into. If another context |
| 76 // is made current, then this surface will be suspended. | 109 // is made current, then this surface will be suspended. |
| 77 IDCompositionSurface* g_current_surface; | 110 IDCompositionSurface* g_current_surface; |
| 78 | 111 |
| 79 } // namespace | 112 } // namespace |
| 80 | 113 |
| 81 class DCLayerTree { | 114 class DCLayerTree { |
| 82 public: | 115 public: |
| 83 DCLayerTree(DirectCompositionSurfaceWin* surface, | 116 DCLayerTree(DirectCompositionSurfaceWin* surface, |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 return swap_chain_; | 204 return swap_chain_; |
| 172 } | 205 } |
| 173 | 206 |
| 174 private: | 207 private: |
| 175 using PFN_DCOMPOSITION_CREATE_SURFACE_HANDLE = | 208 using PFN_DCOMPOSITION_CREATE_SURFACE_HANDLE = |
| 176 HRESULT(WINAPI*)(DWORD, SECURITY_ATTRIBUTES*, HANDLE*); | 209 HRESULT(WINAPI*)(DWORD, SECURITY_ATTRIBUTES*, HANDLE*); |
| 177 | 210 |
| 178 // Returns true if the video processor changed. | 211 // Returns true if the video processor changed. |
| 179 bool InitializeVideoProcessor(const gfx::Size& in_size, | 212 bool InitializeVideoProcessor(const gfx::Size& in_size, |
| 180 const gfx::Size& out_size); | 213 const gfx::Size& out_size); |
| 181 void ReallocateSwapChain(); | 214 void ReallocateSwapChain(bool yuy2); |
| 215 bool ShouldBeYUY2(); |
| 182 | 216 |
| 183 DCLayerTree* surface_; | 217 DCLayerTree* surface_; |
| 184 PFN_DCOMPOSITION_CREATE_SURFACE_HANDLE create_surface_handle_function_; | 218 PFN_DCOMPOSITION_CREATE_SURFACE_HANDLE create_surface_handle_function_; |
| 185 | 219 |
| 186 gfx::Size swap_chain_size_; | 220 gfx::Size swap_chain_size_; |
| 187 gfx::Size processor_input_size_; | 221 gfx::Size processor_input_size_; |
| 188 gfx::Size processor_output_size_; | 222 gfx::Size processor_output_size_; |
| 189 bool is_yuy2_swapchain_ = false; | 223 bool is_yuy2_swapchain_ = false; |
| 190 | 224 |
| 191 // This is the scale from the swapchain size to the size of the contents | 225 // This is the scale from the swapchain size to the size of the contents |
| 192 // onscreen. | 226 // onscreen. |
| 193 float swap_chain_scale_x_ = 0.0f; | 227 float swap_chain_scale_x_ = 0.0f; |
| 194 float swap_chain_scale_y_ = 0.0f; | 228 float swap_chain_scale_y_ = 0.0f; |
| 195 | 229 |
| 230 PresentationHistory presentation_history_; |
| 231 bool failed_to_create_yuy2_swapchain_ = false; |
| 232 int frames_since_color_space_change_ = 0; |
| 233 |
| 196 // This is the GLImage that was presented in the last frame. | 234 // This is the GLImage that was presented in the last frame. |
| 197 scoped_refptr<gl::GLImageDXGI> last_gl_image_; | 235 scoped_refptr<gl::GLImageDXGI> last_gl_image_; |
| 198 | 236 |
| 199 base::win::ScopedComPtr<ID3D11Device> d3d11_device_; | 237 base::win::ScopedComPtr<ID3D11Device> d3d11_device_; |
| 200 base::win::ScopedComPtr<IDXGISwapChain1> swap_chain_; | 238 base::win::ScopedComPtr<IDXGISwapChain1> swap_chain_; |
| 201 base::win::ScopedComPtr<ID3D11VideoProcessorOutputView> out_view_; | 239 base::win::ScopedComPtr<ID3D11VideoProcessorOutputView> out_view_; |
| 202 base::win::ScopedComPtr<ID3D11VideoProcessor> video_processor_; | 240 base::win::ScopedComPtr<ID3D11VideoProcessor> video_processor_; |
| 203 base::win::ScopedComPtr<ID3D11VideoProcessorEnumerator> | 241 base::win::ScopedComPtr<ID3D11VideoProcessorEnumerator> |
| 204 video_processor_enumerator_; | 242 video_processor_enumerator_; |
| 205 base::win::ScopedComPtr<ID3D11VideoDevice> video_device_; | 243 base::win::ScopedComPtr<ID3D11VideoDevice> video_device_; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 HMODULE dcomp = ::GetModuleHandleA("dcomp.dll"); | 318 HMODULE dcomp = ::GetModuleHandleA("dcomp.dll"); |
| 281 CHECK(dcomp); | 319 CHECK(dcomp); |
| 282 create_surface_handle_function_ = | 320 create_surface_handle_function_ = |
| 283 reinterpret_cast<PFN_DCOMPOSITION_CREATE_SURFACE_HANDLE>( | 321 reinterpret_cast<PFN_DCOMPOSITION_CREATE_SURFACE_HANDLE>( |
| 284 GetProcAddress(dcomp, "DCompositionCreateSurfaceHandle")); | 322 GetProcAddress(dcomp, "DCompositionCreateSurfaceHandle")); |
| 285 CHECK(create_surface_handle_function_); | 323 CHECK(create_surface_handle_function_); |
| 286 } | 324 } |
| 287 | 325 |
| 288 DCLayerTree::SwapChainPresenter::~SwapChainPresenter() {} | 326 DCLayerTree::SwapChainPresenter::~SwapChainPresenter() {} |
| 289 | 327 |
| 328 bool DCLayerTree::SwapChainPresenter::ShouldBeYUY2() { |
| 329 // Start out as YUY2. |
| 330 if (!presentation_history_.valid()) |
| 331 return true; |
| 332 int composition_count = presentation_history_.composed_count(); |
| 333 |
| 334 // It's more efficient to use a BGRA backbuffer instead of YUY2 if overlays |
| 335 // aren't being used, as otherwise DWM will use the video processor a second |
| 336 // time to convert it to BGRA before displaying it on screen. |
| 337 |
| 338 if (is_yuy2_swapchain_) { |
| 339 // Switch to BGRA once 3/4 of presents are composed. |
| 340 return composition_count < (PresentationHistory::kPresentsToStore * 3 / 4); |
| 341 } else { |
| 342 // Switch to YUY2 once 3/4 are using overlays (or unknown). |
| 343 return composition_count < (PresentationHistory::kPresentsToStore / 4); |
| 344 } |
| 345 } |
| 346 |
| 290 void DCLayerTree::SwapChainPresenter::PresentToSwapChain( | 347 void DCLayerTree::SwapChainPresenter::PresentToSwapChain( |
| 291 const ui::DCRendererLayerParams& params) { | 348 const ui::DCRendererLayerParams& params) { |
| 292 gl::GLImageDXGI* image_dxgi = | 349 gl::GLImageDXGI* image_dxgi = |
| 293 gl::GLImageDXGI::FromGLImage(params.image.get()); | 350 gl::GLImageDXGI::FromGLImage(params.image.get()); |
| 294 DCHECK(image_dxgi); | 351 DCHECK(image_dxgi); |
| 295 | 352 |
| 296 // Swap chain size is the minimum of the on-screen size and the source | 353 // Swap chain size is the minimum of the on-screen size and the source |
| 297 // size so the video processor can do the minimal amount of work and | 354 // size so the video processor can do the minimal amount of work and |
| 298 // the overlay has to read the minimal amount of data. | 355 // the overlay has to read the minimal amount of data. |
| 299 // DWM is also less likely to promote a surface to an overlay if it's | 356 // DWM is also less likely to promote a surface to an overlay if it's |
| 300 // much larger than its area on-screen. | 357 // much larger than its area on-screen. |
| 301 gfx::Rect bounds_rect = params.rect; | 358 gfx::Rect bounds_rect = params.rect; |
| 302 gfx::Size ceiled_input_size = gfx::ToCeiledSize(params.contents_rect.size()); | 359 gfx::Size ceiled_input_size = gfx::ToCeiledSize(params.contents_rect.size()); |
| 303 gfx::Size swap_chain_size = bounds_rect.size(); | 360 gfx::Size swap_chain_size = bounds_rect.size(); |
| 304 swap_chain_size.SetToMin(ceiled_input_size); | 361 swap_chain_size.SetToMin(ceiled_input_size); |
| 305 | 362 |
| 306 // YUY2 surfaces must have an even width. | 363 // YUY2 surfaces must have an even width. |
| 307 if (swap_chain_size.width() % 2 == 1) | 364 if (swap_chain_size.width() % 2 == 1) |
| 308 swap_chain_size.set_width(swap_chain_size.width() + 1); | 365 swap_chain_size.set_width(swap_chain_size.width() + 1); |
| 309 | 366 |
| 310 InitializeVideoProcessor(ceiled_input_size, swap_chain_size); | 367 InitializeVideoProcessor(ceiled_input_size, swap_chain_size); |
| 311 | 368 |
| 369 bool yuy2_swapchain = ShouldBeYUY2(); |
| 312 bool first_present = false; | 370 bool first_present = false; |
| 313 if (!swap_chain_ || swap_chain_size_ != swap_chain_size) { | 371 if (!swap_chain_ || swap_chain_size_ != swap_chain_size || |
| 372 ((yuy2_swapchain != is_yuy2_swapchain_) && |
| 373 !failed_to_create_yuy2_swapchain_)) { |
| 314 first_present = true; | 374 first_present = true; |
| 315 swap_chain_size_ = swap_chain_size; | 375 swap_chain_size_ = swap_chain_size; |
| 316 swap_chain_.Reset(); | 376 swap_chain_.Reset(); |
| 317 ReallocateSwapChain(); | 377 ReallocateSwapChain(yuy2_swapchain); |
| 318 } else if (last_gl_image_ == image_dxgi) { | 378 } else if (last_gl_image_ == image_dxgi) { |
| 319 // The swap chain is presenting the same image as last swap, which means | 379 // The swap chain is presenting the same image as last swap, which means |
| 320 // that the image was never returned to the video decoder and should have | 380 // that the image was never returned to the video decoder and should have |
| 321 // the same contents as last time. It shouldn't need to be redrawn. | 381 // the same contents as last time. It shouldn't need to be redrawn. |
| 322 return; | 382 return; |
| 323 } | 383 } |
| 324 | 384 |
| 325 last_gl_image_ = image_dxgi; | 385 last_gl_image_ = image_dxgi; |
| 326 | 386 |
| 327 if (!out_view_) { | 387 if (!out_view_) { |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 hr = video_context_->VideoProcessorBlt(video_processor_.get(), | 468 hr = video_context_->VideoProcessorBlt(video_processor_.get(), |
| 409 out_view_.get(), 0, 1, &stream); | 469 out_view_.get(), 0, 1, &stream); |
| 410 CHECK(SUCCEEDED(hr)); | 470 CHECK(SUCCEEDED(hr)); |
| 411 } | 471 } |
| 412 | 472 |
| 413 swap_chain_scale_x_ = bounds_rect.width() * 1.0f / swap_chain_size.width(); | 473 swap_chain_scale_x_ = bounds_rect.width() * 1.0f / swap_chain_size.width(); |
| 414 swap_chain_scale_y_ = bounds_rect.height() * 1.0f / swap_chain_size.height(); | 474 swap_chain_scale_y_ = bounds_rect.height() * 1.0f / swap_chain_size.height(); |
| 415 | 475 |
| 416 swap_chain_->Present(first_present ? 0 : 1, 0); | 476 swap_chain_->Present(first_present ? 0 : 1, 0); |
| 417 | 477 |
| 478 frames_since_color_space_change_++; |
| 479 |
| 418 base::win::ScopedComPtr<IDXGISwapChainMedia> swap_chain_media; | 480 base::win::ScopedComPtr<IDXGISwapChainMedia> swap_chain_media; |
| 419 if (SUCCEEDED(swap_chain_.QueryInterface(swap_chain_media.Receive()))) { | 481 if (SUCCEEDED(swap_chain_.QueryInterface(swap_chain_media.Receive()))) { |
| 420 DXGI_FRAME_STATISTICS_MEDIA stats = {}; | 482 DXGI_FRAME_STATISTICS_MEDIA stats = {}; |
| 421 if (SUCCEEDED(swap_chain_media->GetFrameStatisticsMedia(&stats))) { | 483 if (SUCCEEDED(swap_chain_media->GetFrameStatisticsMedia(&stats))) { |
| 422 UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.DirectComposition.CompositionMode", | 484 UMA_HISTOGRAM_SPARSE_SLOWLY("GPU.DirectComposition.CompositionMode", |
| 423 stats.CompositionMode); | 485 stats.CompositionMode); |
| 486 presentation_history_.AddSample(stats.CompositionMode); |
| 424 } | 487 } |
| 425 } | 488 } |
| 426 } | 489 } |
| 427 | 490 |
| 428 bool DCLayerTree::SwapChainPresenter::InitializeVideoProcessor( | 491 bool DCLayerTree::SwapChainPresenter::InitializeVideoProcessor( |
| 429 const gfx::Size& in_size, | 492 const gfx::Size& in_size, |
| 430 const gfx::Size& out_size) { | 493 const gfx::Size& out_size) { |
| 431 if (video_processor_ && SizeContains(processor_input_size_, in_size) && | 494 if (video_processor_ && SizeContains(processor_input_size_, in_size) && |
| 432 SizeContains(processor_output_size_, out_size)) | 495 SizeContains(processor_output_size_, out_size)) |
| 433 return false; | 496 return false; |
| 434 processor_input_size_ = in_size; | 497 processor_input_size_ = in_size; |
| 435 processor_output_size_ = out_size; | 498 processor_output_size_ = out_size; |
| 436 surface_->InitializeVideoProcessor(in_size, out_size); | 499 surface_->InitializeVideoProcessor(in_size, out_size); |
| 437 | 500 |
| 438 video_processor_enumerator_ = surface_->video_processor_enumerator(); | 501 video_processor_enumerator_ = surface_->video_processor_enumerator(); |
| 439 video_processor_ = surface_->video_processor(); | 502 video_processor_ = surface_->video_processor(); |
| 440 // out_view_ depends on video_processor_enumerator_, so ensure it's | 503 // out_view_ depends on video_processor_enumerator_, so ensure it's |
| 441 // recreated if the enumerator is. | 504 // recreated if the enumerator is. |
| 442 out_view_.Reset(); | 505 out_view_.Reset(); |
| 443 return true; | 506 return true; |
| 444 } | 507 } |
| 445 | 508 |
| 446 void DCLayerTree::SwapChainPresenter::ReallocateSwapChain() { | 509 void DCLayerTree::SwapChainPresenter::ReallocateSwapChain(bool yuy2) { |
| 447 TRACE_EVENT0("gpu", "DCLayerTree::SwapChainPresenter::ReallocateSwapChain"); | 510 TRACE_EVENT0("gpu", "DCLayerTree::SwapChainPresenter::ReallocateSwapChain"); |
| 448 DCHECK(!swap_chain_); | 511 DCHECK(!swap_chain_); |
| 449 | 512 |
| 450 base::win::ScopedComPtr<IDXGIDevice> dxgi_device; | 513 base::win::ScopedComPtr<IDXGIDevice> dxgi_device; |
| 451 d3d11_device_.QueryInterface(dxgi_device.Receive()); | 514 d3d11_device_.QueryInterface(dxgi_device.Receive()); |
| 452 base::win::ScopedComPtr<IDXGIAdapter> dxgi_adapter; | 515 base::win::ScopedComPtr<IDXGIAdapter> dxgi_adapter; |
| 453 dxgi_device->GetAdapter(dxgi_adapter.Receive()); | 516 dxgi_device->GetAdapter(dxgi_adapter.Receive()); |
| 454 base::win::ScopedComPtr<IDXGIFactory2> dxgi_factory; | 517 base::win::ScopedComPtr<IDXGIFactory2> dxgi_factory; |
| 455 dxgi_adapter->GetParent(IID_PPV_ARGS(dxgi_factory.Receive())); | 518 dxgi_adapter->GetParent(IID_PPV_ARGS(dxgi_factory.Receive())); |
| 456 | 519 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 468 desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; | 531 desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; |
| 469 desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; | 532 desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; |
| 470 desc.Flags = | 533 desc.Flags = |
| 471 DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO | DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO; | 534 DXGI_SWAP_CHAIN_FLAG_YUV_VIDEO | DXGI_SWAP_CHAIN_FLAG_FULLSCREEN_VIDEO; |
| 472 | 535 |
| 473 HANDLE handle; | 536 HANDLE handle; |
| 474 create_surface_handle_function_(COMPOSITIONOBJECT_ALL_ACCESS, nullptr, | 537 create_surface_handle_function_(COMPOSITIONOBJECT_ALL_ACCESS, nullptr, |
| 475 &handle); | 538 &handle); |
| 476 swap_chain_handle_.Set(handle); | 539 swap_chain_handle_.Set(handle); |
| 477 | 540 |
| 478 is_yuy2_swapchain_ = true; | 541 if (is_yuy2_swapchain_ != yuy2) { |
| 542 UMA_HISTOGRAM_COUNTS_1000( |
| 543 "GPU.DirectComposition.FramesSinceColorSpaceChange", |
| 544 frames_since_color_space_change_); |
| 545 } |
| 546 |
| 547 frames_since_color_space_change_ = 0; |
| 548 |
| 549 is_yuy2_swapchain_ = false; |
| 479 // The composition surface handle isn't actually used, but | 550 // The composition surface handle isn't actually used, but |
| 480 // CreateSwapChainForComposition can't create YUY2 swapchains. | 551 // CreateSwapChainForComposition can't create YUY2 swapchains. |
| 481 HRESULT hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( | 552 HRESULT hr = E_FAIL; |
| 482 d3d11_device_.get(), swap_chain_handle_.Get(), &desc, nullptr, | 553 if (yuy2) { |
| 483 swap_chain_.Receive()); | 554 hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( |
| 555 d3d11_device_.get(), swap_chain_handle_.Get(), &desc, nullptr, |
| 556 swap_chain_.Receive()); |
| 557 is_yuy2_swapchain_ = SUCCEEDED(hr); |
| 558 failed_to_create_yuy2_swapchain_ = !is_yuy2_swapchain_; |
| 559 } |
| 484 | 560 |
| 485 if (FAILED(hr)) { | 561 if (!is_yuy2_swapchain_) { |
| 486 // This should not be hit in production but is a simple fallback for | 562 if (yuy2) { |
| 487 // testing on systems without YUY2 swapchain support. | 563 DLOG(ERROR) << "YUY2 creation failed with " << std::hex << hr |
| 488 DLOG(ERROR) << "YUY2 creation failed with " << std::hex << hr | 564 << ". Falling back to BGRA"; |
| 489 << ". Falling back to BGRA"; | 565 } |
| 490 is_yuy2_swapchain_ = false; | |
| 491 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; | 566 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; |
| 492 desc.Flags = 0; | 567 desc.Flags = 0; |
| 493 hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( | 568 hr = media_factory->CreateSwapChainForCompositionSurfaceHandle( |
| 494 d3d11_device_.get(), swap_chain_handle_.Get(), &desc, nullptr, | 569 d3d11_device_.get(), swap_chain_handle_.Get(), &desc, nullptr, |
| 495 swap_chain_.Receive()); | 570 swap_chain_.Receive()); |
| 496 CHECK(SUCCEEDED(hr)); | 571 CHECK(SUCCEEDED(hr)); |
| 497 } | 572 } |
| 498 UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.SwapchainFormat", | 573 UMA_HISTOGRAM_BOOLEAN("GPU.DirectComposition.SwapchainFormat", |
| 499 is_yuy2_swapchain_); | 574 is_yuy2_swapchain_); |
| 500 out_view_.Reset(); | 575 out_view_.Reset(); |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { | 1136 DirectCompositionSurfaceWin::GetWindowTaskRunnerForTesting() { |
| 1062 return child_window_.GetTaskRunnerForTesting(); | 1137 return child_window_.GetTaskRunnerForTesting(); |
| 1063 } | 1138 } |
| 1064 | 1139 |
| 1065 base::win::ScopedComPtr<IDXGISwapChain1> | 1140 base::win::ScopedComPtr<IDXGISwapChain1> |
| 1066 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { | 1141 DirectCompositionSurfaceWin::GetLayerSwapChainForTesting(size_t index) const { |
| 1067 return layer_tree_->GetLayerSwapChainForTesting(index); | 1142 return layer_tree_->GetLayerSwapChainForTesting(index); |
| 1068 } | 1143 } |
| 1069 | 1144 |
| 1070 } // namespace gpu | 1145 } // namespace gpu |
| OLD | NEW |