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 | 37 |
40 struct Vertex { | 38 struct Vertex { |
41 float x, y, z, w; | 39 float x, y, z, w; |
42 float u, v; | 40 float u, v; |
43 }; | 41 }; |
44 | 42 |
45 // See accelerated_surface_win.hlsl for source and compilation instructions. | 43 // See accelerated_surface_win.hlsl for source and compilation instructions. |
46 const BYTE g_vertexMain[] = { | 44 const BYTE g_vertexMain[] = { |
47 0, 2, 254, 255, 254, 255, | 45 0, 2, 254, 255, 254, 255, |
48 22, 0, 67, 84, 65, 66, | 46 22, 0, 67, 84, 65, 66, |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 return scoped_refptr<AcceleratedPresenter>(); | 391 return scoped_refptr<AcceleratedPresenter>(); |
394 | 392 |
395 return it->second; | 393 return it->second; |
396 } | 394 } |
397 | 395 |
398 AcceleratedPresenter::AcceleratedPresenter(gfx::NativeWindow window) | 396 AcceleratedPresenter::AcceleratedPresenter(gfx::NativeWindow window) |
399 : present_thread_(g_present_thread_pool.Pointer()->NextThread()), | 397 : present_thread_(g_present_thread_pool.Pointer()->NextThread()), |
400 window_(window), | 398 window_(window), |
401 event_(false, false), | 399 event_(false, false), |
402 hidden_(true) { | 400 hidden_(true) { |
403 reverse_rows_ = CommandLine::ForCurrentProcess()->HasSwitch( | |
404 kReverseImageTransportSurfaceRows); | |
405 } | 401 } |
406 | 402 |
407 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( | 403 scoped_refptr<AcceleratedPresenter> AcceleratedPresenter::GetForWindow( |
408 gfx::NativeWindow window) { | 404 gfx::NativeWindow window) { |
409 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); | 405 return g_accelerated_presenter_map.Pointer()->GetPresenter(window); |
410 } | 406 } |
411 | 407 |
412 void AcceleratedPresenter::AsyncPresentAndAcknowledge( | 408 void AcceleratedPresenter::AsyncPresentAndAcknowledge( |
413 const gfx::Size& size, | 409 const gfx::Size& size, |
414 int64 surface_handle, | 410 int64 surface_handle, |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 return; | 744 return; |
749 | 745 |
750 RECT rect = { | 746 RECT rect = { |
751 0, 0, | 747 0, 0, |
752 size.width(), size.height() | 748 size.width(), size.height() |
753 }; | 749 }; |
754 | 750 |
755 { | 751 { |
756 TRACE_EVENT0("gpu", "Copy"); | 752 TRACE_EVENT0("gpu", "Copy"); |
757 | 753 |
758 if (!reverse_rows_) { | 754 // Use a simple pixel / vertex shader pair to render a quad that flips the |
759 // Use a simple pixel / vertex shader pair to render a quad that flips the | 755 // source texture on the vertical axis. |
760 // source texture on the vertical axis. | 756 IDirect3DSurface9 *default_render_target = NULL; |
761 IDirect3DSurface9 *default_render_target = NULL; | 757 present_thread_->device()->GetRenderTarget(0, &default_render_target); |
762 present_thread_->device()->GetRenderTarget(0, &default_render_target); | |
763 | 758 |
764 present_thread_->device()->SetRenderTarget(0, dest_surface); | 759 present_thread_->device()->SetRenderTarget(0, dest_surface); |
765 present_thread_->device()->SetTexture(0, source_texture_); | 760 present_thread_->device()->SetTexture(0, source_texture_); |
766 | 761 |
767 D3DVIEWPORT9 viewport = { | 762 D3DVIEWPORT9 viewport = { |
768 0, 0, | 763 0, 0, |
769 size.width(), size.height(), | 764 size.width(), size.height(), |
770 0, 1 | 765 0, 1 |
771 }; | 766 }; |
772 present_thread_->device()->SetViewport(&viewport); | 767 present_thread_->device()->SetViewport(&viewport); |
773 | 768 |
774 float halfPixelX = -1.0f / size.width(); | 769 float halfPixelX = -1.0f / size.width(); |
775 float halfPixelY = 1.0f / size.height(); | 770 float halfPixelY = 1.0f / size.height(); |
776 Vertex vertices[] = { | 771 Vertex vertices[] = { |
777 { halfPixelX - 1, halfPixelY + 1, 0.5f, 1, 0, 1 }, | 772 { halfPixelX - 1, halfPixelY + 1, 0.5f, 1, 0, 1 }, |
778 { halfPixelX + 1, halfPixelY + 1, 0.5f, 1, 1, 1 }, | 773 { halfPixelX + 1, halfPixelY + 1, 0.5f, 1, 1, 1 }, |
779 { halfPixelX + 1, halfPixelY - 1, 0.5f, 1, 1, 0 }, | 774 { halfPixelX + 1, halfPixelY - 1, 0.5f, 1, 1, 0 }, |
780 { halfPixelX - 1, halfPixelY - 1, 0.5f, 1, 0, 0 } | 775 { halfPixelX - 1, halfPixelY - 1, 0.5f, 1, 0, 0 } |
781 }; | 776 }; |
782 | 777 |
783 present_thread_->device()->BeginScene(); | 778 present_thread_->device()->BeginScene(); |
784 present_thread_->device()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, | 779 present_thread_->device()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, |
785 arraysize(vertices), | 780 arraysize(vertices), |
786 vertices, | 781 vertices, |
787 sizeof(vertices[0])); | 782 sizeof(vertices[0])); |
788 present_thread_->device()->EndScene(); | 783 present_thread_->device()->EndScene(); |
789 | 784 |
790 present_thread_->device()->SetTexture(0, NULL); | 785 present_thread_->device()->SetTexture(0, NULL); |
791 present_thread_->device()->SetRenderTarget(0, default_render_target); | 786 present_thread_->device()->SetRenderTarget(0, default_render_target); |
792 default_render_target->Release(); | 787 default_render_target->Release(); |
793 } else { | |
794 // Copy the source texture directly into the swap chain without reversing | |
795 // the rows. | |
796 hr = present_thread_->device()->StretchRect(source_surface, | |
797 &rect, | |
798 dest_surface, | |
799 &rect, | |
800 D3DTEXF_NONE); | |
801 if (FAILED(hr)) | |
802 return; | |
803 } | |
804 } | 788 } |
805 | 789 |
806 hr = present_thread_->query()->Issue(D3DISSUE_END); | 790 hr = present_thread_->query()->Issue(D3DISSUE_END); |
807 if (FAILED(hr)) | 791 if (FAILED(hr)) |
808 return; | 792 return; |
809 | 793 |
810 // Flush so the StretchRect can be processed by the GPU while the window is | |
811 // being resized. | |
812 present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); | |
813 | |
814 present_size_ = size; | 794 present_size_ = size; |
815 | 795 |
816 // Wait for the StretchRect to complete before notifying the GPU process | 796 // Wait for the StretchRect to complete before notifying the GPU process |
817 // that it is safe to write to its backing store again. | 797 // that it is safe to write to its backing store again. |
818 { | 798 { |
819 TRACE_EVENT0("gpu", "spin"); | 799 TRACE_EVENT0("gpu", "spin"); |
820 do { | 800 do { |
821 hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); | 801 hr = present_thread_->query()->GetData(NULL, 0, D3DGETDATA_FLUSH); |
822 | 802 |
823 if (hr == S_FALSE) | 803 if (hr == S_FALSE) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 return presenter_->CopyTo(size, buf); | 851 return presenter_->CopyTo(size, buf); |
872 } | 852 } |
873 | 853 |
874 void AcceleratedSurface::Suspend() { | 854 void AcceleratedSurface::Suspend() { |
875 presenter_->Suspend(); | 855 presenter_->Suspend(); |
876 } | 856 } |
877 | 857 |
878 void AcceleratedSurface::WasHidden() { | 858 void AcceleratedSurface::WasHidden() { |
879 presenter_->WasHidden(); | 859 presenter_->WasHidden(); |
880 } | 860 } |
OLD | NEW |