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

Side by Side Diff: ui/gfx/compositor/compositor_win.cc

Issue 9288053: Remove old (pre-webkit) compositor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test Created 8 years, 10 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
« no previous file with comments | « ui/gfx/compositor/compositor_stub.cc ('k') | ui/gfx/compositor/debug_utils.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/gfx/compositor/compositor.h"
6
7 #include <algorithm>
8 #include <d3dx10.h>
9 #include <vector>
10
11 #include "base/compiler_specific.h"
12 #include "base/logging.h"
13 #include "base/stl_util.h"
14 #include "base/string_piece.h"
15 #include "base/win/scoped_comptr.h"
16 #include "grit/gfx_resources.h"
17 #include "third_party/skia/include/core/SkCanvas.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/canvas_skia.h"
20 #include "ui/gfx/rect.h"
21 #include "ui/gfx/transform.h"
22
23 // TODO(sky): this is a hack, figure out real error handling.
24 #define RETURN_IF_FAILED(error) \
25 if (error != S_OK) { \
26 this->Errored(error); \
27 VLOG(1) << "D3D failed" << error; \
28 return; \
29 }
30
31 using base::win::ScopedComPtr;
32
33 namespace ui {
34
35 namespace {
36
37 class CompositorWin;
38
39 // Vertex structure used by the compositor.
40 struct Vertex {
41 D3DXVECTOR3 position;
42 D3DXVECTOR2 texture_offset;
43 };
44
45 // D3D 10 Texture implementation. Creates a quad representing the view and
46 // a texture with the bitmap data. The quad has an origin of 0,0,0 with a size
47 // matching that of |SetCanvas|.
48 class ViewTexture : public Texture {
49 public:
50 ViewTexture(CompositorWin* compositor,
51 ID3D10Device* device,
52 ID3D10Effect* effect);
53
54 // Texture:
55 virtual void SetCanvas(const SkCanvas& canvas,
56 const gfx::Point& origin,
57 const gfx::Size& overall_size) OVERRIDE;
58 virtual void Draw(const ui::TextureDrawParams& params,
59 const gfx::Rect& clip_bounds_in_texture) OVERRIDE;
60
61 private:
62 ~ViewTexture();
63
64 void Errored(HRESULT result);
65
66 void ConvertBitmapToD3DData(const SkBitmap& bitmap,
67 scoped_array<uint32>* converted_data);
68
69 // Creates vertex buffer for specified region
70 void CreateVertexBufferForRegion(const gfx::Rect& bounds);
71
72 scoped_refptr<CompositorWin> compositor_;
73
74 // Size of the corresponding View.
75 gfx::Size view_size_;
76
77 ScopedComPtr<ID3D10Device> device_;
78 ScopedComPtr<ID3D10Effect, NULL> effect_;
79 ScopedComPtr<ID3D10Texture2D> texture_;
80 ScopedComPtr<ID3D10ShaderResourceView> shader_view_;
81 ScopedComPtr<ID3D10Buffer> vertex_buffer_;
82
83 DISALLOW_COPY_AND_ASSIGN(ViewTexture);
84 };
85
86 // D3D 10 Compositor implementation.
87 class CompositorWin : public Compositor {
88 public:
89 CompositorWin(CompositorDelegate* delegate,
90 gfx::AcceleratedWidget widget,
91 const gfx::Size& size);
92
93 void Init();
94
95 // Invoked to update the perspective needed by this texture. |transform| is
96 // the transform for the texture, and |size| the size of the texture.
97 void UpdatePerspective(const ui::Transform& transform,
98 const gfx::Size& view_size);
99
100 // Returns the index buffer used for drawing a texture.
101 ID3D10Buffer* GetTextureIndexBuffer();
102
103 // Compositor:
104 virtual Texture* CreateTexture() OVERRIDE;
105
106 virtual void Blur(const gfx::Rect& bounds) OVERRIDE;
107
108 virtual bool ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) OVERRIDE;
109
110 protected:
111 virtual void OnNotifyStart(bool clear) OVERRIDE;
112 virtual void OnNotifyEnd() OVERRIDE;
113 virtual void OnWidgetSizeChanged() OVERRIDE;
114
115 private:
116 enum Direction {
117 HORIZONTAL,
118 VERTICAL
119 };
120
121 ~CompositorWin();
122
123 void Errored(HRESULT error_code);
124
125 void CreateDevice();
126
127 void LoadEffects();
128
129 void InitVertexLayout();
130
131 // Updates the kernel used for blurring. Size is the size of the texture
132 // being drawn to along the appropriate axis.
133 void UpdateBlurKernel(Direction direction, int size);
134
135 // Creates a texture, render target view and shader.
136 void CreateTexture(const gfx::Size& size,
137 ID3D10Texture2D** texture,
138 ID3D10RenderTargetView** render_target_view,
139 ID3D10ShaderResourceView** shader_resource_view);
140
141 // Creates |vertex_buffer_|.
142 void CreateVertexBuffer();
143
144 // Creates |index_buffer_|.
145 void CreateIndexBuffer();
146
147 // Creates a vertex buffer for the specified region. The caller owns the
148 // return value.
149 ID3D10Buffer* CreateVertexBufferForRegion(const gfx::Rect& bounds);
150
151 gfx::AcceleratedWidget host_;
152
153 ScopedComPtr<ID3D10Device> device_;
154 ScopedComPtr<IDXGISwapChain> swap_chain_;
155 ScopedComPtr<ID3D10RenderTargetView> dest_render_target_view_;
156 ScopedComPtr<ID3D10Texture2D> depth_stencil_buffer_;
157 ScopedComPtr<ID3D10DepthStencilView> depth_stencil_view_;
158 ScopedComPtr<ID3D10Effect, NULL> fx_;
159 ID3D10EffectTechnique* technique_;
160
161 // Layout for Vertex.
162 ScopedComPtr<ID3D10InputLayout> vertex_layout_;
163
164 // Identity vertext buffer. Used when copying from main back to dest.
165 ScopedComPtr<ID3D10Buffer> vertex_buffer_;
166
167 // Index buffer used for drawing a rectangle.
168 ScopedComPtr<ID3D10Buffer> index_buffer_;
169
170 // Used for bluring.
171 ScopedComPtr<ID3D10Effect, NULL> blur_fx_;
172 ID3D10EffectTechnique* blur_technique_;
173
174 // All rendering is done to the main_texture. Effects (such as bloom) render
175 // into the blur texture, and are then copied back to the main texture. When
176 // rendering is done |main_texture_| is drawn back to
177 // |dest_render_target_view_|.
178 ScopedComPtr<ID3D10Texture2D> main_texture_;
179 ScopedComPtr<ID3D10RenderTargetView> main_render_target_view_;
180 ScopedComPtr<ID3D10ShaderResourceView> main_texture_shader_view_;
181
182 ScopedComPtr<ID3D10Texture2D> blur_texture_;
183 ScopedComPtr<ID3D10RenderTargetView> blur_render_target_view_;
184 ScopedComPtr<ID3D10ShaderResourceView> blur_texture_shader_view_;
185
186 DISALLOW_COPY_AND_ASSIGN(CompositorWin);
187 };
188
189 ViewTexture::ViewTexture(CompositorWin* compositor,
190 ID3D10Device* device,
191 ID3D10Effect* effect)
192 : compositor_(compositor),
193 device_(device),
194 effect_(effect) {
195 }
196
197 ViewTexture::~ViewTexture() {
198 }
199
200 void ViewTexture::SetCanvas(const SkCanvas& canvas,
201 const gfx::Point& origin,
202 const gfx::Size& overall_size) {
203 view_size_ = overall_size;
204
205 scoped_array<uint32> converted_data;
206 const SkBitmap& bitmap = canvas.getDevice()->accessBitmap(false);
207 ConvertBitmapToD3DData(bitmap, &converted_data);
208 if (gfx::Size(bitmap.width(), bitmap.height()) == overall_size) {
209 shader_view_.Release();
210 texture_.Release();
211
212 D3D10_TEXTURE2D_DESC texture_desc;
213 texture_desc.Width = bitmap.width();
214 texture_desc.Height = bitmap.height();
215 texture_desc.MipLevels = 1;
216 texture_desc.ArraySize = 1;
217 texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
218 texture_desc.SampleDesc.Count = 1;
219 texture_desc.SampleDesc.Quality = 0;
220 texture_desc.Usage = D3D10_USAGE_DEFAULT;
221 texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
222 texture_desc.CPUAccessFlags = 0;
223 texture_desc.MiscFlags = 0;
224 RETURN_IF_FAILED(device_->CreateTexture2D(&texture_desc,
225 NULL, texture_.Receive()));
226 RETURN_IF_FAILED(
227 device_->CreateShaderResourceView(texture_.get(), NULL,
228 shader_view_.Receive()));
229 }
230 DCHECK(texture_.get());
231 D3D10_BOX dst_box = { origin.x(), origin.y(), 0,
232 origin.x() + bitmap.width(),
233 origin.y() + bitmap.height(), 1 };
234 device_->UpdateSubresource(texture_.get(), 0, &dst_box,
235 converted_data.get(), bitmap.width() * 4, 0);
236 }
237
238 void ViewTexture::Draw(const ui::TextureDrawParams& params,
239 const gfx::Rect& clip_bounds) {
240 if (params.vertically_flipped)
241 NOTIMPLEMENTED();
242
243 compositor_->UpdatePerspective(params.transform, view_size_);
244
245 // Make texture active.
246 RETURN_IF_FAILED(
247 effect_->GetVariableByName("textureMap")->AsShaderResource()->
248 SetResource(shader_view_.get()));
249
250 RETURN_IF_FAILED(effect_->GetVariableByName("alpha")->AsScalar()->SetFloat(
251 params.opacity));
252
253 ID3D10EffectTechnique* technique = effect_->GetTechniqueByName("ViewTech");
254 DCHECK(technique);
255 D3D10_TECHNIQUE_DESC tech_desc;
256 technique->GetDesc(&tech_desc);
257 for(UINT p = 0; p < tech_desc.Passes; ++p)
258 technique->GetPassByIndex(p)->Apply(0);
259
260 UINT stride = sizeof(Vertex);
261 UINT offset = 0;
262 CreateVertexBufferForRegion(clip_bounds);
263 ID3D10Buffer* vertex_buffer = vertex_buffer_.get();
264 device_->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
265 device_->IASetIndexBuffer(compositor_->GetTextureIndexBuffer(),
266 DXGI_FORMAT_R32_UINT, 0);
267 device_->DrawIndexed(6, 0, 0);
268 }
269
270 void ViewTexture::Errored(HRESULT result) {
271 // TODO: figure out error handling.
272 DCHECK(false);
273 }
274
275 void ViewTexture::ConvertBitmapToD3DData(
276 const SkBitmap& bitmap,
277 scoped_array<uint32>* converted_data) {
278 int width = bitmap.width();
279 int height = bitmap.height();
280 SkAutoLockPixels pixel_lock(bitmap);
281 // D3D wants colors in ABGR format (premultiplied).
282 converted_data->reset(new uint32[width * height]);
283 uint32_t* bitmap_data = bitmap.getAddr32(0, 0);
284 for (int x = 0, offset = 0; x < width; ++x) {
285 for (int y = 0; y < height; ++y, ++offset) {
286 SkColor color = bitmap_data[offset];
287 (*converted_data)[offset] =
288 (SkColorGetA(color) << 24) |
289 (SkColorGetB(color) << 16) |
290 (SkColorGetG(color) << 8) |
291 (SkColorGetR(color));
292 }
293 }
294 }
295
296 void ViewTexture::CreateVertexBufferForRegion(const gfx::Rect& bounds) {
297 vertex_buffer_.Release();
298 float x = bounds.x();
299 float max_x = bounds.right();
300 float y = bounds.y();
301 float max_y = bounds.bottom();
302 float tex_x = x / static_cast<float>(view_size_.width());
303 float max_tex_x = max_x / static_cast<float>(view_size_.width());
304 float tex_y = y / static_cast<float>(view_size_.width());
305 float max_tex_y = max_y / static_cast<float>(view_size_.height());
306 Vertex vertices[] = {
307 { D3DXVECTOR3( x, -max_y, 0.0f), D3DXVECTOR2( tex_x, max_tex_y) },
308 { D3DXVECTOR3( x, -y, 0.0f), D3DXVECTOR2( tex_x, tex_y) },
309 { D3DXVECTOR3(max_x, -y, 0.0f), D3DXVECTOR2(max_tex_x, tex_y) },
310 { D3DXVECTOR3(max_x, -max_y, 0.0f), D3DXVECTOR2(max_tex_x, max_tex_y) }
311 };
312
313 // Create the vertex buffer containing the points.
314 D3D10_BUFFER_DESC buffer_desc;
315 buffer_desc.Usage = D3D10_USAGE_IMMUTABLE;
316 buffer_desc.ByteWidth = sizeof(Vertex) * ARRAYSIZE_UNSAFE(vertices);
317 buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
318 buffer_desc.CPUAccessFlags = 0;
319 buffer_desc.MiscFlags = 0;
320 D3D10_SUBRESOURCE_DATA init_data;
321 init_data.pSysMem = vertices;
322 RETURN_IF_FAILED(device_->CreateBuffer(&buffer_desc, &init_data,
323 vertex_buffer_.Receive()));
324 }
325
326 CompositorWin::CompositorWin(CompositorDelegate* delegate,
327 gfx::AcceleratedWidget widget,
328 const gfx::Size& size)
329 : Compositor(delegate, size),
330 host_(widget),
331 technique_(NULL) {
332 }
333
334 void CompositorWin::Init() {
335 CreateDevice();
336 LoadEffects();
337 OnWidgetSizeChanged();
338 InitVertexLayout();
339 CreateVertexBuffer();
340 CreateIndexBuffer();
341 }
342
343 void CompositorWin::UpdatePerspective(const ui::Transform& transform,
344 const gfx::Size& view_size) {
345 float transform_data_buffer[16];
346 transform.matrix().asColMajorf(transform_data_buffer);
347 D3DXMATRIX transform_matrix(&transform_data_buffer[0]);
348 std::swap(transform_matrix._12, transform_matrix._21);
349 std::swap(transform_matrix._13, transform_matrix._31);
350 std::swap(transform_matrix._23, transform_matrix._32);
351
352 // Different coordinate system; flip the y.
353 transform_matrix._42 *= -1;
354
355 // Scale so x and y are from 0-2.
356 D3DXMATRIX scale_matrix;
357 D3DXMatrixScaling(
358 &scale_matrix,
359 2.0f / static_cast<float>(size().width()),
360 2.0f / static_cast<float>(size().height()),
361 1.0f);
362
363 // Translate so x and y are from -1,-1 to 1,1.
364 D3DXMATRIX translate_matrix;
365 D3DXMatrixTranslation(&translate_matrix, -1.0f, 1.0f, 0.0f);
366
367 D3DXMATRIX projection_matrix;
368 D3DXMatrixIdentity(&projection_matrix);
369 D3DXMatrixPerspectiveFovLH(&projection_matrix,
370 atanf(.5f) * 2.0f, 1.0f, 1.0f, 1000.0f);
371 D3DXVECTOR3 pos(0.0f, 0.0f, -2.0f);
372 D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
373 D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
374 D3DXMATRIX view;
375 D3DXMatrixIdentity(&view);
376 D3DXMatrixLookAtLH(&view, &pos, &target, &up);
377
378 D3DXMATRIX wvp = transform_matrix * scale_matrix * translate_matrix * view *
379 projection_matrix;
380
381 fx_->GetVariableByName("gWVP")->AsMatrix()->SetMatrix(wvp);
382 }
383
384 ID3D10Buffer* CompositorWin::GetTextureIndexBuffer() {
385 return index_buffer_.get();
386 }
387
388 Texture* CompositorWin::CreateTexture() {
389 return new ViewTexture(this, device_.get(), fx_.get());
390 }
391
392 void CompositorWin::OnNotifyStart(bool clear) {
393 ID3D10RenderTargetView* target_view = main_render_target_view_.get();
394 device_->OMSetRenderTargets(1, &target_view, depth_stencil_view_.get());
395
396 // Clear the background and stencil view.
397 // TODO(vollick) see if |clear| can be used to avoid unnecessary clearing.
398 device_->ClearRenderTargetView(target_view,
399 D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f));
400 device_->ClearDepthStencilView(
401 depth_stencil_view_.get(), D3D10_CLEAR_DEPTH|D3D10_CLEAR_STENCIL,
402 1.0f, 0);
403
404 // TODO: these steps may not be necessary each time through.
405 device_->OMSetDepthStencilState(0, 0);
406 float blend_factors[] = {0.0f, 0.0f, 0.0f, 0.0f};
407 device_->OMSetBlendState(0, blend_factors, 0xffffffff);
408 device_->IASetInputLayout(vertex_layout_.get());
409 device_->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
410 }
411
412 void CompositorWin::OnNotifyEnd() {
413 // Copy from main_render_target_view_| (where all are rendering was done) back
414 // to |dest_render_target_view_|.
415 ID3D10RenderTargetView* target_view = dest_render_target_view_.get();
416 device_->OMSetRenderTargets(1, &target_view, NULL);
417 device_->ClearRenderTargetView(target_view,
418 D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f));
419 RETURN_IF_FAILED(
420 fx_->GetVariableByName("textureMap")->AsShaderResource()->
421 SetResource(main_texture_shader_view_.get()));
422 D3DXMATRIX identify_matrix;
423 D3DXMatrixIdentity(&identify_matrix);
424 fx_->GetVariableByName("gWVP")->AsMatrix()->SetMatrix(identify_matrix);
425 ID3D10EffectTechnique* technique = fx_->GetTechniqueByName("ViewTech");
426 DCHECK(technique);
427 D3D10_TECHNIQUE_DESC tech_desc;
428 technique->GetDesc(&tech_desc);
429 for(UINT p = 0; p < tech_desc.Passes; ++p)
430 technique->GetPassByIndex(p)->Apply(0);
431 UINT stride = sizeof(Vertex);
432 UINT offset = 0;
433 ID3D10Buffer* vertex_buffer = vertex_buffer_.get();
434 device_->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
435 device_->IASetIndexBuffer(index_buffer_.get(), DXGI_FORMAT_R32_UINT, 0);
436 device_->DrawIndexed(6, 0, 0);
437 RETURN_IF_FAILED(
438 fx_->GetVariableByName("textureMap")->AsShaderResource()->
439 SetResource(NULL));
440 swap_chain_->Present(0, 0);
441
442 // We may delete the shader resource view before drawing again. Unset it so
443 // that d3d doesn't generate a warning when we do that.
444 fx_->GetVariableByName("textureMap")->AsShaderResource()->SetResource(NULL);
445 for(UINT i = 0; i < tech_desc.Passes; ++i)
446 technique_->GetPassByIndex(i)->Apply(0);
447 }
448
449 void CompositorWin::Blur(const gfx::Rect& bounds) {
450 // Set up the vertex buffer for the region we're going to blur.
451 ScopedComPtr<ID3D10Buffer> scoped_vertex_buffer(
452 CreateVertexBufferForRegion(bounds));
453 ID3D10Buffer* vertex_buffer = scoped_vertex_buffer.get();
454 UINT stride = sizeof(Vertex);
455 UINT offset = 0;
456 device_->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
457 device_->IASetIndexBuffer(index_buffer_.get(), DXGI_FORMAT_R32_UINT, 0);
458 device_->DrawIndexed(6, 0, 0);
459 D3DXMATRIX identity_matrix;
460 D3DXMatrixIdentity(&identity_matrix);
461
462 // Horizontal blur from the main texture to blur texture.
463 UpdateBlurKernel(HORIZONTAL, size().width());
464 ID3D10RenderTargetView* target_view = blur_render_target_view_.get();
465 device_->OMSetRenderTargets(1, &target_view, NULL);
466 RETURN_IF_FAILED(
467 blur_fx_->GetVariableByName("textureMap")->AsShaderResource()->
468 SetResource(main_texture_shader_view_.get()));
469 blur_fx_->GetVariableByName("gWVP")->AsMatrix()->SetMatrix(
470 identity_matrix);
471 ID3D10EffectTechnique* technique = blur_fx_->GetTechniqueByName("ViewTech");
472 DCHECK(technique);
473 D3D10_TECHNIQUE_DESC tech_desc;
474 technique->GetDesc(&tech_desc);
475 for(UINT p = 0; p < tech_desc.Passes; ++p)
476 technique->GetPassByIndex(p)->Apply(0);
477 device_->DrawIndexed(6, 0, 0);
478
479 {
480 // We do this to avoid a warning.
481 ID3D10ShaderResourceView* tmp = NULL;
482 device_->PSSetShaderResources(0, 1, &tmp);
483 }
484
485 // Vertical blur from the blur texture back to main buffer.
486 RETURN_IF_FAILED(
487 blur_fx_->GetVariableByName("textureMap")->AsShaderResource()->
488 SetResource(blur_texture_shader_view_.get()));
489 UpdateBlurKernel(VERTICAL, size().height());
490 target_view = main_render_target_view_.get();
491 device_->OMSetRenderTargets(1, &target_view, NULL);
492 for(UINT p = 0; p < tech_desc.Passes; ++p)
493 technique->GetPassByIndex(p)->Apply(0);
494 device_->DrawIndexed(6, 0, 0);
495
496 #if !defined(NDEBUG)
497 // A warning is generated if a bound vertexbuffer is deleted. To avoid that
498 // warning we reset the buffer here. We only do it for debug builds as it's
499 // ok to effectively unbind the vertex buffer.
500 vertex_buffer = vertex_buffer_.get();
501 device_->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
502 device_->IASetIndexBuffer(index_buffer_.get(), DXGI_FORMAT_R32_UINT, 0);
503 #endif
504 }
505
506 bool CompositorWin::ReadPixels(SkBitmap* bitmap, const gfx::Rect& bounds) {
507 NOTIMPLEMENTED();
508 return false;
509 }
510
511 void CompositorWin::OnWidgetSizeChanged() {
512 dest_render_target_view_ = NULL;
513 depth_stencil_buffer_ = NULL;
514 depth_stencil_view_ = NULL;
515
516 main_render_target_view_ = NULL;
517 main_texture_ = NULL;
518 main_texture_shader_view_ = NULL;
519
520 blur_render_target_view_ = NULL;
521 blur_texture_ = NULL;
522 blur_texture_shader_view_ = NULL;
523
524 CreateTexture(size(), main_texture_.Receive(),
525 main_render_target_view_.Receive(),
526 main_texture_shader_view_.Receive());
527
528 CreateTexture(size(), blur_texture_.Receive(),
529 blur_render_target_view_.Receive(),
530 blur_texture_shader_view_.Receive());
531
532 // Resize the swap chain and recreate the render target view.
533 RETURN_IF_FAILED(swap_chain_->ResizeBuffers(
534 1, size().width(), size().height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0));
535 ScopedComPtr<ID3D10Texture2D> back_buffer;
536 RETURN_IF_FAILED(swap_chain_->GetBuffer(
537 0, __uuidof(ID3D10Texture2D),
538 reinterpret_cast<void**>(back_buffer.Receive())));
539 RETURN_IF_FAILED(device_->CreateRenderTargetView(
540 back_buffer.get(), 0,
541 dest_render_target_view_.Receive()));
542
543 // Create the depth/stencil buffer and view.
544 D3D10_TEXTURE2D_DESC depth_stencil_desc;
545 depth_stencil_desc.Width = size().width();
546 depth_stencil_desc.Height = size().height();
547 depth_stencil_desc.MipLevels = 1;
548 depth_stencil_desc.ArraySize = 1;
549 depth_stencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
550 depth_stencil_desc.SampleDesc.Count = 1; // multisampling must match
551 depth_stencil_desc.SampleDesc.Quality = 0; // swap chain values.
552 depth_stencil_desc.Usage = D3D10_USAGE_DEFAULT;
553 depth_stencil_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
554 depth_stencil_desc.CPUAccessFlags = 0;
555 depth_stencil_desc.MiscFlags = 0;
556
557 RETURN_IF_FAILED(device_->CreateTexture2D(&depth_stencil_desc, 0,
558 depth_stencil_buffer_.Receive()));
559 RETURN_IF_FAILED(device_->CreateDepthStencilView(
560 depth_stencil_buffer_.get(), 0,
561 depth_stencil_view_.Receive()));
562
563
564 // Set the viewport transform.
565 D3D10_VIEWPORT vp;
566 vp.TopLeftX = 0;
567 vp.TopLeftY = 0;
568 vp.Width = size().width();
569 vp.Height = size().height();
570 vp.MinDepth = 0.0f;
571 vp.MaxDepth = 1.0f;
572
573 device_->RSSetViewports(1, &vp);
574 }
575
576 CompositorWin::~CompositorWin() {
577 }
578
579 void CompositorWin::Errored(HRESULT error_code) {
580 // TODO: figure out error handling.
581 DCHECK(false);
582 }
583
584 void CompositorWin::CreateDevice() {
585 DXGI_SWAP_CHAIN_DESC sd;
586 sd.BufferDesc.Width = size().width();
587 sd.BufferDesc.Height = size().height();
588 sd.BufferDesc.RefreshRate.Numerator = 60;
589 sd.BufferDesc.RefreshRate.Denominator = 1;
590 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
591 sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
592 sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
593
594 // No multisampling.
595 sd.SampleDesc.Count = 1;
596 sd.SampleDesc.Quality = 0;
597
598 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
599 sd.BufferCount = 1;
600 sd.OutputWindow = host_;
601 sd.Windowed = true;
602 sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
603 sd.Flags = 0;
604
605 // Create the device.
606 UINT createDeviceFlags = 0;
607 #if !defined(NDEBUG)
608 createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
609 #endif
610 RETURN_IF_FAILED(
611 D3D10CreateDeviceAndSwapChain(
612 0, //default adapter
613 D3D10_DRIVER_TYPE_HARDWARE,
614 0, // no software device
615 createDeviceFlags,
616 D3D10_SDK_VERSION,
617 &sd,
618 swap_chain_.Receive(),
619 device_.Receive()));
620 }
621
622 void CompositorWin::LoadEffects() {
623 DWORD shader_flags = D3D10_SHADER_ENABLE_STRICTNESS;
624 #if !defined(NDEBUG)
625 shader_flags |= D3D10_SHADER_DEBUG | D3D10_SHADER_SKIP_OPTIMIZATION;
626 #endif
627 ScopedComPtr<ID3D10Blob> compilation_errors;
628 const base::StringPiece& fx_data = ResourceBundle::GetSharedInstance().
629 GetRawDataResource(IDR_COMPOSITOR_FX);
630 DCHECK(!fx_data.empty());
631 RETURN_IF_FAILED(
632 D3DX10CreateEffectFromMemory(
633 fx_data.data(), fx_data.size(), "compositor.fx", NULL, NULL,
634 "fx_4_0", shader_flags, 0, device_.get(), NULL, NULL, fx_.Receive(),
635 compilation_errors.Receive(), NULL));
636 technique_ = fx_->GetTechniqueByName("ViewTech");
637 DCHECK(technique_);
638
639 const base::StringPiece& blur_data = ResourceBundle::GetSharedInstance().
640 GetRawDataResource(IDR_BLUR_FX);
641 DCHECK(!blur_data.empty());
642 compilation_errors = NULL;
643 RETURN_IF_FAILED(
644 D3DX10CreateEffectFromMemory(
645 blur_data.data(), blur_data.size(), "bloom.fx", NULL, NULL,
646 "fx_4_0", shader_flags, 0, device_.get(), NULL, NULL,
647 blur_fx_.Receive(), compilation_errors.Receive(), NULL));
648 blur_technique_ = blur_fx_->GetTechniqueByName("ViewTech");
649 DCHECK(blur_technique_);
650 }
651
652 void CompositorWin::InitVertexLayout() {
653 D3D10_INPUT_ELEMENT_DESC vertex_desc[] = {
654 { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
655 D3D10_INPUT_PER_VERTEX_DATA, 0 },
656 { "TEXC", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12,
657 D3D10_INPUT_PER_VERTEX_DATA, 0 },
658 };
659
660 // Create the input layout
661 D3D10_PASS_DESC pass_desc;
662 RETURN_IF_FAILED(technique_->GetPassByIndex(0)->GetDesc(&pass_desc));
663 RETURN_IF_FAILED(
664 device_->CreateInputLayout(vertex_desc, ARRAYSIZE_UNSAFE(vertex_desc),
665 pass_desc.pIAInputSignature,
666 pass_desc.IAInputSignatureSize,
667 vertex_layout_.Receive()));
668 }
669
670 void CompositorWin::UpdateBlurKernel(Direction direction, int size) {
671 // Update the blur data.
672 const int kSize = 13;
673 float pixel_data[4 * kSize];
674 memset(pixel_data, 0, sizeof(float) * 4 * kSize);
675 for (int i = 0; i < kSize; ++i) {
676 pixel_data[i * 4 + ((direction == HORIZONTAL) ? 0 : 1)] =
677 static_cast<float>(i - (kSize / 2)) / static_cast<float>(size);
678 }
679 RETURN_IF_FAILED(blur_fx_->GetVariableByName("TexelKernel")->AsVector()->
680 SetFloatVectorArray(pixel_data, 0, kSize));
681 }
682
683 void CompositorWin::CreateTexture(
684 const gfx::Size& size,
685 ID3D10Texture2D** texture,
686 ID3D10RenderTargetView** render_target_view,
687 ID3D10ShaderResourceView** shader_resource_view) {
688 D3D10_TEXTURE2D_DESC texture_desc;
689 texture_desc.Width = size.width();
690 texture_desc.Height = size.height();
691 texture_desc.MipLevels = 1;
692 texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
693 texture_desc.SampleDesc.Count = 1;
694 texture_desc.SampleDesc.Quality = 0;
695 texture_desc.Usage = D3D10_USAGE_DEFAULT;
696 texture_desc.BindFlags =
697 D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
698 texture_desc.CPUAccessFlags = 0;
699 texture_desc.MiscFlags = 0;
700 texture_desc.ArraySize = 1;
701 RETURN_IF_FAILED(device_->CreateTexture2D(&texture_desc, NULL, texture));
702
703 RETURN_IF_FAILED(
704 device_->CreateShaderResourceView(*texture, NULL, shader_resource_view));
705
706 D3D10_RENDER_TARGET_VIEW_DESC render_target_view_desc;
707 render_target_view_desc.Format = texture_desc.Format;
708 render_target_view_desc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2DMS;
709 render_target_view_desc.Texture2D.MipSlice = 0;
710 RETURN_IF_FAILED(device_->CreateRenderTargetView(
711 *texture, &render_target_view_desc, render_target_view));
712 }
713
714 void CompositorWin::CreateVertexBuffer() {
715 vertex_buffer_.Release();
716
717 Vertex vertices[] = {
718 { D3DXVECTOR3(-1.0f, -1.0f, 0.0f), D3DXVECTOR2(0.0f, 1.0f) },
719 { D3DXVECTOR3(-1.0f, 1.0f, 0.0f), D3DXVECTOR2(0.0f, 0.0f) },
720 { D3DXVECTOR3( 1.0f, 1.0f, 0.0f), D3DXVECTOR2(1.0f, 0.0f) },
721 { D3DXVECTOR3( 1.0f, -1.0f, 0.0f), D3DXVECTOR2(1.0f, 1.0f) },
722 };
723
724 // Create the vertex buffer containing the points.
725 D3D10_BUFFER_DESC buffer_desc;
726 buffer_desc.Usage = D3D10_USAGE_IMMUTABLE;
727 buffer_desc.ByteWidth = sizeof(Vertex) * ARRAYSIZE_UNSAFE(vertices);
728 buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
729 buffer_desc.CPUAccessFlags = 0;
730 buffer_desc.MiscFlags = 0;
731 D3D10_SUBRESOURCE_DATA init_data;
732 init_data.pSysMem = vertices;
733 RETURN_IF_FAILED(device_->CreateBuffer(&buffer_desc, &init_data,
734 vertex_buffer_.Receive()));
735 }
736
737 void CompositorWin::CreateIndexBuffer() {
738 index_buffer_.Release();
739
740 // Then the index buffer.
741 DWORD indices[] = {
742 0, 1, 2,
743 0, 2, 3,
744 };
745 D3D10_BUFFER_DESC index_buffer;
746 index_buffer.Usage = D3D10_USAGE_IMMUTABLE;
747 index_buffer.ByteWidth = sizeof(DWORD) * ARRAYSIZE_UNSAFE(indices);
748 index_buffer.BindFlags = D3D10_BIND_INDEX_BUFFER;
749 index_buffer.CPUAccessFlags = 0;
750 index_buffer.MiscFlags = 0;
751 D3D10_SUBRESOURCE_DATA init_data;
752 init_data.pSysMem = indices;
753 RETURN_IF_FAILED(device_->CreateBuffer(&index_buffer, &init_data,
754 index_buffer_.Receive()));
755 }
756
757 ID3D10Buffer* CompositorWin::CreateVertexBufferForRegion(
758 const gfx::Rect& bounds) {
759 float x = static_cast<float>(bounds.x()) /
760 static_cast<float>(size().width()) * 2.0f - 1.0f;
761 float max_x =
762 x + bounds.width() / static_cast<float>(size().width()) * 2.0f;
763 float y =
764 static_cast<float>(size().height() - bounds.y() - bounds.height()) /
765 static_cast<float>(size().height()) * 2.0f - 1.0f;
766 float max_y =
767 y + bounds.height() / static_cast<float>(size().height()) * 2.0f;
768 float tex_x = x / 2.0f + .5f;
769 float max_tex_x = max_x / 2.0f + .5f;
770 float tex_y = 1.0f - (max_y + 1.0f) / 2.0f;
771 float max_tex_y = tex_y + (max_y - y) / 2.0f;
772 Vertex vertices[] = {
773 { D3DXVECTOR3( x, y, 0.0f), D3DXVECTOR2( tex_x, max_tex_y) },
774 { D3DXVECTOR3( x, max_y, 0.0f), D3DXVECTOR2( tex_x, tex_y) },
775 { D3DXVECTOR3(max_x, max_y, 0.0f), D3DXVECTOR2(max_tex_x, tex_y) },
776 { D3DXVECTOR3(max_x, y, 0.0f), D3DXVECTOR2(max_tex_x, max_tex_y) },
777 };
778
779 // Create the vertex buffer containing the points.
780 D3D10_BUFFER_DESC buffer_desc;
781 buffer_desc.Usage = D3D10_USAGE_IMMUTABLE;
782 buffer_desc.ByteWidth = sizeof(Vertex) * ARRAYSIZE_UNSAFE(vertices);
783 buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
784 buffer_desc.CPUAccessFlags = 0;
785 buffer_desc.MiscFlags = 0;
786 D3D10_SUBRESOURCE_DATA init_data;
787 init_data.pSysMem = vertices;
788 ID3D10Buffer* vertex_buffer = NULL;
789 // TODO: better error handling.
790 int error_code =
791 device_->CreateBuffer(&buffer_desc, &init_data, &vertex_buffer);
792 if (error_code != S_OK) {
793 Errored(error_code);
794 return NULL;
795 }
796 return vertex_buffer;
797 }
798
799 } // namespace
800
801 // static
802 Compositor* Compositor::Create(CompositorDelegate* delegate,
803 gfx::AcceleratedWidget widget,
804 const gfx::Size& size) {
805 CompositorWin* compositor = new CompositorWin(delegate, widget, size);
806 compositor->Init();
807 return compositor;
808 }
809
810 } // namespace ui
OLDNEW
« no previous file with comments | « ui/gfx/compositor/compositor_stub.cc ('k') | ui/gfx/compositor/debug_utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698