diff options
Diffstat (limited to 'ui/gfx/surface')
-rw-r--r-- | ui/gfx/surface/accelerated_surface_win.cc | 59 | ||||
-rw-r--r-- | ui/gfx/surface/accelerated_surface_win.h | 11 |
2 files changed, 46 insertions, 24 deletions
diff --git a/ui/gfx/surface/accelerated_surface_win.cc b/ui/gfx/surface/accelerated_surface_win.cc index 2be4e80..50559aa 100644 --- a/ui/gfx/surface/accelerated_surface_win.cc +++ b/ui/gfx/surface/accelerated_surface_win.cc @@ -142,7 +142,7 @@ void AcceleratedSurface::AsyncPresentAndAcknowledge( completion_task)); } -void AcceleratedSurface::Present() { +bool AcceleratedSurface::Present() { TRACE_EVENT0("surface", "Present"); HRESULT hr; @@ -150,11 +150,11 @@ void AcceleratedSurface::Present() { base::AutoLock locked(lock_); if (!device_) - return; + return true; RECT rect; if (!GetClientRect(window_, &rect)) - return; + return true; { TRACE_EVENT0("surface", "PresentEx"); @@ -163,13 +163,26 @@ void AcceleratedSurface::Present() { NULL, NULL, D3DPRESENT_INTERVAL_IMMEDIATE); + + // If the device hung, force a resize to reset the device. + if (hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICEHUNG) { + base::AtomicRefCountInc(&num_pending_resizes_); + g_present_thread_pool.Pointer()->PostTask( + thread_affinity_, + FROM_HERE, + base::Bind(&AcceleratedSurface::DoReset, this)); + + // A device hang destroys the contents of the back buffer so no point in + // scheduling a present. + } + if (FAILED(hr)) - return; + return false; } hr = query_->Issue(D3DISSUE_END); if (FAILED(hr)) - return; + return true; { TRACE_EVENT0("surface", "spin"); @@ -180,6 +193,8 @@ void AcceleratedSurface::Present() { Sleep(0); } while (hr == S_FALSE); } + + return true; } void AcceleratedSurface::DoInitialize() { @@ -231,14 +246,6 @@ void AcceleratedSurface::DoInitialize() { return; } -void AcceleratedSurface::QueriesDestroyed() { - g_present_thread_pool.Pointer()->PostTask( - thread_affinity_, - FROM_HERE, - base::Bind(&AcceleratedSurface::DoDestroy, - this)); -} - void AcceleratedSurface::DoDestroy() { TRACE_EVENT0("surface", "DoDestroy"); @@ -250,6 +257,12 @@ void AcceleratedSurface::DoDestroy() { void AcceleratedSurface::DoResize(const gfx::Size& size) { TRACE_EVENT0("surface", "DoResize"); + size_ = size; + DoReset(); +} + +void AcceleratedSurface::DoReset() { + TRACE_EVENT0("surface", "DoReset"); HRESULT hr; @@ -261,8 +274,8 @@ void AcceleratedSurface::DoResize(const gfx::Size& size) { return; D3DPRESENT_PARAMETERS parameters = { 0 }; - parameters.BackBufferWidth = size.width(); - parameters.BackBufferHeight = size.height(); + parameters.BackBufferWidth = size_.width(); + parameters.BackBufferHeight = size_.height(); parameters.BackBufferCount = 1; parameters.BackBufferFormat = D3DFMT_A8R8G8B8; parameters.hDeviceWindow = window_; @@ -275,8 +288,6 @@ void AcceleratedSurface::DoResize(const gfx::Size& size) { if (FAILED(hr)) return; - size_ = size; - device_->Clear(0, NULL, D3DCLEAR_TARGET, 0xFFFFFFFF, 0, 0); } @@ -380,7 +391,17 @@ void AcceleratedSurface::DoPresentAndAcknowledge( { TRACE_EVENT0("surface", "Present"); hr = device_->Present(&rect, &rect, NULL, NULL); - if (FAILED(hr)) - return; + + // If the device hung, force a resize to reset the device. + if (hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICEHUNG) { + base::AtomicRefCountInc(&num_pending_resizes_); + g_present_thread_pool.Pointer()->PostTask( + thread_affinity_, + FROM_HERE, + base::Bind(&AcceleratedSurface::DoReset, this)); + + // A device hang destroys the contents of the back buffer so no point in + // scheduling a present. + } } } diff --git a/ui/gfx/surface/accelerated_surface_win.h b/ui/gfx/surface/accelerated_surface_win.h index b526deb..593972b 100644 --- a/ui/gfx/surface/accelerated_surface_win.h +++ b/ui/gfx/surface/accelerated_surface_win.h @@ -35,13 +35,13 @@ class SURFACE_EXPORT AcceleratedSurface const base::Closure& completion_task); // Synchronously present a frame with no acknowledgement. - void Present(); + bool Present(); private: void DoInitialize(); - void QueriesDestroyed(); void DoDestroy(); void DoResize(const gfx::Size& size); + void DoReset(); void DoPresentAndAcknowledge(const gfx::Size& size, int64 surface_id, const base::Closure& completion_task); @@ -55,6 +55,10 @@ class SURFACE_EXPORT AcceleratedSurface // Only accessed on the UI thread so the lock is unnecessary. gfx::Size pending_size_; + // The current size of the swap chain. This is only accessed on the thread + // with which the surface has affinity. + gfx::Size size_; + // The number of pending resizes. This is accessed with atomic operations so // the lock is not necessary. base::AtomicRefCount num_pending_resizes_; @@ -71,9 +75,6 @@ class SURFACE_EXPORT AcceleratedSurface // texture again. base::win::ScopedComPtr<IDirect3DQuery9> query_; - // The current size of the swap chain. - gfx::Size size_; - DISALLOW_COPY_AND_ASSIGN(AcceleratedSurface); }; |