OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 #include "webrtc/test/win/d3d_renderer.h" | 10 #include "webrtc/test/win/d3d_renderer.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 | 26 |
27 VideoRenderer* VideoRenderer::CreatePlatformRenderer(const char* window_title, | 27 VideoRenderer* VideoRenderer::CreatePlatformRenderer(const char* window_title, |
28 size_t width, | 28 size_t width, |
29 size_t height) { | 29 size_t height) { |
30 return D3dRenderer::Create(window_title, width, height); | 30 return D3dRenderer::Create(window_title, width, height); |
31 } | 31 } |
32 | 32 |
33 D3dRenderer::D3dRenderer(size_t width, size_t height) | 33 D3dRenderer::D3dRenderer(size_t width, size_t height) |
34 : width_(width), | 34 : width_(width), |
35 height_(height), | 35 height_(height), |
36 hwnd_(NULL), | 36 hwnd_(nullptr), |
37 d3d_(NULL), | 37 d3d_(nullptr), |
38 d3d_device_(NULL), | 38 d3d_device_(nullptr), |
39 texture_(NULL), | 39 texture_(nullptr), |
40 vertex_buffer_(NULL) { | 40 vertex_buffer_(nullptr) { |
41 RTC_DCHECK_GT(width, 0); | 41 RTC_DCHECK_GT(width, 0); |
42 RTC_DCHECK_GT(height, 0); | 42 RTC_DCHECK_GT(height, 0); |
43 } | 43 } |
44 | 44 |
45 D3dRenderer::~D3dRenderer() { Destroy(); } | 45 D3dRenderer::~D3dRenderer() { Destroy(); } |
46 | 46 |
47 LRESULT WINAPI D3dRenderer::WindowProc(HWND hwnd, UINT msg, WPARAM wparam, | 47 LRESULT WINAPI D3dRenderer::WindowProc(HWND hwnd, UINT msg, WPARAM wparam, |
48 LPARAM lparam) { | 48 LPARAM lparam) { |
49 if (msg == WM_DESTROY || (msg == WM_CHAR && wparam == VK_RETURN)) { | 49 if (msg == WM_DESTROY || (msg == WM_CHAR && wparam == VK_RETURN)) { |
50 PostQuitMessage(0); | 50 PostQuitMessage(0); |
51 return 0; | 51 return 0; |
52 } | 52 } |
53 | 53 |
54 return DefWindowProcA(hwnd, msg, wparam, lparam); | 54 return DefWindowProcA(hwnd, msg, wparam, lparam); |
55 } | 55 } |
56 | 56 |
57 void D3dRenderer::Destroy() { | 57 void D3dRenderer::Destroy() { |
58 texture_ = NULL; | 58 texture_ = nullptr; |
59 vertex_buffer_ = NULL; | 59 vertex_buffer_ = nullptr; |
60 d3d_device_ = NULL; | 60 d3d_device_ = nullptr; |
61 d3d_ = NULL; | 61 d3d_ = nullptr; |
62 | 62 |
63 if (hwnd_ != NULL) { | 63 if (hwnd_ != nullptr) { |
64 DestroyWindow(hwnd_); | 64 DestroyWindow(hwnd_); |
65 RTC_DCHECK(!IsWindow(hwnd_)); | 65 RTC_DCHECK(!IsWindow(hwnd_)); |
66 hwnd_ = NULL; | 66 hwnd_ = nullptr; |
67 } | 67 } |
68 } | 68 } |
69 | 69 |
70 bool D3dRenderer::Init(const char* window_title) { | 70 bool D3dRenderer::Init(const char* window_title) { |
71 hwnd_ = CreateWindowA(kD3DClassName, | 71 hwnd_ = CreateWindowA(kD3DClassName, window_title, WS_OVERLAPPEDWINDOW, 0, 0, |
72 window_title, | 72 static_cast<int>(width_), static_cast<int>(height_), |
73 WS_OVERLAPPEDWINDOW, | 73 nullptr, nullptr, nullptr, nullptr); |
74 0, | |
75 0, | |
76 static_cast<int>(width_), | |
77 static_cast<int>(height_), | |
78 NULL, | |
79 NULL, | |
80 NULL, | |
81 NULL); | |
82 | 74 |
83 if (hwnd_ == NULL) { | 75 if (hwnd_ == nullptr) { |
84 Destroy(); | 76 Destroy(); |
85 return false; | 77 return false; |
86 } | 78 } |
87 | 79 |
88 d3d_ = Direct3DCreate9(D3D_SDK_VERSION); | 80 d3d_ = Direct3DCreate9(D3D_SDK_VERSION); |
89 if (d3d_ == NULL) { | 81 if (d3d_ == nullptr) { |
90 Destroy(); | 82 Destroy(); |
91 return false; | 83 return false; |
92 } | 84 } |
93 | 85 |
94 D3DPRESENT_PARAMETERS d3d_params = {}; | 86 D3DPRESENT_PARAMETERS d3d_params = {}; |
95 | 87 |
96 d3d_params.Windowed = TRUE; | 88 d3d_params.Windowed = TRUE; |
97 d3d_params.SwapEffect = D3DSWAPEFFECT_COPY; | 89 d3d_params.SwapEffect = D3DSWAPEFFECT_COPY; |
98 | 90 |
99 IDirect3DDevice9* d3d_device; | 91 IDirect3DDevice9* d3d_device; |
100 if (d3d_->CreateDevice(D3DADAPTER_DEFAULT, | 92 if (d3d_->CreateDevice(D3DADAPTER_DEFAULT, |
101 D3DDEVTYPE_HAL, | 93 D3DDEVTYPE_HAL, |
102 hwnd_, | 94 hwnd_, |
103 D3DCREATE_SOFTWARE_VERTEXPROCESSING, | 95 D3DCREATE_SOFTWARE_VERTEXPROCESSING, |
104 &d3d_params, | 96 &d3d_params, |
105 &d3d_device) != D3D_OK) { | 97 &d3d_device) != D3D_OK) { |
106 Destroy(); | 98 Destroy(); |
107 return false; | 99 return false; |
108 } | 100 } |
109 d3d_device_ = d3d_device; | 101 d3d_device_ = d3d_device; |
110 d3d_device->Release(); | 102 d3d_device->Release(); |
111 | 103 |
112 IDirect3DVertexBuffer9* vertex_buffer; | 104 IDirect3DVertexBuffer9* vertex_buffer; |
113 const int kRectVertices = 4; | 105 const int kRectVertices = 4; |
114 if (d3d_device_->CreateVertexBuffer(kRectVertices * sizeof(D3dCustomVertex), | 106 if (d3d_device_->CreateVertexBuffer(kRectVertices * sizeof(D3dCustomVertex), |
115 0, | 107 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, |
116 D3DFVF_CUSTOMVERTEX, | 108 &vertex_buffer, nullptr) != D3D_OK) { |
117 D3DPOOL_MANAGED, | |
118 &vertex_buffer, | |
119 NULL) != D3D_OK) { | |
120 Destroy(); | 109 Destroy(); |
121 return false; | 110 return false; |
122 } | 111 } |
123 vertex_buffer_ = vertex_buffer; | 112 vertex_buffer_ = vertex_buffer; |
124 vertex_buffer->Release(); | 113 vertex_buffer->Release(); |
125 | 114 |
126 d3d_device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); | 115 d3d_device_->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); |
127 d3d_device_->SetRenderState(D3DRS_LIGHTING, FALSE); | 116 d3d_device_->SetRenderState(D3DRS_LIGHTING, FALSE); |
128 Resize(width_, height_); | 117 Resize(width_, height_); |
129 | 118 |
130 ShowWindow(hwnd_, SW_SHOWNOACTIVATE); | 119 ShowWindow(hwnd_, SW_SHOWNOACTIVATE); |
131 d3d_device_->Present(NULL, NULL, NULL, NULL); | 120 d3d_device_->Present(nullptr, nullptr, nullptr, nullptr); |
132 | 121 |
133 return true; | 122 return true; |
134 } | 123 } |
135 | 124 |
136 D3dRenderer* D3dRenderer::Create(const char* window_title, | 125 D3dRenderer* D3dRenderer::Create(const char* window_title, |
137 size_t width, | 126 size_t width, |
138 size_t height) { | 127 size_t height) { |
139 static ATOM wc_atom = 0; | 128 static ATOM wc_atom = 0; |
140 if (wc_atom == 0) { | 129 if (wc_atom == 0) { |
141 WNDCLASSA wc = {}; | 130 WNDCLASSA wc = {}; |
142 | 131 |
143 wc.style = CS_HREDRAW | CS_VREDRAW; | 132 wc.style = CS_HREDRAW | CS_VREDRAW; |
144 wc.lpfnWndProc = WindowProc; | 133 wc.lpfnWndProc = WindowProc; |
145 wc.hCursor = LoadCursor(NULL, IDC_ARROW); | 134 wc.hCursor = LoadCursor(nullptr, IDC_ARROW); |
146 wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW); | 135 wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW); |
147 wc.lpszClassName = kD3DClassName; | 136 wc.lpszClassName = kD3DClassName; |
148 | 137 |
149 wc_atom = RegisterClassA(&wc); | 138 wc_atom = RegisterClassA(&wc); |
150 if (wc_atom == 0) | 139 if (wc_atom == 0) |
151 return false; | 140 return false; |
152 } | 141 } |
153 | 142 |
154 D3dRenderer* d3d_renderer = new D3dRenderer(width, height); | 143 D3dRenderer* d3d_renderer = new D3dRenderer(width, height); |
155 if (!d3d_renderer->Init(window_title)) { | 144 if (!d3d_renderer->Init(window_title)) { |
156 delete d3d_renderer; | 145 delete d3d_renderer; |
157 return NULL; | 146 return nullptr; |
158 } | 147 } |
159 | 148 |
160 return d3d_renderer; | 149 return d3d_renderer; |
161 } | 150 } |
162 | 151 |
163 void D3dRenderer::Resize(size_t width, size_t height) { | 152 void D3dRenderer::Resize(size_t width, size_t height) { |
164 width_ = width; | 153 width_ = width; |
165 height_ = height; | 154 height_ = height; |
166 IDirect3DTexture9* texture; | 155 IDirect3DTexture9* texture; |
167 | 156 |
168 d3d_device_->CreateTexture(static_cast<UINT>(width_), | 157 d3d_device_->CreateTexture(static_cast<UINT>(width_), |
169 static_cast<UINT>(height_), | 158 static_cast<UINT>(height_), 1, 0, D3DFMT_A8R8G8B8, |
170 1, | 159 D3DPOOL_MANAGED, &texture, nullptr); |
171 0, | |
172 D3DFMT_A8R8G8B8, | |
173 D3DPOOL_MANAGED, | |
174 &texture, | |
175 NULL); | |
176 texture_ = texture; | 160 texture_ = texture; |
177 texture->Release(); | 161 texture->Release(); |
178 | 162 |
179 // Vertices for the video frame to be rendered to. | 163 // Vertices for the video frame to be rendered to. |
180 static const D3dCustomVertex rect[] = { | 164 static const D3dCustomVertex rect[] = { |
181 {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f}, | 165 {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f}, |
182 {-1.0f, 1.0f, 0.0f, 0.0f, 0.0f}, | 166 {-1.0f, 1.0f, 0.0f, 0.0f, 0.0f}, |
183 {1.0f, -1.0f, 0.0f, 1.0f, 1.0f}, | 167 {1.0f, -1.0f, 0.0f, 1.0f, 1.0f}, |
184 {1.0f, 1.0f, 0.0f, 1.0f, 0.0f}, | 168 {1.0f, 1.0f, 0.0f, 1.0f, 0.0f}, |
185 }; | 169 }; |
186 | 170 |
187 void* buf_data; | 171 void* buf_data; |
188 if (vertex_buffer_->Lock(0, 0, &buf_data, 0) != D3D_OK) | 172 if (vertex_buffer_->Lock(0, 0, &buf_data, 0) != D3D_OK) |
189 return; | 173 return; |
190 | 174 |
191 memcpy(buf_data, &rect, sizeof(rect)); | 175 memcpy(buf_data, &rect, sizeof(rect)); |
192 vertex_buffer_->Unlock(); | 176 vertex_buffer_->Unlock(); |
193 } | 177 } |
194 | 178 |
195 void D3dRenderer::OnFrame(const webrtc::VideoFrame& frame) { | 179 void D3dRenderer::OnFrame(const webrtc::VideoFrame& frame) { |
196 if (static_cast<size_t>(frame.width()) != width_ || | 180 if (static_cast<size_t>(frame.width()) != width_ || |
197 static_cast<size_t>(frame.height()) != height_) { | 181 static_cast<size_t>(frame.height()) != height_) { |
198 Resize(static_cast<size_t>(frame.width()), | 182 Resize(static_cast<size_t>(frame.width()), |
199 static_cast<size_t>(frame.height())); | 183 static_cast<size_t>(frame.height())); |
200 } | 184 } |
201 | 185 |
202 D3DLOCKED_RECT lock_rect; | 186 D3DLOCKED_RECT lock_rect; |
203 if (texture_->LockRect(0, &lock_rect, NULL, 0) != D3D_OK) | 187 if (texture_->LockRect(0, &lock_rect, nullptr, 0) != D3D_OK) |
204 return; | 188 return; |
205 | 189 |
206 ConvertFromI420(frame, kARGB, 0, static_cast<uint8_t*>(lock_rect.pBits)); | 190 ConvertFromI420(frame, kARGB, 0, static_cast<uint8_t*>(lock_rect.pBits)); |
207 texture_->UnlockRect(0); | 191 texture_->UnlockRect(0); |
208 | 192 |
209 d3d_device_->BeginScene(); | 193 d3d_device_->BeginScene(); |
210 d3d_device_->SetFVF(D3DFVF_CUSTOMVERTEX); | 194 d3d_device_->SetFVF(D3DFVF_CUSTOMVERTEX); |
211 d3d_device_->SetStreamSource(0, vertex_buffer_, 0, sizeof(D3dCustomVertex)); | 195 d3d_device_->SetStreamSource(0, vertex_buffer_, 0, sizeof(D3dCustomVertex)); |
212 d3d_device_->SetTexture(0, texture_); | 196 d3d_device_->SetTexture(0, texture_); |
213 d3d_device_->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); | 197 d3d_device_->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); |
214 d3d_device_->EndScene(); | 198 d3d_device_->EndScene(); |
215 | 199 |
216 d3d_device_->Present(NULL, NULL, NULL, NULL); | 200 d3d_device_->Present(nullptr, nullptr, nullptr, nullptr); |
217 } | 201 } |
218 } // namespace test | 202 } // namespace test |
219 } // namespace webrtc | 203 } // namespace webrtc |
OLD | NEW |