Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: ui/surface/accelerated_surface_win.cc

Issue 10386185: Add trace events to measure GPU process startup timing and time to first present. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/gl/gl_surface.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/surface/accelerated_surface_win.h" 5 #include "ui/surface/accelerated_surface_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <algorithm> 8 #include <algorithm>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 base::LazyInstance<AcceleratedPresenterMap> 154 base::LazyInstance<AcceleratedPresenterMap>
155 g_accelerated_presenter_map = LAZY_INSTANCE_INITIALIZER; 155 g_accelerated_presenter_map = LAZY_INSTANCE_INITIALIZER;
156 156
157 PresentThread::PresentThread(const char* name) : base::Thread(name) { 157 PresentThread::PresentThread(const char* name) : base::Thread(name) {
158 } 158 }
159 159
160 void PresentThread::InitDevice() { 160 void PresentThread::InitDevice() {
161 if (device_) 161 if (device_)
162 return; 162 return;
163 163
164 TRACE_EVENT0("surface", "PresentThread::Init"); 164 TRACE_EVENT0("gpu", "PresentThread::Init");
165 d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL)); 165 d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL));
166 ResetDevice(); 166 ResetDevice();
167 } 167 }
168 168
169 void PresentThread::ResetDevice() { 169 void PresentThread::ResetDevice() {
170 TRACE_EVENT0("surface", "PresentThread::ResetDevice"); 170 TRACE_EVENT0("gpu", "PresentThread::ResetDevice");
171 171
172 // This will crash some Intel drivers but we can't render anything without 172 // This will crash some Intel drivers but we can't render anything without
173 // reseting the device, which would be disappointing. 173 // reseting the device, which would be disappointing.
174 query_ = NULL; 174 query_ = NULL;
175 device_ = NULL; 175 device_ = NULL;
176 176
177 Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>( 177 Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>(
178 d3d_module_.GetFunctionPointer(kCreate3D9DeviceExName)); 178 d3d_module_.GetFunctionPointer(kCreate3D9DeviceExName));
179 if (!create_func) 179 if (!create_func)
180 return; 180 return;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 present_thread_->message_loop()->PostTask( 305 present_thread_->message_loop()->PostTask(
306 FROM_HERE, 306 FROM_HERE,
307 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, 307 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge,
308 this, 308 this,
309 size, 309 size,
310 surface_handle, 310 surface_handle,
311 completion_task)); 311 completion_task));
312 } 312 }
313 313
314 bool AcceleratedPresenter::Present() { 314 bool AcceleratedPresenter::Present() {
315 TRACE_EVENT0("surface", "Present"); 315 TRACE_EVENT0("gpu", "Present");
316 316
317 bool result; 317 bool result;
318 318
319 present_thread_->message_loop()->PostTask( 319 present_thread_->message_loop()->PostTask(
320 FROM_HERE, 320 FROM_HERE,
321 base::Bind(&AcceleratedPresenter::DoPresent, 321 base::Bind(&AcceleratedPresenter::DoPresent,
322 this, 322 this,
323 &result)); 323 &result));
324 // http://crbug.com/125391 324 // http://crbug.com/125391
325 base::ThreadRestrictions::ScopedAllowWait allow_wait; 325 base::ThreadRestrictions::ScopedAllowWait allow_wait;
326 event_.Wait(); 326 event_.Wait();
327 return result; 327 return result;
328 } 328 }
329 329
330 void AcceleratedPresenter::DoPresent(bool* result) 330 void AcceleratedPresenter::DoPresent(bool* result)
331 { 331 {
332 *result = DoRealPresent(); 332 *result = DoRealPresent();
333 event_.Signal(); 333 event_.Signal();
334 } 334 }
335 335
336 bool AcceleratedPresenter::DoRealPresent() 336 bool AcceleratedPresenter::DoRealPresent()
337 { 337 {
338 TRACE_EVENT0("surface", "DoRealPresent"); 338 TRACE_EVENT0("gpu", "DoRealPresent");
339 HRESULT hr; 339 HRESULT hr;
340 340
341 base::AutoLock locked(lock_); 341 base::AutoLock locked(lock_);
342 342
343 // Signal the caller to recomposite if the presenter has been suspended or no 343 // Signal the caller to recomposite if the presenter has been suspended or no
344 // surface has ever been presented. 344 // surface has ever been presented.
345 if (!swap_chain_) 345 if (!swap_chain_)
346 return false; 346 return false;
347 347
348 // If invalidated, do nothing. The window is gone. 348 // If invalidated, do nothing. The window is gone.
349 if (!window_) 349 if (!window_)
350 return true; 350 return true;
351 351
352 RECT rect = { 352 RECT rect = {
353 0, 0, 353 0, 0,
354 size_.width(), size_.height() 354 size_.width(), size_.height()
355 }; 355 };
356 356
357 { 357 {
358 TRACE_EVENT0("surface", "PresentEx"); 358 TRACE_EVENT0("gpu", "PresentEx");
359 hr = swap_chain_->Present(&rect, 359 hr = swap_chain_->Present(&rect,
360 &rect, 360 &rect,
361 window_, 361 window_,
362 NULL, 362 NULL,
363 D3DPRESENT_INTERVAL_IMMEDIATE); 363 D3DPRESENT_INTERVAL_IMMEDIATE);
364 if (FAILED(hr)) 364 if (FAILED(hr))
365 return false; 365 return false;
366 } 366 }
367 367
368 return true; 368 return true;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 switches::kGpuSwapDelay).c_str(), &delay); 502 switches::kGpuSwapDelay).c_str(), &delay);
503 } 503 }
504 return base::TimeDelta::FromMilliseconds(delay); 504 return base::TimeDelta::FromMilliseconds(delay);
505 } 505 }
506 506
507 void AcceleratedPresenter::DoPresentAndAcknowledge( 507 void AcceleratedPresenter::DoPresentAndAcknowledge(
508 const gfx::Size& size, 508 const gfx::Size& size,
509 int64 surface_handle, 509 int64 surface_handle,
510 const base::Callback<void(bool)>& completion_task) { 510 const base::Callback<void(bool)>& completion_task) {
511 TRACE_EVENT1( 511 TRACE_EVENT1(
512 "surface", "DoPresentAndAcknowledge", "surface_handle", surface_handle); 512 "gpu", "DoPresentAndAcknowledge", "surface_handle", surface_handle);
513 513
514 HRESULT hr; 514 HRESULT hr;
515 515
516 base::AutoLock locked(lock_); 516 base::AutoLock locked(lock_);
517 517
518 // Initialize the device lazily since calling Direct3D can crash bots. 518 // Initialize the device lazily since calling Direct3D can crash bots.
519 present_thread_->InitDevice(); 519 present_thread_->InitDevice();
520 520
521 if (!present_thread_->device()) { 521 if (!present_thread_->device()) {
522 if (!completion_task.is_null()) 522 if (!completion_task.is_null())
(...skipping 12 matching lines...) Expand all
535 // Round up size so the swap chain is not continuously resized with the 535 // Round up size so the swap chain is not continuously resized with the
536 // surface, which could lead to memory fragmentation. 536 // surface, which could lead to memory fragmentation.
537 const int kRound = 64; 537 const int kRound = 64;
538 gfx::Size quantized_size( 538 gfx::Size quantized_size(
539 std::max(1, (size.width() + kRound - 1) / kRound * kRound), 539 std::max(1, (size.width() + kRound - 1) / kRound * kRound),
540 std::max(1, (size.height() + kRound - 1) / kRound * kRound)); 540 std::max(1, (size.height() + kRound - 1) / kRound * kRound));
541 541
542 // Ensure the swap chain exists and is the same size (rounded up) as the 542 // Ensure the swap chain exists and is the same size (rounded up) as the
543 // surface to be presented. 543 // surface to be presented.
544 if (!swap_chain_ || size_ != quantized_size) { 544 if (!swap_chain_ || size_ != quantized_size) {
545 TRACE_EVENT0("surface", "CreateAdditionalSwapChain"); 545 TRACE_EVENT0("gpu", "CreateAdditionalSwapChain");
546 size_ = quantized_size; 546 size_ = quantized_size;
547 547
548 D3DPRESENT_PARAMETERS parameters = { 0 }; 548 D3DPRESENT_PARAMETERS parameters = { 0 };
549 parameters.BackBufferWidth = quantized_size.width(); 549 parameters.BackBufferWidth = quantized_size.width();
550 parameters.BackBufferHeight = quantized_size.height(); 550 parameters.BackBufferHeight = quantized_size.height();
551 parameters.BackBufferCount = 1; 551 parameters.BackBufferCount = 1;
552 parameters.BackBufferFormat = D3DFMT_A8R8G8B8; 552 parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
553 parameters.hDeviceWindow = GetShellWindow(); 553 parameters.hDeviceWindow = GetShellWindow();
554 parameters.Windowed = TRUE; 554 parameters.Windowed = TRUE;
555 parameters.Flags = 0; 555 parameters.Flags = 0;
556 parameters.PresentationInterval = GetPresentationInterval(); 556 parameters.PresentationInterval = GetPresentationInterval();
557 parameters.SwapEffect = D3DSWAPEFFECT_COPY; 557 parameters.SwapEffect = D3DSWAPEFFECT_COPY;
558 558
559 swap_chain_ = NULL; 559 swap_chain_ = NULL;
560 HRESULT hr = present_thread_->device()->CreateAdditionalSwapChain( 560 HRESULT hr = present_thread_->device()->CreateAdditionalSwapChain(
561 &parameters, 561 &parameters,
562 swap_chain_.Receive()); 562 swap_chain_.Receive());
563 if (FAILED(hr)) 563 if (FAILED(hr))
564 return; 564 return;
565 } 565 }
566 566
567 if (!source_texture_.get()) { 567 if (!source_texture_.get()) {
568 TRACE_EVENT0("surface", "CreateTexture"); 568 TRACE_EVENT0("gpu", "CreateTexture");
569 HANDLE handle = reinterpret_cast<HANDLE>(surface_handle); 569 HANDLE handle = reinterpret_cast<HANDLE>(surface_handle);
570 hr = present_thread_->device()->CreateTexture(size.width(), 570 hr = present_thread_->device()->CreateTexture(size.width(),
571 size.height(), 571 size.height(),
572 1, 572 1,
573 D3DUSAGE_RENDERTARGET, 573 D3DUSAGE_RENDERTARGET,
574 D3DFMT_A8R8G8B8, 574 D3DFMT_A8R8G8B8,
575 D3DPOOL_DEFAULT, 575 D3DPOOL_DEFAULT,
576 source_texture_.Receive(), 576 source_texture_.Receive(),
577 &handle); 577 &handle);
578 if (FAILED(hr)) 578 if (FAILED(hr))
(...skipping 11 matching lines...) Expand all
590 dest_surface.Receive()); 590 dest_surface.Receive());
591 if (FAILED(hr)) 591 if (FAILED(hr))
592 return; 592 return;
593 593
594 RECT rect = { 594 RECT rect = {
595 0, 0, 595 0, 0,
596 size.width(), size.height() 596 size.width(), size.height()
597 }; 597 };
598 598
599 { 599 {
600 TRACE_EVENT0("surface", "StretchRect"); 600 TRACE_EVENT0("gpu", "StretchRect");
601 hr = present_thread_->device()->StretchRect(source_surface, 601 hr = present_thread_->device()->StretchRect(source_surface,
602 &rect, 602 &rect,
603 dest_surface, 603 dest_surface,
604 &rect, 604 &rect,
605 D3DTEXF_NONE); 605 D3DTEXF_NONE);
606 if (FAILED(hr)) 606 if (FAILED(hr))
607 return; 607 return;
608 } 608 }
609 609
610 hr = present_thread_->query()->Issue(D3DISSUE_END); 610 hr = present_thread_->query()->Issue(D3DISSUE_END);
611 if (FAILED(hr)) 611 if (FAILED(hr))
612 return; 612 return;
613 613
614 // Flush so the StretchRect can be processed by the GPU while the window is 614 // Flush so the StretchRect can be processed by the GPU while the window is
615 // being resized. 615 // being resized.
616 present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); 616 present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH);
617 617
618 ::SetWindowPos( 618 ::SetWindowPos(
619 window_, 619 window_,
620 NULL, 620 NULL,
621 0, 0, 621 0, 0,
622 size.width(), size.height(), 622 size.width(), size.height(),
623 SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE |SWP_NOOWNERZORDER | 623 SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE |SWP_NOOWNERZORDER |
624 SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOSENDCHANGING | 624 SWP_NOREDRAW | SWP_NOSENDCHANGING | SWP_NOSENDCHANGING |
625 SWP_ASYNCWINDOWPOS | SWP_NOZORDER); 625 SWP_ASYNCWINDOWPOS | SWP_NOZORDER);
626 626
627 // Wait for the StretchRect to complete before notifying the GPU process 627 // Wait for the StretchRect to complete before notifying the GPU process
628 // that it is safe to write to its backing store again. 628 // that it is safe to write to its backing store again.
629 { 629 {
630 TRACE_EVENT0("surface", "spin"); 630 TRACE_EVENT0("gpu", "spin");
631 do { 631 do {
632 hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); 632 hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH);
633 633
634 if (hr == S_FALSE) 634 if (hr == S_FALSE)
635 Sleep(1); 635 Sleep(1);
636 } while (hr == S_FALSE); 636 } while (hr == S_FALSE);
637 } 637 }
638 638
639 static const base::TimeDelta swap_delay = GetSwapDelay(); 639 static const base::TimeDelta swap_delay = GetSwapDelay();
640 if (swap_delay.ToInternalValue()) 640 if (swap_delay.ToInternalValue())
641 base::PlatformThread::Sleep(swap_delay); 641 base::PlatformThread::Sleep(swap_delay);
642 642
643 { 643 {
644 TRACE_EVENT0("surface", "Present"); 644 TRACE_EVENT0("gpu", "Present");
645 hr = swap_chain_->Present(&rect, &rect, window_, NULL, 0); 645 hr = swap_chain_->Present(&rect, &rect, window_, NULL, 0);
646 if (FAILED(hr) && 646 if (FAILED(hr) &&
647 FAILED(present_thread_->device()->CheckDeviceState(window_))) { 647 FAILED(present_thread_->device()->CheckDeviceState(window_))) {
648 present_thread_->ResetDevice(); 648 present_thread_->ResetDevice();
649 } 649 }
650 } 650 }
651 } 651 }
652 652
653 void AcceleratedPresenter::DoSuspend() { 653 void AcceleratedPresenter::DoSuspend() {
654 base::AutoLock locked(lock_); 654 base::AutoLock locked(lock_);
(...skipping 19 matching lines...) Expand all
674 return presenter_->Present(); 674 return presenter_->Present();
675 } 675 }
676 676
677 bool AcceleratedSurface::CopyTo(const gfx::Size& size, void* buf) { 677 bool AcceleratedSurface::CopyTo(const gfx::Size& size, void* buf) {
678 return presenter_->CopyTo(size, buf); 678 return presenter_->CopyTo(size, buf);
679 } 679 }
680 680
681 void AcceleratedSurface::Suspend() { 681 void AcceleratedSurface::Suspend() {
682 presenter_->Suspend(); 682 presenter_->Suspend();
683 } 683 }
OLDNEW
« no previous file with comments | « ui/gl/gl_surface.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698