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

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

Issue 11753031: Revert 175152 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 11 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
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 <dwmapi.h> 7 #include <dwmapi.h>
8 #include <windows.h> 8 #include <windows.h>
9 #include <algorithm> 9 #include <algorithm>
10 10
11 #include "accelerated_surface_win_hlsl_compiled.h"
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
13 #include "base/callback.h" 14 #include "base/callback.h"
14 #include "base/command_line.h" 15 #include "base/command_line.h"
15 #include "base/debug/trace_event.h" 16 #include "base/debug/trace_event.h"
16 #include "base/file_path.h" 17 #include "base/file_path.h"
17 #include "base/lazy_instance.h" 18 #include "base/lazy_instance.h"
18 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
19 #include "base/message_loop_proxy.h" 20 #include "base/message_loop_proxy.h"
20 #include "base/scoped_native_library.h" 21 #include "base/scoped_native_library.h"
21 #include "base/string_number_conversions.h" 22 #include "base/string_number_conversions.h"
22 #include "base/stringprintf.h" 23 #include "base/stringprintf.h"
23 #include "base/synchronization/waitable_event.h" 24 #include "base/synchronization/waitable_event.h"
24 #include "base/threading/thread.h" 25 #include "base/threading/thread.h"
25 #include "base/threading/thread_restrictions.h" 26 #include "base/threading/thread_restrictions.h"
26 #include "base/time.h" 27 #include "base/time.h"
27 #include "base/tracked_objects.h" 28 #include "base/tracked_objects.h"
28 #include "base/win/wrapped_window_proc.h" 29 #include "base/win/wrapped_window_proc.h"
29 #include "ui/base/win/hwnd_util.h" 30 #include "ui/base/win/hwnd_util.h"
30 #include "ui/gfx/rect.h" 31 #include "ui/gfx/rect.h"
31 #include "ui/gl/gl_switches.h" 32 #include "ui/gl/gl_switches.h"
32 #include "ui/surface/accelerated_surface_transformer_win.h"
33 #include "ui/surface/d3d9_utils_win.h"
34 33
35 namespace d3d_utils = ui_surface_d3d9_utils; 34
35 using ui_surface::AcceleratedSurfaceWinHLSL::kVsOneTexture;
36 using ui_surface::AcceleratedSurfaceWinHLSL::kPsOneTexture;
37
36 38
37 namespace { 39 namespace {
38 40
41 typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT sdk_version,
42 IDirect3D9Ex **d3d);
43
44 const wchar_t kD3D9ModuleName[] = L"d3d9.dll";
45 const char kCreate3D9DeviceExName[] = "Direct3DCreate9Ex";
46
39 const char kUseOcclusionQuery[] = "use-occlusion-query"; 47 const char kUseOcclusionQuery[] = "use-occlusion-query";
40 48
49 struct Vertex {
50 float x, y, z, w;
51 float u, v;
52 };
53
54 const static D3DVERTEXELEMENT9 g_vertexElements[] = {
55 { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0 },
56 { 0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 },
57 D3DDECL_END()
58 };
59
41 UINT GetPresentationInterval() { 60 UINT GetPresentationInterval() {
42 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) 61 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync))
43 return D3DPRESENT_INTERVAL_IMMEDIATE; 62 return D3DPRESENT_INTERVAL_IMMEDIATE;
44 else 63 else
45 return D3DPRESENT_INTERVAL_ONE; 64 return D3DPRESENT_INTERVAL_ONE;
46 } 65 }
47 66
48 bool UsingOcclusionQuery() { 67 bool UsingOcclusionQuery() {
49 return CommandLine::ForCurrentProcess()->HasSwitch(kUseOcclusionQuery); 68 return CommandLine::ForCurrentProcess()->HasSwitch(kUseOcclusionQuery);
50 } 69 }
51 70
71 // Calculate the number necessary to transform |src_subrect| into |dst_size|
72 // by repeating downsampling of the image of |src_subrect| by a factor no more
73 // than 2.
74 int GetResampleCount(const gfx::Rect& src_subrect,
75 const gfx::Size& dst_size,
76 const gfx::Size& back_buffer_size) {
77 // At least one copy is required, since the back buffer itself is not
78 // lockable.
79 int min_resample_count = 1;
80 int width_count = 0;
81 int width = src_subrect.width();
82 while (width > dst_size.width()) {
83 ++width_count;
84 width >>= 1;
85 }
86 int height_count = 0;
87 int height = src_subrect.height();
88 while (height > dst_size.height()) {
89 ++height_count;
90 height >>= 1;
91 }
92 return std::max(std::max(width_count, height_count),
93 min_resample_count);
94 }
95
96 // Returns half the size of |size| no smaller than |min_size|.
97 gfx::Size GetHalfSizeNoLessThan(const gfx::Size& size,
98 const gfx::Size& min_size) {
99 return gfx::Size(std::max(min_size.width(), size.width() / 2),
100 std::max(min_size.height(), size.height() / 2));
101 }
102
103 bool CreateTemporarySurface(IDirect3DDevice9* device,
104 const gfx::Size& size,
105 IDirect3DSurface9** surface) {
106 HRESULT hr = device->CreateRenderTarget(
107 size.width(),
108 size.height(),
109 D3DFMT_A8R8G8B8,
110 D3DMULTISAMPLE_NONE,
111 0,
112 TRUE,
113 surface,
114 NULL);
115 return SUCCEEDED(hr);
116 }
117
52 } // namespace 118 } // namespace
53 119
54 // A PresentThread is a thread that is dedicated to presenting surfaces to a 120 // A PresentThread is a thread that is dedicated to presenting surfaces to a
55 // window. It owns a Direct3D device and a Direct3D query for this purpose. 121 // window. It owns a Direct3D device and a Direct3D query for this purpose.
56 class PresentThread : public base::Thread, 122 class PresentThread : public base::Thread,
57 public base::RefCountedThreadSafe<PresentThread> { 123 public base::RefCountedThreadSafe<PresentThread> {
58 public: 124 public:
59 explicit PresentThread(const char* name); 125 explicit PresentThread(const char* name);
60 126
61 IDirect3DDevice9Ex* device() { return device_.get(); } 127 IDirect3DDevice9Ex* device() { return device_.get(); }
62 IDirect3DQuery9* query() { return query_.get(); } 128 IDirect3DQuery9* query() { return query_.get(); }
63 AcceleratedSurfaceTransformer* surface_transformer() {
64 return &surface_transformer_;
65 }
66 129
67 void InitDevice(); 130 void InitDevice();
68 void ResetDevice(); 131 void ResetDevice();
69 132
70 protected: 133 protected:
71 virtual void Init(); 134 virtual void Init();
72 virtual void CleanUp(); 135 virtual void CleanUp();
73 136
74 private: 137 private:
75 friend class base::RefCountedThreadSafe<PresentThread>; 138 friend class base::RefCountedThreadSafe<PresentThread>;
76 139
77 ~PresentThread(); 140 ~PresentThread();
78 141
79 base::ScopedNativeLibrary d3d_module_; 142 base::ScopedNativeLibrary d3d_module_;
80 base::win::ScopedComPtr<IDirect3DDevice9Ex> device_; 143 base::win::ScopedComPtr<IDirect3DDevice9Ex> device_;
144
81 // This query is used to wait until a certain amount of progress has been 145 // This query is used to wait until a certain amount of progress has been
82 // made by the GPU and it is safe for the producer to modify its shared 146 // made by the GPU and it is safe for the producer to modify its shared
83 // texture again. 147 // texture again.
84 base::win::ScopedComPtr<IDirect3DQuery9> query_; 148 base::win::ScopedComPtr<IDirect3DQuery9> query_;
85 AcceleratedSurfaceTransformer surface_transformer_;
86 149
87 DISALLOW_COPY_AND_ASSIGN(PresentThread); 150 DISALLOW_COPY_AND_ASSIGN(PresentThread);
88 }; 151 };
89 152
90 // There is a fixed sized pool of PresentThreads and therefore the maximum 153 // There is a fixed sized pool of PresentThreads and therefore the maximum
91 // number of Direct3D devices owned by those threads is bounded. 154 // number of Direct3D devices owned by those threads is bounded.
92 class PresentThreadPool { 155 class PresentThreadPool {
93 public: 156 public:
94 static const int kNumPresentThreads = 4; 157 static const int kNumPresentThreads = 4;
95 158
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 g_accelerated_presenter_map = LAZY_INSTANCE_INITIALIZER; 191 g_accelerated_presenter_map = LAZY_INSTANCE_INITIALIZER;
129 192
130 PresentThread::PresentThread(const char* name) : base::Thread(name) { 193 PresentThread::PresentThread(const char* name) : base::Thread(name) {
131 } 194 }
132 195
133 void PresentThread::InitDevice() { 196 void PresentThread::InitDevice() {
134 if (device_) 197 if (device_)
135 return; 198 return;
136 199
137 TRACE_EVENT0("gpu", "PresentThread::Init"); 200 TRACE_EVENT0("gpu", "PresentThread::Init");
138 d3d_utils::LoadD3D9(&d3d_module_); 201 d3d_module_.Reset(base::LoadNativeLibrary(FilePath(kD3D9ModuleName), NULL));
139 ResetDevice(); 202 ResetDevice();
140 } 203 }
141 204
142 void PresentThread::ResetDevice() { 205 void PresentThread::ResetDevice() {
143 TRACE_EVENT0("gpu", "PresentThread::ResetDevice"); 206 TRACE_EVENT0("gpu", "PresentThread::ResetDevice");
144 207
145 // This will crash some Intel drivers but we can't render anything without 208 // This will crash some Intel drivers but we can't render anything without
146 // reseting the device, which would be disappointing. 209 // reseting the device, which would be disappointing.
147 query_ = NULL; 210 query_ = NULL;
148 device_ = NULL; 211 device_ = NULL;
149 212
150 if (!d3d_utils::CreateDevice(d3d_module_, 213 Direct3DCreate9ExFunc create_func = reinterpret_cast<Direct3DCreate9ExFunc>(
151 D3DDEVTYPE_HAL, 214 d3d_module_.GetFunctionPointer(kCreate3D9DeviceExName));
152 GetPresentationInterval(), 215 if (!create_func)
153 device_.Receive())) {
154 return; 216 return;
155 } 217
218 base::win::ScopedComPtr<IDirect3D9Ex> d3d;
219 HRESULT hr = create_func(D3D_SDK_VERSION, d3d.Receive());
220 if (FAILED(hr))
221 return;
222
223 // Any old window will do to create the device. In practice the window to
224 // present to is an argument to IDirect3DDevice9::Present.
225 HWND window = GetShellWindow();
226
227 D3DPRESENT_PARAMETERS parameters = { 0 };
228 parameters.BackBufferWidth = 1;
229 parameters.BackBufferHeight = 1;
230 parameters.BackBufferCount = 1;
231 parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
232 parameters.hDeviceWindow = window;
233 parameters.Windowed = TRUE;
234 parameters.Flags = 0;
235 parameters.PresentationInterval = GetPresentationInterval();
236 parameters.SwapEffect = D3DSWAPEFFECT_COPY;
237
238 hr = d3d->CreateDeviceEx(
239 D3DADAPTER_DEFAULT,
240 D3DDEVTYPE_HAL,
241 window,
242 D3DCREATE_FPU_PRESERVE | D3DCREATE_SOFTWARE_VERTEXPROCESSING |
243 D3DCREATE_DISABLE_PSGP_THREADING | D3DCREATE_MULTITHREADED,
244 &parameters,
245 NULL,
246 device_.Receive());
247 if (FAILED(hr))
248 return;
156 249
157 if (UsingOcclusionQuery()) { 250 if (UsingOcclusionQuery()) {
158 HRESULT hr = device_->CreateQuery(D3DQUERYTYPE_OCCLUSION, query_.Receive()); 251 hr = device_->CreateQuery(D3DQUERYTYPE_OCCLUSION, query_.Receive());
159 if (FAILED(hr)) { 252 if (FAILED(hr)) {
160 device_ = NULL; 253 device_ = NULL;
161 return; 254 return;
162 } 255 }
163 } else { 256 } else {
164 HRESULT hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); 257 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive());
165 if (FAILED(hr)) { 258 if (FAILED(hr)) {
166 device_ = NULL; 259 device_ = NULL;
167 return; 260 return;
168 } 261 }
169 } 262 }
170 263
171 if (!surface_transformer_.Init(device_)) { 264 base::win::ScopedComPtr<IDirect3DVertexShader9> vertex_shader;
265 hr = device_->CreateVertexShader(
266 reinterpret_cast<const DWORD*>(kVsOneTexture),
267 vertex_shader.Receive());
268 if (FAILED(hr)) {
269 device_ = NULL;
172 query_ = NULL; 270 query_ = NULL;
173 device_ = NULL;
174 return; 271 return;
175 } 272 }
273
274 device_->SetVertexShader(vertex_shader);
275
276 base::win::ScopedComPtr<IDirect3DPixelShader9> pixel_shader;
277 hr = device_->CreatePixelShader(
278 reinterpret_cast<const DWORD*>(kPsOneTexture),
279 pixel_shader.Receive());
280
281 if (FAILED(hr)) {
282 device_ = NULL;
283 query_ = NULL;
284 return;
285 }
286
287 device_->SetPixelShader(pixel_shader);
288
289 base::win::ScopedComPtr<IDirect3DVertexDeclaration9> vertex_declaration;
290 hr = device_->CreateVertexDeclaration(g_vertexElements,
291 vertex_declaration.Receive());
292 if (FAILED(hr)) {
293 device_ = NULL;
294 query_ = NULL;
295 return;
296 }
297
298 device_->SetVertexDeclaration(vertex_declaration);
176 } 299 }
177 300
178 void PresentThread::Init() { 301 void PresentThread::Init() {
179 TRACE_EVENT0("gpu", "Initialize thread"); 302 TRACE_EVENT0("gpu", "Initialize thread");
180 } 303 }
181 304
182 void PresentThread::CleanUp() { 305 void PresentThread::CleanUp() {
183 // The D3D device and query are leaked because destroying the associated D3D 306 // The D3D device and query are leaked because destroying the associated D3D
184 // query crashes some Intel drivers. 307 // query crashes some Intel drivers.
185 surface_transformer_.DetachAll();
186 device_.Detach(); 308 device_.Detach();
187 query_.Detach(); 309 query_.Detach();
188 } 310 }
189 311
190 PresentThread::~PresentThread() { 312 PresentThread::~PresentThread() {
191 Stop(); 313 Stop();
192 } 314 }
193 315
194 PresentThreadPool::PresentThreadPool() : next_thread_(0) { 316 PresentThreadPool::PresentThreadPool() : next_thread_(0) {
195 } 317 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 return it->second; 375 return it->second;
254 } 376 }
255 377
256 AcceleratedPresenter::AcceleratedPresenter(gfx::PluginWindowHandle window) 378 AcceleratedPresenter::AcceleratedPresenter(gfx::PluginWindowHandle window)
257 : present_thread_(g_present_thread_pool.Pointer()->NextThread()), 379 : present_thread_(g_present_thread_pool.Pointer()->NextThread()),
258 window_(window), 380 window_(window),
259 event_(false, false), 381 event_(false, false),
260 hidden_(true) { 382 hidden_(true) {
261 } 383 }
262 384
263 // static
264 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( 385 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow(
265 gfx::PluginWindowHandle window) { 386 gfx::PluginWindowHandle window) {
266 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); 387 return g_accelerated_presenter_map.Pointer()->GetPresenter(window);
267 } 388 }
268 389
269 void AcceleratedPresenter::AsyncPresentAndAcknowledge( 390 void AcceleratedPresenter::AsyncPresentAndAcknowledge(
270 const gfx::Size& size, 391 const gfx::Size& size,
271 int64 surface_handle, 392 int64 surface_handle,
272 const CopyCompletionTask& copy_completion_task, 393 const CopyCompletionTask& copy_completion_task,
273 const PresentCompletionTask& present_completion_task) { 394 const PresentCompletionTask& present_completion_task) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 "width", dst_size.width(), 463 "width", dst_size.width(),
343 "height", dst_size.height()); 464 "height", dst_size.height());
344 465
345 base::AutoLock locked(lock_); 466 base::AutoLock locked(lock_);
346 467
347 TRACE_EVENT0("gpu", "CopyTo_locked"); 468 TRACE_EVENT0("gpu", "CopyTo_locked");
348 469
349 if (!swap_chain_) 470 if (!swap_chain_)
350 return false; 471 return false;
351 472
352 AcceleratedSurfaceTransformer* gpu_ops =
353 present_thread_->surface_transformer();
354
355 base::win::ScopedComPtr<IDirect3DSurface9> back_buffer; 473 base::win::ScopedComPtr<IDirect3DSurface9> back_buffer;
356 HRESULT hr = swap_chain_->GetBackBuffer(0, 474 HRESULT hr = swap_chain_->GetBackBuffer(0,
357 D3DBACKBUFFER_TYPE_MONO, 475 D3DBACKBUFFER_TYPE_MONO,
358 back_buffer.Receive()); 476 back_buffer.Receive());
359 if (FAILED(hr)) 477 if (FAILED(hr))
360 return false; 478 return false;
361 479
362 D3DSURFACE_DESC desc; 480 D3DSURFACE_DESC desc;
363 hr = back_buffer->GetDesc(&desc); 481 hr = back_buffer->GetDesc(&desc);
364 if (FAILED(hr)) 482 if (FAILED(hr))
365 return false; 483 return false;
366 484
367 const gfx::Size back_buffer_size(desc.Width, desc.Height); 485 const gfx::Size back_buffer_size(desc.Width, desc.Height);
368 if (back_buffer_size.IsEmpty()) 486 if (back_buffer_size.IsEmpty())
369 return false; 487 return false;
370 488
371 // With window resizing, it's possible that the back buffer is smaller than 489 // With window resizing, it's possible that the back buffer is smaller than
372 // the requested src subset. Clip to the actual back buffer. 490 // the requested src subset. Clip to the actual back buffer.
373 gfx::Rect src_subrect = requested_src_subrect; 491 gfx::Rect src_subrect = requested_src_subrect;
374 src_subrect.Intersect(gfx::Rect(back_buffer_size)); 492 src_subrect.Intersect(gfx::Rect(back_buffer_size));
493
494 // Set up intermediate buffers needed for downsampling.
495 const int resample_count =
496 GetResampleCount(src_subrect, dst_size, back_buffer_size);
375 base::win::ScopedComPtr<IDirect3DSurface9> final_surface; 497 base::win::ScopedComPtr<IDirect3DSurface9> final_surface;
376 { 498 base::win::ScopedComPtr<IDirect3DSurface9> temp_buffer[2];
377 TRACE_EVENT0("gpu", "CreateTemporaryLockableSurface"); 499 if (resample_count == 0)
378 if (!d3d_utils::CreateTemporaryLockableSurface(present_thread_->device(), 500 final_surface = back_buffer;
379 dst_size, 501 if (resample_count > 0) {
380 final_surface.Receive())) { 502 TRACE_EVENT0("gpu", "CreateTemporarySurface");
503 if (!CreateTemporarySurface(present_thread_->device(),
504 dst_size,
505 final_surface.Receive()))
381 return false; 506 return false;
382 }
383 } 507 }
384 508 const gfx::Size half_size =
385 { 509 GetHalfSizeNoLessThan(src_subrect.size(), dst_size);
386 // Let the surface transformer start the resize into |final_surface|. 510 if (resample_count > 1) {
387 TRACE_EVENT0("gpu", "ResizeBilinear"); 511 TRACE_EVENT0("gpu", "CreateTemporarySurface");
388 if (!gpu_ops->ResizeBilinear(back_buffer, src_subrect, final_surface)) 512 if (!CreateTemporarySurface(present_thread_->device(),
513 half_size,
514 temp_buffer[0].Receive()))
515 return false;
516 }
517 if (resample_count > 2) {
518 TRACE_EVENT0("gpu", "CreateTemporarySurface");
519 const gfx::Size quarter_size = GetHalfSizeNoLessThan(half_size, dst_size);
520 if (!CreateTemporarySurface(present_thread_->device(),
521 quarter_size,
522 temp_buffer[1].Receive()))
389 return false; 523 return false;
390 } 524 }
391 525
526 // Repeat downsampling the surface until its size becomes identical to
527 // |dst_size|. We keep the factor of each downsampling no more than two
528 // because using a factor more than two can introduce aliasing.
529 RECT read_rect = src_subrect.ToRECT();
530 gfx::Size write_size = half_size;
531 int read_buffer_index = 1;
532 int write_buffer_index = 0;
533 for (int i = 0; i < resample_count; ++i) {
534 TRACE_EVENT0("gpu", "StretchRect");
535 base::win::ScopedComPtr<IDirect3DSurface9> read_buffer =
536 (i == 0) ? back_buffer : temp_buffer[read_buffer_index];
537 base::win::ScopedComPtr<IDirect3DSurface9> write_buffer =
538 (i == resample_count - 1) ? final_surface :
539 temp_buffer[write_buffer_index];
540 RECT write_rect = gfx::Rect(write_size).ToRECT();
541 hr = present_thread_->device()->StretchRect(read_buffer,
542 &read_rect,
543 write_buffer,
544 &write_rect,
545 D3DTEXF_LINEAR);
546 if (FAILED(hr))
547 return false;
548 read_rect = write_rect;
549 write_size = GetHalfSizeNoLessThan(write_size, dst_size);
550 std::swap(read_buffer_index, write_buffer_index);
551 }
392 D3DLOCKED_RECT locked_rect; 552 D3DLOCKED_RECT locked_rect;
393 553
394 // Empirical evidence seems to suggest that LockRect and memcpy are faster 554 // Empirical evidence seems to suggest that LockRect and memcpy are faster
395 // than would be GetRenderTargetData to an offscreen surface wrapping *buf. 555 // than would be GetRenderTargetData to an offscreen surface wrapping *buf.
396 { 556 {
397 TRACE_EVENT0("gpu", "LockRect"); 557 TRACE_EVENT0("gpu", "LockRect");
398 hr = final_surface->LockRect(&locked_rect, NULL, 558 hr = final_surface->LockRect(&locked_rect, NULL,
399 D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); 559 D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
400 if (FAILED(hr)) 560 if (FAILED(hr))
401 return false; 561 return false;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 709
550 swap_chain_ = NULL; 710 swap_chain_ = NULL;
551 HRESULT hr = present_thread_->device()->CreateAdditionalSwapChain( 711 HRESULT hr = present_thread_->device()->CreateAdditionalSwapChain(
552 &parameters, 712 &parameters,
553 swap_chain_.Receive()); 713 swap_chain_.Receive());
554 if (FAILED(hr)) 714 if (FAILED(hr))
555 return; 715 return;
556 } 716 }
557 717
558 if (!source_texture_.get()) { 718 if (!source_texture_.get()) {
559 TRACE_EVENT0("gpu", "OpenSharedTexture"); 719 TRACE_EVENT0("gpu", "CreateTexture");
560 if (!d3d_utils::OpenSharedTexture(present_thread_->device(), 720 HANDLE handle = reinterpret_cast<HANDLE>(surface_handle);
561 surface_handle, 721 hr = present_thread_->device()->CreateTexture(size.width(),
562 size, 722 size.height(),
563 source_texture_.Receive())) { 723 1,
724 D3DUSAGE_RENDERTARGET,
725 D3DFMT_A8R8G8B8,
726 D3DPOOL_DEFAULT,
727 source_texture_.Receive(),
728 &handle);
729 if (FAILED(hr))
564 return; 730 return;
565 }
566 } 731 }
567 732
568 base::win::ScopedComPtr<IDirect3DSurface9> source_surface; 733 base::win::ScopedComPtr<IDirect3DSurface9> source_surface;
569 hr = source_texture_->GetSurfaceLevel(0, source_surface.Receive()); 734 hr = source_texture_->GetSurfaceLevel(0, source_surface.Receive());
570 if (FAILED(hr)) { 735 if (FAILED(hr)) {
571 TRACE_EVENT0("gpu", "EarlyOut_NoSurfaceLevel"); 736 TRACE_EVENT0("gpu", "EarlyOut_NoSurfaceLevel");
572 return; 737 return;
573 } 738 }
574 739
575 base::win::ScopedComPtr<IDirect3DSurface9> dest_surface; 740 base::win::ScopedComPtr<IDirect3DSurface9> dest_surface;
576 hr = swap_chain_->GetBackBuffer(0, 741 hr = swap_chain_->GetBackBuffer(0,
577 D3DBACKBUFFER_TYPE_MONO, 742 D3DBACKBUFFER_TYPE_MONO,
578 dest_surface.Receive()); 743 dest_surface.Receive());
579 if (FAILED(hr)) { 744 if (FAILED(hr)) {
580 TRACE_EVENT0("gpu", "EarlyOut_NoBackbuffer"); 745 TRACE_EVENT0("gpu", "EarlyOut_NoBackbuffer");
581 return; 746 return;
582 } 747 }
583 748
584 RECT rect = { 749 RECT rect = {
585 0, 0, 750 0, 0,
586 size.width(), size.height() 751 size.width(), size.height()
587 }; 752 };
588 753
589 { 754 {
590 TRACE_EVENT0("gpu", "Copy"); 755 TRACE_EVENT0("gpu", "Copy");
591 756
757 // Use a simple pixel / vertex shader pair to render a quad that flips the
758 // source texture on the vertical axis.
759 IDirect3DSurface9 *default_render_target = NULL;
760 present_thread_->device()->GetRenderTarget(0, &default_render_target);
761
762 present_thread_->device()->SetRenderTarget(0, dest_surface);
763 present_thread_->device()->SetTexture(0, source_texture_);
764
765 D3DVIEWPORT9 viewport = {
766 0, 0,
767 size.width(), size.height(),
768 0, 1
769 };
770 present_thread_->device()->SetViewport(&viewport);
771
772 float halfPixelX = -1.0f / size.width();
773 float halfPixelY = 1.0f / size.height();
774 Vertex vertices[] = {
775 { halfPixelX - 1, halfPixelY + 1, 0.5f, 1, 0, 1 },
776 { halfPixelX + 1, halfPixelY + 1, 0.5f, 1, 1, 1 },
777 { halfPixelX + 1, halfPixelY - 1, 0.5f, 1, 1, 0 },
778 { halfPixelX - 1, halfPixelY - 1, 0.5f, 1, 0, 0 }
779 };
780
592 if (UsingOcclusionQuery()) { 781 if (UsingOcclusionQuery()) {
593 present_thread_->query()->Issue(D3DISSUE_BEGIN); 782 present_thread_->query()->Issue(D3DISSUE_BEGIN);
594 } 783 }
595 784
596 // Copy while flipping the source texture on the vertical axis. 785 present_thread_->device()->BeginScene();
597 bool result = present_thread_->surface_transformer()->CopyInverted( 786 present_thread_->device()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,
598 source_texture_, dest_surface, size); 787 2,
599 if (!result) 788 vertices,
600 return; 789 sizeof(vertices[0]));
790 present_thread_->device()->EndScene();
791
792 present_thread_->device()->SetTexture(0, NULL);
793 present_thread_->device()->SetRenderTarget(0, default_render_target);
794 default_render_target->Release();
601 } 795 }
602 796
603 hr = present_thread_->query()->Issue(D3DISSUE_END); 797 hr = present_thread_->query()->Issue(D3DISSUE_END);
604 if (FAILED(hr)) 798 if (FAILED(hr))
605 return; 799 return;
606 800
607 // Wait for the StretchRect to complete before notifying the GPU process 801 // Wait for the StretchRect to complete before notifying the GPU process
608 // that it is safe to write to its backing store again. 802 // that it is safe to write to its backing store again.
609 { 803 {
610 TRACE_EVENT0("gpu", "spin"); 804 TRACE_EVENT0("gpu", "spin");
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 presenter_->AsyncCopyTo(src_subrect, dst_size, buf, callback); 1016 presenter_->AsyncCopyTo(src_subrect, dst_size, buf, callback);
823 } 1017 }
824 1018
825 void AcceleratedSurface::Suspend() { 1019 void AcceleratedSurface::Suspend() {
826 presenter_->Suspend(); 1020 presenter_->Suspend();
827 } 1021 }
828 1022
829 void AcceleratedSurface::WasHidden() { 1023 void AcceleratedSurface::WasHidden() {
830 presenter_->WasHidden(); 1024 presenter_->WasHidden();
831 } 1025 }
OLDNEW
« no previous file with comments | « ui/surface/accelerated_surface_transformer_win_unittest.cc ('k') | ui/surface/accelerated_surface_win.hlsl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698