Index: ui/gfx/surface/accelerated_surface_win.cc |
=================================================================== |
--- ui/gfx/surface/accelerated_surface_win.cc (revision 126152) |
+++ ui/gfx/surface/accelerated_surface_win.cc (working copy) |
@@ -50,10 +50,10 @@ |
IDirect3DDevice9* device() { return device_.get(); } |
IDirect3DQuery9* query() { return query_.get(); } |
+ void InitDevice(); |
void ResetDevice(); |
protected: |
- virtual void Init(); |
virtual void CleanUp(); |
private: |
@@ -94,6 +94,16 @@ |
Stop(); |
} |
+void PresentThread::InitDevice() { |
+ // Initialize the device lazily since calling Direct3D can crash bots. |
vangelis
2012/03/13 22:09:37
This comment probably makes more sense at the call
apatrick_chromium
2012/03/13 22:22:02
Done.
|
+ if (device_) |
+ return; |
+ |
+ TRACE_EVENT0("surface", "PresentThread::Init"); |
+ d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL)); |
+ ResetDevice(); |
+} |
+ |
void PresentThread::ResetDevice() { |
TRACE_EVENT0("surface", "PresentThread::ResetDevice"); |
@@ -144,12 +154,6 @@ |
device_ = NULL; |
} |
-void PresentThread::Init() { |
- TRACE_EVENT0("surface", "PresentThread::Init"); |
- d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL)); |
- ResetDevice(); |
-} |
- |
void PresentThread::CleanUp() { |
// The D3D device and query are leaked because destroying the associated D3D |
// query crashes some Intel drivers. |
@@ -158,15 +162,17 @@ |
} |
PresentThreadPool::PresentThreadPool() : next_thread_(0) { |
+ // Do this in the constructor so present_threads_ is initialized before any |
+ // other thread sees it. See LazyInstance documentation. |
+ for (int i = 0; i < kNumPresentThreads; ++i) { |
+ present_threads_[i].reset(new PresentThread( |
+ base::StringPrintf("PresentThread #%d", i).c_str())); |
+ present_threads_[i]->Start(); |
+ } |
} |
PresentThread* PresentThreadPool::NextThread() { |
next_thread_ = (next_thread_ + 1) % kNumPresentThreads; |
- if (!present_threads_[next_thread_].get()) { |
- present_threads_[next_thread_].reset(new PresentThread( |
- base::StringPrintf("PresentThread #%d", next_thread_).c_str())); |
- present_threads_[next_thread_]->Start(); |
- } |
return present_threads_[next_thread_].get(); |
} |
@@ -196,7 +202,8 @@ |
base::AutoLock locked(lock_); |
- // Signal the caller to recomposite if the presenter has been suspended. |
+ // Signal the caller to recomposite if the presenter has been suspended or no |
+ // surface has ever been presented. |
if (!swap_chain_) |
return false; |
@@ -266,6 +273,16 @@ |
base::AutoLock locked(lock_); |
+ present_thread_->InitDevice(); |
+ |
+ // A surface with ID zero is presented even when shared surfaces are not in |
+ // use for synchronization purposes. In that case, just acknowledge. |
+ if (!surface_id) { |
+ if (!completion_task.is_null()) |
+ completion_task.Run(true); |
+ return; |
+ } |
+ |
if (!present_thread_->device()) { |
if (!completion_task.is_null()) |
completion_task.Run(false); |
@@ -308,13 +325,10 @@ |
return; |
} |
- HANDLE handle = reinterpret_cast<HANDLE>(surface_id); |
- if (!handle) |
- return; |
- |
base::win::ScopedComPtr<IDirect3DTexture9> source_texture; |
{ |
TRACE_EVENT0("surface", "CreateTexture"); |
+ HANDLE handle = reinterpret_cast<HANDLE>(surface_id); |
hr = present_thread_->device()->CreateTexture(size.width(), |
size.height(), |
1, |
@@ -401,16 +415,15 @@ |
swap_chain_ = NULL; |
} |
-AcceleratedSurface::AcceleratedSurface(){ |
+AcceleratedSurface::AcceleratedSurface() |
+ : presenter_(new AcceleratedPresenter) { |
} |
AcceleratedSurface::~AcceleratedSurface() { |
- if (presenter_) { |
- // Ensure that the swap chain is destroyed on the PresentThread in case |
- // there are still pending presents. |
- presenter_->Suspend(); |
- presenter_->WaitForPendingTasks(); |
- } |
+ // Ensure that the swap chain is destroyed on the PresentThread in case |
+ // there are still pending presents. |
+ presenter_->Suspend(); |
+ presenter_->WaitForPendingTasks(); |
} |
void AcceleratedSurface::AsyncPresentAndAcknowledge( |
@@ -421,9 +434,6 @@ |
if (!surface_id) |
return; |
- if (!presenter_) |
- presenter_ = new AcceleratedPresenter; |
- |
presenter_->AsyncPresentAndAcknowledge(window, |
size, |
surface_id, |
@@ -431,14 +441,10 @@ |
} |
bool AcceleratedSurface::Present(HWND window) { |
- if (presenter_) |
- return presenter_->Present(window); |
- else |
- return false; |
+ return presenter_->Present(window); |
} |
void AcceleratedSurface::Suspend() { |
- if (presenter_) |
- presenter_->Suspend(); |
+ presenter_->Suspend(); |
} |