OLD | NEW |
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/gfx/surface/accelerated_surface_win.h" | 5 #include "ui/gfx/surface/accelerated_surface_win.h" |
6 | 6 |
7 #include <d3d9.h> | 7 #include <d3d9.h> |
8 #include <windows.h> | 8 #include <windows.h> |
9 | 9 |
10 #include <list> | 10 #include <list> |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 void DoReset(); | 115 void DoReset(); |
116 void DoPresentAndAcknowledge(gfx::NativeWindow window, | 116 void DoPresentAndAcknowledge(gfx::NativeWindow window, |
117 const gfx::Size& size, | 117 const gfx::Size& size, |
118 int64 surface_id, | 118 int64 surface_id, |
119 const base::Closure& completion_task); | 119 const base::Closure& completion_task); |
120 | 120 |
121 // Immutable and accessible from any thread without the lock. | 121 // Immutable and accessible from any thread without the lock. |
122 const int thread_affinity_; | 122 const int thread_affinity_; |
123 base::ScopedNativeLibrary d3d_module_; | 123 base::ScopedNativeLibrary d3d_module_; |
124 | 124 |
| 125 // Whether the presenter is suspended and therefore unable to represent. Only |
| 126 // accessed on the UI thread so the lock is unnecessary. |
| 127 bool suspended_; |
| 128 |
125 // The size of the swap chain once any pending resizes have been processed. | 129 // The size of the swap chain once any pending resizes have been processed. |
126 // Only accessed on the UI thread so the lock is unnecessary. | 130 // Only accessed on the UI thread so the lock is unnecessary. |
127 gfx::Size pending_size_; | 131 gfx::Size pending_size_; |
128 | 132 |
129 // The current size of the swap chain. This is only accessed on the thread | 133 // The current size of the swap chain. This is only accessed on the thread |
130 // with which the surface has affinity. | 134 // with which the surface has affinity. |
131 gfx::Size size_; | 135 gfx::Size size_; |
132 | 136 |
133 // The number of pending resizes. This is accessed with atomic operations so | 137 // The number of pending resizes. This is accessed with atomic operations so |
134 // the lock is not necessary. | 138 // the lock is not necessary. |
135 base::AtomicRefCount num_pending_resizes_; | 139 base::AtomicRefCount num_pending_resizes_; |
136 | 140 |
137 // Take the lock before accessing any other state. | 141 // Take the lock before accessing any other state. |
138 base::Lock lock_; | 142 base::Lock lock_; |
139 | 143 |
140 // This device's swap chain is presented to the child window. Copy semantics | 144 // This device's swap chain is presented to the child window. Copy semantics |
141 // are used so it is possible to represent it to quickly validate the window. | 145 // are used so it is possible to represent it to quickly validate the window. |
142 base::win::ScopedComPtr<IDirect3DDevice9Ex> device_; | 146 base::win::ScopedComPtr<IDirect3DDevice9Ex> device_; |
143 | 147 |
144 // This query is used to wait until a certain amount of progress has been | 148 // This query is used to wait until a certain amount of progress has been |
145 // made by the GPU and it is safe for the producer to modify its shared | 149 // made by the GPU and it is safe for the producer to modify its shared |
146 // texture again. | 150 // texture again. |
147 base::win::ScopedComPtr<IDirect3DQuery9> query_; | 151 base::win::ScopedComPtr<IDirect3DQuery9> query_; |
148 | 152 |
149 DISALLOW_COPY_AND_ASSIGN(AcceleratedPresenter); | 153 DISALLOW_COPY_AND_ASSIGN(AcceleratedPresenter); |
150 }; | 154 }; |
151 | 155 |
152 AcceleratedPresenter::AcceleratedPresenter() | 156 AcceleratedPresenter::AcceleratedPresenter() |
153 : thread_affinity_(g_present_thread_pool.Pointer()->NextThread()), | 157 : thread_affinity_(g_present_thread_pool.Pointer()->NextThread()), |
| 158 suspended_(true), |
154 num_pending_resizes_(0) { | 159 num_pending_resizes_(0) { |
155 g_present_thread_pool.Pointer()->PostTask( | 160 g_present_thread_pool.Pointer()->PostTask( |
156 thread_affinity_, | 161 thread_affinity_, |
157 FROM_HERE, | 162 FROM_HERE, |
158 base::Bind(&AcceleratedPresenter::DoInitialize, base::Unretained(this))); | 163 base::Bind(&AcceleratedPresenter::DoInitialize, base::Unretained(this))); |
159 } | 164 } |
160 | 165 |
161 AcceleratedPresenter::~AcceleratedPresenter() { | 166 AcceleratedPresenter::~AcceleratedPresenter() { |
162 // The D3D device and query are leaked because destroying the associated D3D | 167 // The D3D device and query are leaked because destroying the associated D3D |
163 // query crashes some Intel drivers. | 168 // query crashes some Intel drivers. |
(...skipping 25 matching lines...) Expand all Loading... |
189 | 194 |
190 g_present_thread_pool.Pointer()->PostTask( | 195 g_present_thread_pool.Pointer()->PostTask( |
191 thread_affinity_, | 196 thread_affinity_, |
192 FROM_HERE, | 197 FROM_HERE, |
193 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, | 198 base::Bind(&AcceleratedPresenter::DoPresentAndAcknowledge, |
194 base::Unretained(this), | 199 base::Unretained(this), |
195 window, | 200 window, |
196 size, | 201 size, |
197 surface_id, | 202 surface_id, |
198 completion_task)); | 203 completion_task)); |
| 204 |
| 205 suspended_ = false; |
199 } | 206 } |
200 | 207 |
201 bool AcceleratedPresenter::Present(gfx::NativeWindow window) { | 208 bool AcceleratedPresenter::Present(gfx::NativeWindow window) { |
202 TRACE_EVENT0("surface", "Present"); | 209 TRACE_EVENT0("surface", "Present"); |
203 | 210 |
204 HRESULT hr; | 211 HRESULT hr; |
205 | 212 |
| 213 if (suspended_) |
| 214 return false; |
| 215 |
206 base::AutoLock locked(lock_); | 216 base::AutoLock locked(lock_); |
207 | 217 |
208 if (!device_) | 218 if (!device_) |
209 return true; | 219 return true; |
210 | 220 |
211 RECT rect; | 221 RECT rect; |
212 if (!GetClientRect(window, &rect)) | 222 if (!GetClientRect(window, &rect)) |
213 return true; | 223 return true; |
214 | 224 |
215 { | 225 { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 // in use. | 268 // in use. |
259 pending_size_ = gfx::Size(1, 1); | 269 pending_size_ = gfx::Size(1, 1); |
260 base::AtomicRefCountInc(&num_pending_resizes_); | 270 base::AtomicRefCountInc(&num_pending_resizes_); |
261 | 271 |
262 g_present_thread_pool.Pointer()->PostTask( | 272 g_present_thread_pool.Pointer()->PostTask( |
263 thread_affinity_, | 273 thread_affinity_, |
264 FROM_HERE, | 274 FROM_HERE, |
265 base::Bind(&AcceleratedPresenter::DoResize, | 275 base::Bind(&AcceleratedPresenter::DoResize, |
266 base::Unretained(this), | 276 base::Unretained(this), |
267 gfx::Size(1, 1))); | 277 gfx::Size(1, 1))); |
| 278 |
| 279 suspended_ = true; |
268 } | 280 } |
269 | 281 |
270 void AcceleratedPresenter::DoInitialize() { | 282 void AcceleratedPresenter::DoInitialize() { |
271 TRACE_EVENT0("surface", "DoInitialize"); | 283 TRACE_EVENT0("surface", "DoInitialize"); |
272 | 284 |
273 HRESULT hr; | 285 HRESULT hr; |
274 | 286 |
275 d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL)); | 287 d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL)); |
276 | 288 |
277 Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>( | 289 Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>( |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 const base::Closure& completion_task) { | 504 const base::Closure& completion_task) { |
493 presenter_->AsyncPresentAndAcknowledge(window, | 505 presenter_->AsyncPresentAndAcknowledge(window, |
494 size, | 506 size, |
495 surface_id, | 507 surface_id, |
496 completion_task); | 508 completion_task); |
497 } | 509 } |
498 | 510 |
499 bool AcceleratedSurface::Present(HWND window) { | 511 bool AcceleratedSurface::Present(HWND window) { |
500 return presenter_->Present(window); | 512 return presenter_->Present(window); |
501 } | 513 } |
| 514 |
| 515 void AcceleratedSurface::Suspend() { |
| 516 presenter_->Suspend(); |
| 517 } |
| 518 |
OLD | NEW |