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/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 16 matching lines...) Expand all Loading... |
27 #include "ui/base/win/hwnd_util.h" | 27 #include "ui/base/win/hwnd_util.h" |
28 #include "ui/gl/gl_switches.h" | 28 #include "ui/gl/gl_switches.h" |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT sdk_version, | 32 typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT sdk_version, |
33 IDirect3D9Ex **d3d); | 33 IDirect3D9Ex **d3d); |
34 | 34 |
35 const wchar_t kD3D9ModuleName[] = L"d3d9.dll"; | 35 const wchar_t kD3D9ModuleName[] = L"d3d9.dll"; |
36 const char kCreate3D9DeviceExName[] = "Direct3DCreate9Ex"; | 36 const char kCreate3D9DeviceExName[] = "Direct3DCreate9Ex"; |
| 37 const char kReverseImageTransportSurfaceRows[] = |
| 38 "reverse-image-transport-surface-rows"; |
| 39 |
| 40 struct Vertex { |
| 41 float x, y, z, w; |
| 42 float u, v; |
| 43 }; |
| 44 |
| 45 // See accelerated_surface_win.hlsl for source and compilation instructions. |
| 46 const BYTE g_vertexMain[] = { |
| 47 0, 2, 254, 255, 254, 255, |
| 48 22, 0, 67, 84, 65, 66, |
| 49 28, 0, 0, 0, 35, 0, |
| 50 0, 0, 0, 2, 254, 255, |
| 51 0, 0, 0, 0, 0, 0, |
| 52 0, 0, 0, 1, 0, 0, |
| 53 28, 0, 0, 0, 118, 115, |
| 54 95, 50, 95, 48, 0, 77, |
| 55 105, 99, 114, 111, 115, 111, |
| 56 102, 116, 32, 40, 82, 41, |
| 57 32, 72, 76, 83, 76, 32, |
| 58 83, 104, 97, 100, 101, 114, |
| 59 32, 67, 111, 109, 112, 105, |
| 60 108, 101, 114, 32, 57, 46, |
| 61 50, 57, 46, 57, 53, 50, |
| 62 46, 51, 49, 49, 49, 0, |
| 63 31, 0, 0, 2, 0, 0, |
| 64 0, 128, 0, 0, 15, 144, |
| 65 31, 0, 0, 2, 5, 0, |
| 66 0, 128, 1, 0, 15, 144, |
| 67 1, 0, 0, 2, 0, 0, |
| 68 15, 192, 0, 0, 228, 144, |
| 69 1, 0, 0, 2, 0, 0, |
| 70 3, 224, 1, 0, 228, 144, |
| 71 255, 255, 0, 0 |
| 72 }; |
| 73 |
| 74 const BYTE g_pixelMain[] = { |
| 75 0, 2, 255, 255, 254, 255, |
| 76 32, 0, 67, 84, 65, 66, |
| 77 28, 0, 0, 0, 75, 0, |
| 78 0, 0, 0, 2, 255, 255, |
| 79 1, 0, 0, 0, 28, 0, |
| 80 0, 0, 0, 1, 0, 0, |
| 81 68, 0, 0, 0, 48, 0, |
| 82 0, 0, 3, 0, 0, 0, |
| 83 1, 0, 0, 0, 52, 0, |
| 84 0, 0, 0, 0, 0, 0, |
| 85 115, 0, 171, 171, 4, 0, |
| 86 12, 0, 1, 0, 1, 0, |
| 87 1, 0, 0, 0, 0, 0, |
| 88 0, 0, 112, 115, 95, 50, |
| 89 95, 48, 0, 77, 105, 99, |
| 90 114, 111, 115, 111, 102, 116, |
| 91 32, 40, 82, 41, 32, 72, |
| 92 76, 83, 76, 32, 83, 104, |
| 93 97, 100, 101, 114, 32, 67, |
| 94 111, 109, 112, 105, 108, 101, |
| 95 114, 32, 57, 46, 50, 57, |
| 96 46, 57, 53, 50, 46, 51, |
| 97 49, 49, 49, 0, 31, 0, |
| 98 0, 2, 0, 0, 0, 128, |
| 99 0, 0, 3, 176, 31, 0, |
| 100 0, 2, 0, 0, 0, 144, |
| 101 0, 8, 15, 160, 66, 0, |
| 102 0, 3, 0, 0, 15, 128, |
| 103 0, 0, 228, 176, 0, 8, |
| 104 228, 160, 1, 0, 0, 2, |
| 105 0, 8, 15, 128, 0, 0, |
| 106 228, 128, 255, 255, 0, 0 |
| 107 }; |
| 108 |
| 109 const static D3DVERTEXELEMENT9 g_vertexElements[] = { |
| 110 { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0 }, |
| 111 { 0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 }, |
| 112 D3DDECL_END() |
| 113 }; |
37 | 114 |
38 UINT GetPresentationInterval() { | 115 UINT GetPresentationInterval() { |
39 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) | 116 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) |
40 return D3DPRESENT_INTERVAL_IMMEDIATE; | 117 return D3DPRESENT_INTERVAL_IMMEDIATE; |
41 else | 118 else |
42 return D3DPRESENT_INTERVAL_ONE; | 119 return D3DPRESENT_INTERVAL_ONE; |
43 } | 120 } |
44 | 121 |
45 // Calculate the number necessary to transform |source_size| into |dest_size| | 122 // Calculate the number necessary to transform |source_size| into |dest_size| |
46 // by repeating downsampling of the image of |source_size| by a factor no more | 123 // by repeating downsampling of the image of |source_size| by a factor no more |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 window, | 282 window, |
206 D3DCREATE_FPU_PRESERVE | D3DCREATE_SOFTWARE_VERTEXPROCESSING | | 283 D3DCREATE_FPU_PRESERVE | D3DCREATE_SOFTWARE_VERTEXPROCESSING | |
207 D3DCREATE_DISABLE_PSGP_THREADING | D3DCREATE_MULTITHREADED, | 284 D3DCREATE_DISABLE_PSGP_THREADING | D3DCREATE_MULTITHREADED, |
208 ¶meters, | 285 ¶meters, |
209 NULL, | 286 NULL, |
210 device_.Receive()); | 287 device_.Receive()); |
211 if (FAILED(hr)) | 288 if (FAILED(hr)) |
212 return; | 289 return; |
213 | 290 |
214 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); | 291 hr = device_->CreateQuery(D3DQUERYTYPE_EVENT, query_.Receive()); |
215 if (FAILED(hr)) | 292 if (FAILED(hr)) { |
216 device_ = NULL; | 293 device_ = NULL; |
| 294 return; |
| 295 } |
| 296 |
| 297 base::win::ScopedComPtr<IDirect3DVertexShader9> vertex_shader; |
| 298 hr = device_->CreateVertexShader(reinterpret_cast<const DWORD*>(g_vertexMain), |
| 299 vertex_shader.Receive()); |
| 300 if (FAILED(hr)) { |
| 301 device_ = NULL; |
| 302 query_ = NULL; |
| 303 return; |
| 304 } |
| 305 |
| 306 device_->SetVertexShader(vertex_shader); |
| 307 |
| 308 base::win::ScopedComPtr<IDirect3DPixelShader9> pixel_shader; |
| 309 hr = device_->CreatePixelShader(reinterpret_cast<const DWORD*>(g_pixelMain), |
| 310 pixel_shader.Receive()); |
| 311 |
| 312 if (FAILED(hr)) { |
| 313 device_ = NULL; |
| 314 query_ = NULL; |
| 315 return; |
| 316 } |
| 317 |
| 318 device_->SetPixelShader(pixel_shader); |
| 319 |
| 320 base::win::ScopedComPtr<IDirect3DVertexDeclaration9> vertex_declaration; |
| 321 hr = device_->CreateVertexDeclaration(g_vertexElements, |
| 322 vertex_declaration.Receive()); |
| 323 if (FAILED(hr)) { |
| 324 device_ = NULL; |
| 325 query_ = NULL; |
| 326 return; |
| 327 } |
| 328 |
| 329 device_->SetVertexDeclaration(vertex_declaration); |
217 } | 330 } |
218 | 331 |
219 void PresentThread::CleanUp() { | 332 void PresentThread::CleanUp() { |
220 // The D3D device and query are leaked because destroying the associated D3D | 333 // The D3D device and query are leaked because destroying the associated D3D |
221 // query crashes some Intel drivers. | 334 // query crashes some Intel drivers. |
222 device_.Detach(); | 335 device_.Detach(); |
223 query_.Detach(); | 336 query_.Detach(); |
224 } | 337 } |
225 | 338 |
226 PresentThread::~PresentThread() { | 339 PresentThread::~PresentThread() { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 return scoped_refptr<AcceleratedPresenter>(); | 393 return scoped_refptr<AcceleratedPresenter>(); |
281 | 394 |
282 return it->second; | 395 return it->second; |
283 } | 396 } |
284 | 397 |
285 AcceleratedPresenter::AcceleratedPresenter(gfx::NativeWindow window) | 398 AcceleratedPresenter::AcceleratedPresenter(gfx::NativeWindow window) |
286 : present_thread_(g_present_thread_pool.Pointer()->NextThread()), | 399 : present_thread_(g_present_thread_pool.Pointer()->NextThread()), |
287 window_(window), | 400 window_(window), |
288 event_(false, false), | 401 event_(false, false), |
289 hidden_(true) { | 402 hidden_(true) { |
| 403 reverse_rows_ = CommandLine::ForCurrentProcess()->HasSwitch( |
| 404 kReverseImageTransportSurfaceRows); |
290 } | 405 } |
291 | 406 |
292 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( | 407 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( |
293 gfx::NativeWindow window) { | 408 gfx::NativeWindow window) { |
294 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); | 409 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); |
295 } | 410 } |
296 | 411 |
297 void AcceleratedPresenter::AsyncPresentAndAcknowledge( | 412 void AcceleratedPresenter::AsyncPresentAndAcknowledge( |
298 const gfx::Size& size, | 413 const gfx::Size& size, |
299 int64 surface_handle, | 414 int64 surface_handle, |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
627 dest_surface.Receive()); | 742 dest_surface.Receive()); |
628 if (FAILED(hr)) | 743 if (FAILED(hr)) |
629 return; | 744 return; |
630 | 745 |
631 RECT rect = { | 746 RECT rect = { |
632 0, 0, | 747 0, 0, |
633 size.width(), size.height() | 748 size.width(), size.height() |
634 }; | 749 }; |
635 | 750 |
636 { | 751 { |
637 TRACE_EVENT0("gpu", "StretchRect"); | 752 TRACE_EVENT0("gpu", "Copy"); |
638 hr = present_thread_->device()->StretchRect(source_surface, | 753 |
639 &rect, | 754 if (reverse_rows_) { |
640 dest_surface, | 755 // Use a simple pixel / vertex shader pair to render a quad that flips the |
641 &rect, | 756 // source texture on the vertical axis. |
642 D3DTEXF_NONE); | 757 IDirect3DSurface9 *default_render_target = NULL; |
643 if (FAILED(hr)) | 758 present_thread_->device()->GetRenderTarget(0, &default_render_target); |
644 return; | 759 |
| 760 present_thread_->device()->SetRenderTarget(0, dest_surface); |
| 761 present_thread_->device()->SetTexture(0, source_texture_); |
| 762 |
| 763 D3DVIEWPORT9 viewport = { |
| 764 0, 0, |
| 765 size.width(), size.height(), |
| 766 0, 1 |
| 767 }; |
| 768 present_thread_->device()->SetViewport(&viewport); |
| 769 |
| 770 float halfPixelX = -1.0f / size.width(); |
| 771 float halfPixelY = 1.0f / size.height(); |
| 772 Vertex vertices[] = { |
| 773 { halfPixelX - 1, halfPixelY + 1, 0.5f, 1, 0, 1 }, |
| 774 { halfPixelX + 1, halfPixelY + 1, 0.5f, 1, 1, 1 }, |
| 775 { halfPixelX + 1, halfPixelY - 1, 0.5f, 1, 1, 0 }, |
| 776 { halfPixelX - 1, halfPixelY - 1, 0.5f, 1, 0, 0 } |
| 777 }; |
| 778 |
| 779 present_thread_->device()->BeginScene(); |
| 780 present_thread_->device()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, |
| 781 arraysize(vertices), |
| 782 vertices, |
| 783 sizeof(vertices[0])); |
| 784 present_thread_->device()->EndScene(); |
| 785 |
| 786 present_thread_->device()->SetTexture(0, NULL); |
| 787 present_thread_->device()->SetRenderTarget(0, default_render_target); |
| 788 default_render_target->Release(); |
| 789 } else { |
| 790 // Copy the source texture directly into the swap chain without reversing |
| 791 // the rows. |
| 792 hr = present_thread_->device()->StretchRect(source_surface, |
| 793 &rect, |
| 794 dest_surface, |
| 795 &rect, |
| 796 D3DTEXF_NONE); |
| 797 if (FAILED(hr)) |
| 798 return; |
| 799 } |
645 } | 800 } |
646 | 801 |
647 hr = present_thread_->query()->Issue(D3DISSUE_END); | 802 hr = present_thread_->query()->Issue(D3DISSUE_END); |
648 if (FAILED(hr)) | 803 if (FAILED(hr)) |
649 return; | 804 return; |
650 | 805 |
651 // Flush so the StretchRect can be processed by the GPU while the window is | 806 // Flush so the StretchRect can be processed by the GPU while the window is |
652 // being resized. | 807 // being resized. |
653 present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); | 808 present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); |
654 | 809 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 return presenter_->CopyTo(size, buf); | 865 return presenter_->CopyTo(size, buf); |
711 } | 866 } |
712 | 867 |
713 void AcceleratedSurface::Suspend() { | 868 void AcceleratedSurface::Suspend() { |
714 presenter_->Suspend(); | 869 presenter_->Suspend(); |
715 } | 870 } |
716 | 871 |
717 void AcceleratedSurface::WasHidden() { | 872 void AcceleratedSurface::WasHidden() { |
718 presenter_->WasHidden(); | 873 presenter_->WasHidden(); |
719 } | 874 } |
OLD | NEW |