OLD | NEW |
(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/stl_util-inl.h" |
| 13 #include "base/string_piece.h" |
| 14 #include "base/win/scoped_comptr.h" |
| 15 #include "grit/gfx_resources.h" |
| 16 #include "third_party/skia/include/core/SkBitmap.h" |
| 17 #include "ui/base/resource/resource_bundle.h" |
| 18 #include "ui/gfx/canvas_skia.h" |
| 19 #include "ui/gfx/rect.h" |
| 20 #include "ui/gfx/transform.h" |
| 21 |
| 22 // TODO(sky): this is a hack, figure out real error handling. |
| 23 #define RETURN_IF_FAILED(error) \ |
| 24 if (error != S_OK) { \ |
| 25 this->Errored(error); \ |
| 26 VLOG(1) << "D3D failed" << error; \ |
| 27 return; \ |
| 28 } |
| 29 |
| 30 using base::win::ScopedComPtr; |
| 31 |
| 32 namespace ui { |
| 33 |
| 34 namespace { |
| 35 |
| 36 class ViewTexture; |
| 37 |
| 38 // ViewTexture talks to its host by way of this interface. |
| 39 class ViewTextureHost { |
| 40 public: |
| 41 // Invoked to update the perspective needed by this texture. |transform| is |
| 42 // the transform for the texture, and |size| the size of the texture. |
| 43 virtual void UpdatePerspective(const ui::Transform& transform, |
| 44 const gfx::Size& size) = 0; |
| 45 |
| 46 // Returns the overall size of the compositor. |
| 47 virtual const gfx::Size& GetHostSize() = 0; |
| 48 |
| 49 protected: |
| 50 virtual ~ViewTextureHost() {} |
| 51 }; |
| 52 |
| 53 // D3D 10 Texture implementation. Creates a quad representing the view and |
| 54 // a texture with the bitmap data. The quad has an origin of 0,0,0 with a size |
| 55 // matching that of |SetBitmap|. |
| 56 class ViewTexture : public Texture { |
| 57 public: |
| 58 ViewTexture(ViewTextureHost* host, |
| 59 ID3D10Device* device, |
| 60 ID3D10Effect* effect); |
| 61 |
| 62 ~ViewTexture(); |
| 63 |
| 64 void Init(); |
| 65 |
| 66 // Texture: |
| 67 virtual void SetBitmap(const SkBitmap& bitmap, |
| 68 const gfx::Point& origin, |
| 69 const gfx::Size& overall_size) OVERRIDE; |
| 70 virtual void Draw(const ui::Transform& transform) OVERRIDE; |
| 71 |
| 72 private: |
| 73 struct Vertex { |
| 74 D3DXVECTOR3 position; |
| 75 D3DXVECTOR2 texture_offset; |
| 76 }; |
| 77 |
| 78 void Errored(HRESULT result); |
| 79 |
| 80 void ConvertBitmapToD3DData(const SkBitmap& bitmap, |
| 81 scoped_array<uint32>* converted_data); |
| 82 |
| 83 void CreateVertexBuffer(const gfx::Size& size); |
| 84 |
| 85 // TODO: this should be shared among all textures. |
| 86 void CreateIndexBuffer(); |
| 87 |
| 88 ViewTextureHost* host_; |
| 89 |
| 90 // Size of the corresponding View. |
| 91 gfx::Size view_size_; |
| 92 |
| 93 ScopedComPtr<ID3D10Device> device_; |
| 94 ScopedComPtr<ID3D10Effect, NULL> effect_; |
| 95 ScopedComPtr<ID3D10Texture2D> texture_; |
| 96 ScopedComPtr<ID3D10ShaderResourceView> shader_view_; |
| 97 ScopedComPtr<ID3D10Buffer> vertex_buffer_; |
| 98 ScopedComPtr<ID3D10Buffer> index_buffer_; |
| 99 |
| 100 DISALLOW_COPY_AND_ASSIGN(ViewTexture); |
| 101 }; |
| 102 |
| 103 ViewTexture::ViewTexture(ViewTextureHost* host, |
| 104 ID3D10Device* device, |
| 105 ID3D10Effect* effect) |
| 106 : host_(host), |
| 107 device_(device), |
| 108 effect_(effect) { |
| 109 } |
| 110 |
| 111 ViewTexture::~ViewTexture() { |
| 112 } |
| 113 |
| 114 void ViewTexture::Init() { |
| 115 CreateIndexBuffer(); |
| 116 } |
| 117 |
| 118 void ViewTexture::SetBitmap(const SkBitmap& bitmap, |
| 119 const gfx::Point& origin, |
| 120 const gfx::Size& overall_size) { |
| 121 if (view_size_ != overall_size) |
| 122 CreateVertexBuffer(overall_size); |
| 123 view_size_ = overall_size; |
| 124 |
| 125 scoped_array<uint32> converted_data; |
| 126 ConvertBitmapToD3DData(bitmap, &converted_data); |
| 127 if (gfx::Size(bitmap.width(), bitmap.height()) == overall_size) { |
| 128 shader_view_.Release(); |
| 129 texture_.Release(); |
| 130 |
| 131 D3D10_TEXTURE2D_DESC texture_desc; |
| 132 texture_desc.Width = bitmap.width(); |
| 133 texture_desc.Height = bitmap.height(); |
| 134 texture_desc.MipLevels = 1; |
| 135 texture_desc.ArraySize = 1; |
| 136 texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; |
| 137 texture_desc.SampleDesc.Count = 1; |
| 138 texture_desc.SampleDesc.Quality = 0; |
| 139 texture_desc.Usage = D3D10_USAGE_DEFAULT; |
| 140 texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; |
| 141 texture_desc.CPUAccessFlags = 0; |
| 142 texture_desc.MiscFlags = 0; |
| 143 D3D10_SUBRESOURCE_DATA texture_data; |
| 144 texture_data.pSysMem = converted_data.get(); |
| 145 texture_data.SysMemPitch = texture_desc.Width * 4; |
| 146 texture_data.SysMemSlicePitch = 0; |
| 147 RETURN_IF_FAILED(device_->CreateTexture2D(&texture_desc, |
| 148 &texture_data, |
| 149 texture_.Receive())); |
| 150 RETURN_IF_FAILED( |
| 151 device_->CreateShaderResourceView(texture_.get(), NULL, |
| 152 shader_view_.Receive())); |
| 153 } else { |
| 154 // Only part of the texture was updated. |
| 155 DCHECK(texture_.get()); |
| 156 D3D10_BOX dst_box = { origin.x(), origin.y(), 0, |
| 157 origin.x() + bitmap.width(), |
| 158 origin.y() + bitmap.height(), 0 }; |
| 159 device_->UpdateSubresource(texture_.get(), 0, &dst_box, |
| 160 converted_data.get(), bitmap.width() * 4, 0); |
| 161 } |
| 162 } |
| 163 |
| 164 void ViewTexture::Draw(const ui::Transform& transform) { |
| 165 host_->UpdatePerspective(transform, view_size_); |
| 166 |
| 167 // Make texture active. |
| 168 RETURN_IF_FAILED( |
| 169 effect_->GetVariableByName("textureMap")->AsShaderResource()-> |
| 170 SetResource(shader_view_.get())); |
| 171 |
| 172 ID3D10EffectTechnique* technique = effect_->GetTechniqueByName("ViewTech"); |
| 173 DCHECK(technique); |
| 174 D3D10_TECHNIQUE_DESC tech_desc; |
| 175 technique->GetDesc(&tech_desc); |
| 176 for(UINT p = 0; p < tech_desc.Passes; ++p) |
| 177 technique->GetPassByIndex(p)->Apply(0); |
| 178 |
| 179 UINT stride = sizeof(Vertex); |
| 180 UINT offset = 0; |
| 181 ID3D10Buffer* vertex_buffer = vertex_buffer_.get(); |
| 182 device_->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset); |
| 183 device_->IASetIndexBuffer(index_buffer_.get(), DXGI_FORMAT_R32_UINT, 0); |
| 184 device_->DrawIndexed(6, 0, 0); |
| 185 } |
| 186 |
| 187 void ViewTexture::Errored(HRESULT result) { |
| 188 // TODO: figure out error handling. |
| 189 DCHECK(false); |
| 190 } |
| 191 |
| 192 void ViewTexture::ConvertBitmapToD3DData(const SkBitmap& bitmap, |
| 193 scoped_array<uint32>* converted_data) { |
| 194 int width = bitmap.width(); |
| 195 int height = bitmap.height(); |
| 196 SkAutoLockPixels pixel_lock(bitmap); |
| 197 // D3D wants the data in a different format (and not pre-multiplied). |
| 198 converted_data->reset(new uint32[width * height]); |
| 199 for (int x = 0; x < width; ++x) { |
| 200 for (int y = 0; y < height; ++y) { |
| 201 SkColor color = bitmap.getColor(x, y); |
| 202 int alpha = SkColorGetA(color); |
| 203 (*converted_data)[y * width + x] = |
| 204 (SkColorGetA(color) << 24) | |
| 205 (SkColorGetB(color) << 16) | |
| 206 (SkColorGetG(color) << 8) | |
| 207 (SkColorGetR(color)); |
| 208 } |
| 209 } |
| 210 } |
| 211 |
| 212 void ViewTexture::CreateVertexBuffer(const gfx::Size& size) { |
| 213 vertex_buffer_.Release(); |
| 214 const gfx::Size& host_size = host_->GetHostSize(); |
| 215 float x = static_cast<float>(host_size.width()) / 2.0f; |
| 216 float y = static_cast<float>(host_size.height()) / 2.0f; |
| 217 float w = static_cast<float>(size.width()); |
| 218 float h = static_cast<float>(size.height()); |
| 219 Vertex vertices[] = { |
| 220 { D3DXVECTOR3(0.0f, -h, 0.0f), D3DXVECTOR2(0.0f, 1.0f) }, |
| 221 { D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR2(0.0f, 0.0f) }, |
| 222 { D3DXVECTOR3( w, 0.0f, 0.0f), D3DXVECTOR2(1.0f, 0.0f) }, |
| 223 { D3DXVECTOR3( w, -h, 0.0f), D3DXVECTOR2(1.0f, 1.0f) }, |
| 224 }; |
| 225 |
| 226 // Create the vertex buffer containing the points. |
| 227 D3D10_BUFFER_DESC buffer_desc; |
| 228 buffer_desc.Usage = D3D10_USAGE_IMMUTABLE; |
| 229 buffer_desc.ByteWidth = sizeof(Vertex) * ARRAYSIZE_UNSAFE(vertices); |
| 230 buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; |
| 231 buffer_desc.CPUAccessFlags = 0; |
| 232 buffer_desc.MiscFlags = 0; |
| 233 D3D10_SUBRESOURCE_DATA init_data; |
| 234 init_data.pSysMem = vertices; |
| 235 RETURN_IF_FAILED(device_->CreateBuffer(&buffer_desc, &init_data, |
| 236 vertex_buffer_.Receive())); |
| 237 } |
| 238 |
| 239 void ViewTexture::CreateIndexBuffer() { |
| 240 index_buffer_.Release(); |
| 241 |
| 242 // Then the index buffer. |
| 243 DWORD indices[] = { |
| 244 0, 1, 2, |
| 245 0, 2, 3, |
| 246 }; |
| 247 D3D10_BUFFER_DESC index_buffer; |
| 248 index_buffer.Usage = D3D10_USAGE_IMMUTABLE; |
| 249 index_buffer.ByteWidth = sizeof(DWORD) * ARRAYSIZE_UNSAFE(indices); |
| 250 index_buffer.BindFlags = D3D10_BIND_INDEX_BUFFER; |
| 251 index_buffer.CPUAccessFlags = 0; |
| 252 index_buffer.MiscFlags = 0; |
| 253 D3D10_SUBRESOURCE_DATA init_data2; |
| 254 init_data2.pSysMem = indices; |
| 255 RETURN_IF_FAILED(device_->CreateBuffer(&index_buffer, &init_data2, |
| 256 index_buffer_.Receive())); |
| 257 } |
| 258 |
| 259 // D3D 10 Compositor implementation. |
| 260 class CompositorWin : public Compositor, public ViewTextureHost { |
| 261 public: |
| 262 explicit CompositorWin(gfx::AcceleratedWidget widget); |
| 263 |
| 264 void Init(); |
| 265 |
| 266 // ViewTextureHost. |
| 267 virtual void UpdatePerspective(const ui::Transform& transform, |
| 268 const gfx::Size& view_size) OVERRIDE; |
| 269 virtual const gfx::Size& GetHostSize() OVERRIDE; |
| 270 |
| 271 // Compositor: |
| 272 virtual Texture* CreateTexture() OVERRIDE; |
| 273 virtual void NotifyStart() OVERRIDE; |
| 274 virtual void NotifyEnd() OVERRIDE; |
| 275 |
| 276 private: |
| 277 ~CompositorWin(); |
| 278 |
| 279 void Errored(HRESULT error_code); |
| 280 |
| 281 // Returns the bounds of the hosting window. |
| 282 gfx::Rect HostBounds(); |
| 283 |
| 284 void CreateDevice(); |
| 285 |
| 286 void LoadEffects(); |
| 287 |
| 288 void InitVertexLayout(); |
| 289 |
| 290 void Resize(const gfx::Rect& bounds); |
| 291 |
| 292 gfx::AcceleratedWidget host_; |
| 293 |
| 294 // Bounds the device was last created at. |
| 295 gfx::Rect last_bounds_; |
| 296 |
| 297 ScopedComPtr<ID3D10Device> device_; |
| 298 ScopedComPtr<IDXGISwapChain> swap_chain_; |
| 299 ScopedComPtr<ID3D10RenderTargetView> render_target_view_; |
| 300 ScopedComPtr<ID3D10Texture2D> depth_stencil_buffer_; |
| 301 ScopedComPtr<ID3D10DepthStencilView> depth_stencil_view_; |
| 302 ScopedComPtr<ID3D10Effect, NULL> fx_; |
| 303 ID3D10EffectTechnique* technique_; |
| 304 ScopedComPtr<ID3D10InputLayout> vertex_layout_; |
| 305 |
| 306 DISALLOW_COPY_AND_ASSIGN(CompositorWin); |
| 307 }; |
| 308 |
| 309 CompositorWin::CompositorWin(gfx::AcceleratedWidget widget) |
| 310 : host_(widget), |
| 311 technique_(NULL) { |
| 312 } |
| 313 |
| 314 void CompositorWin::Init() { |
| 315 CreateDevice(); |
| 316 LoadEffects(); |
| 317 Resize(last_bounds_); |
| 318 InitVertexLayout(); |
| 319 } |
| 320 |
| 321 void CompositorWin::UpdatePerspective(const ui::Transform& transform, |
| 322 const gfx::Size& view_size) { |
| 323 // Apply transform from view. |
| 324 const SkMatrix& sk_matrix(transform.matrix()); |
| 325 // Use -1 * kMTransY for y-translation as origin for views is upper left. |
| 326 D3DXMATRIX transform_matrix( |
| 327 // row 1 |
| 328 sk_matrix[SkMatrix::kMScaleX], sk_matrix[SkMatrix::kMSkewX], 0.0f, |
| 329 sk_matrix[SkMatrix::kMPersp0], |
| 330 // row 2 |
| 331 sk_matrix[SkMatrix::kMSkewY], sk_matrix[SkMatrix::kMScaleY], 0.0f, |
| 332 sk_matrix[SkMatrix::kMPersp1], |
| 333 // row 3 |
| 334 0.0f, 0.0f, 1.0f, sk_matrix[SkMatrix::kMPersp2], |
| 335 // row 4. |
| 336 sk_matrix[SkMatrix::kMTransX], -sk_matrix[SkMatrix::kMTransY], 0.0f, |
| 337 1.0f); |
| 338 |
| 339 // Scale so x and y are from 0-2. |
| 340 D3DXMATRIX scale_matrix; |
| 341 D3DXMatrixScaling( |
| 342 &scale_matrix, |
| 343 2.0f / static_cast<float>(last_bounds_.width()), |
| 344 2.0f / static_cast<float>(last_bounds_.height()), |
| 345 1.0f); |
| 346 |
| 347 // Translate so x and y are from -1,-1 to 1,1. |
| 348 D3DXMATRIX translate_matrix; |
| 349 D3DXMatrixTranslation(&translate_matrix, -1.0f, 1.0f, 0.0f); |
| 350 |
| 351 D3DXMATRIX projection_matrix; |
| 352 D3DXMatrixIdentity(&projection_matrix); |
| 353 D3DXMatrixPerspectiveFovLH(&projection_matrix, |
| 354 atanf(.5f) * 2.0f, 1.0f, 1.0f, 1000.0f); |
| 355 D3DXVECTOR3 pos(0.0f, 0.0f, -2.0f); |
| 356 D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); |
| 357 D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); |
| 358 D3DXMATRIX view; |
| 359 D3DXMatrixIdentity(&view); |
| 360 D3DXMatrixLookAtLH(&view, &pos, &target, &up); |
| 361 |
| 362 D3DXMATRIX wvp = transform_matrix * scale_matrix * translate_matrix * view * |
| 363 projection_matrix; |
| 364 fx_->GetVariableByName("gWVP")->AsMatrix()->SetMatrix((float*)&wvp); |
| 365 } |
| 366 |
| 367 const gfx::Size& CompositorWin::GetHostSize() { |
| 368 return last_bounds_.size(); |
| 369 } |
| 370 |
| 371 Texture* CompositorWin::CreateTexture() { |
| 372 ViewTexture* texture = new ViewTexture(this, device_.get(), fx_.get()); |
| 373 texture->Init(); |
| 374 return texture; |
| 375 } |
| 376 |
| 377 void CompositorWin::NotifyStart() { |
| 378 gfx::Rect bounds = HostBounds(); |
| 379 if (bounds != last_bounds_) |
| 380 Resize(bounds); |
| 381 |
| 382 // Clear the background and stencil view. |
| 383 device_->ClearRenderTargetView(render_target_view_.get(), |
| 384 D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f)); |
| 385 device_->ClearDepthStencilView( |
| 386 depth_stencil_view_.get(), D3D10_CLEAR_DEPTH|D3D10_CLEAR_STENCIL, |
| 387 1.0f, 0); |
| 388 |
| 389 // TODO: these steps may not be necessary each time through. |
| 390 device_->OMSetDepthStencilState(0, 0); |
| 391 float blend_factors[] = {0.0f, 0.0f, 0.0f, 0.0f}; |
| 392 device_->OMSetBlendState(0, blend_factors, 0xffffffff); |
| 393 device_->IASetInputLayout(vertex_layout_.get()); |
| 394 device_->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); |
| 395 } |
| 396 |
| 397 void CompositorWin::NotifyEnd() { |
| 398 swap_chain_->Present(0, 0); |
| 399 |
| 400 // We may delete the shader resource view before drawing again. Unset it so |
| 401 // that d3d doesn't generate a warning when we do that. |
| 402 fx_->GetVariableByName("textureMap")->AsShaderResource()-> |
| 403 SetResource(NULL); |
| 404 D3D10_TECHNIQUE_DESC tech_desc; |
| 405 technique_->GetDesc(&tech_desc); |
| 406 for(UINT i = 0; i < tech_desc.Passes; ++i) |
| 407 technique_->GetPassByIndex(i)->Apply(0); |
| 408 } |
| 409 |
| 410 CompositorWin::~CompositorWin() { |
| 411 } |
| 412 |
| 413 void CompositorWin::Errored(HRESULT error_code) { |
| 414 // TODO: figure out error handling. |
| 415 DCHECK(false); |
| 416 } |
| 417 |
| 418 gfx::Rect CompositorWin::HostBounds() { |
| 419 RECT client_rect; |
| 420 GetClientRect(host_, &client_rect); |
| 421 return gfx::Rect(client_rect); |
| 422 } |
| 423 |
| 424 void CompositorWin::CreateDevice() { |
| 425 last_bounds_ = HostBounds(); |
| 426 |
| 427 DXGI_SWAP_CHAIN_DESC sd; |
| 428 sd.BufferDesc.Width = last_bounds_.width(); |
| 429 sd.BufferDesc.Height = last_bounds_.height(); |
| 430 sd.BufferDesc.RefreshRate.Numerator = 60; |
| 431 sd.BufferDesc.RefreshRate.Denominator = 1; |
| 432 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; |
| 433 sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; |
| 434 sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; |
| 435 |
| 436 // No multisampling. |
| 437 sd.SampleDesc.Count = 1; |
| 438 sd.SampleDesc.Quality = 0; |
| 439 |
| 440 sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; |
| 441 sd.BufferCount = 1; |
| 442 sd.OutputWindow = host_; |
| 443 sd.Windowed = true; |
| 444 sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; |
| 445 sd.Flags = 0; |
| 446 |
| 447 // Create the device. |
| 448 UINT createDeviceFlags = 0; |
| 449 #if !defined(NDEBUG) |
| 450 createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG; |
| 451 #endif |
| 452 RETURN_IF_FAILED( |
| 453 D3D10CreateDeviceAndSwapChain( |
| 454 0, //default adapter |
| 455 D3D10_DRIVER_TYPE_HARDWARE, |
| 456 0, // no software device |
| 457 createDeviceFlags, |
| 458 D3D10_SDK_VERSION, |
| 459 &sd, |
| 460 swap_chain_.Receive(), |
| 461 device_.Receive())); |
| 462 } |
| 463 |
| 464 void CompositorWin::LoadEffects() { |
| 465 DWORD shader_flags = D3D10_SHADER_ENABLE_STRICTNESS; |
| 466 #if !defined(NDEBUG) |
| 467 shader_flags |= D3D10_SHADER_DEBUG | D3D10_SHADER_SKIP_OPTIMIZATION; |
| 468 #endif |
| 469 ScopedComPtr<ID3D10Blob> compilation_errors; |
| 470 const base::StringPiece& fx_data = ResourceBundle::GetSharedInstance(). |
| 471 GetRawDataResource(IDR_COMPOSITOR_FX); |
| 472 DCHECK(!fx_data.empty()); |
| 473 RETURN_IF_FAILED( |
| 474 D3DX10CreateEffectFromMemory( |
| 475 fx_data.data(), fx_data.size(), "compositor.fx", NULL, NULL, |
| 476 "fx_4_0", shader_flags, 0, device_.get(), NULL, NULL, fx_.Receive(), |
| 477 compilation_errors.Receive(), NULL)); |
| 478 technique_ = fx_->GetTechniqueByName("ViewTech"); |
| 479 DCHECK(technique_); |
| 480 } |
| 481 |
| 482 void CompositorWin::InitVertexLayout() { |
| 483 D3D10_INPUT_ELEMENT_DESC vertex_desc[] = { |
| 484 { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, |
| 485 D3D10_INPUT_PER_VERTEX_DATA, 0 }, |
| 486 { "TEXC", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, |
| 487 D3D10_INPUT_PER_VERTEX_DATA, 0 }, |
| 488 }; |
| 489 |
| 490 // Create the input layout |
| 491 D3D10_PASS_DESC pass_desc; |
| 492 RETURN_IF_FAILED(technique_->GetPassByIndex(0)->GetDesc(&pass_desc)); |
| 493 RETURN_IF_FAILED( |
| 494 device_->CreateInputLayout(vertex_desc, ARRAYSIZE_UNSAFE(vertex_desc), |
| 495 pass_desc.pIAInputSignature, |
| 496 pass_desc.IAInputSignatureSize, |
| 497 vertex_layout_.Receive())); |
| 498 } |
| 499 |
| 500 void CompositorWin::Resize(const gfx::Rect& bounds) { |
| 501 render_target_view_ = NULL; |
| 502 depth_stencil_buffer_ = NULL; |
| 503 depth_stencil_view_ = NULL; |
| 504 |
| 505 // Resize the swap chain and recreate the render target view. |
| 506 RETURN_IF_FAILED(swap_chain_->ResizeBuffers( |
| 507 1, bounds.width(), bounds.height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0)); |
| 508 ScopedComPtr<ID3D10Texture2D> back_buffer; |
| 509 RETURN_IF_FAILED(swap_chain_->GetBuffer( |
| 510 0, __uuidof(ID3D10Texture2D), |
| 511 reinterpret_cast<void**>(back_buffer.Receive()))); |
| 512 RETURN_IF_FAILED(device_->CreateRenderTargetView( |
| 513 back_buffer.get(), 0, render_target_view_.Receive())); |
| 514 |
| 515 // Create the depth/stencil buffer and view. |
| 516 D3D10_TEXTURE2D_DESC depth_stencil_desc; |
| 517 depth_stencil_desc.Width = bounds.width(); |
| 518 depth_stencil_desc.Height = bounds.height(); |
| 519 depth_stencil_desc.MipLevels = 1; |
| 520 depth_stencil_desc.ArraySize = 1; |
| 521 depth_stencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; |
| 522 depth_stencil_desc.SampleDesc.Count = 1; // multisampling must match |
| 523 depth_stencil_desc.SampleDesc.Quality = 0; // swap chain values. |
| 524 depth_stencil_desc.Usage = D3D10_USAGE_DEFAULT; |
| 525 depth_stencil_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL; |
| 526 depth_stencil_desc.CPUAccessFlags = 0; |
| 527 depth_stencil_desc.MiscFlags = 0; |
| 528 |
| 529 RETURN_IF_FAILED(device_->CreateTexture2D(&depth_stencil_desc, 0, |
| 530 depth_stencil_buffer_.Receive())); |
| 531 RETURN_IF_FAILED(device_->CreateDepthStencilView( |
| 532 depth_stencil_buffer_.get(), 0, |
| 533 depth_stencil_view_.Receive())); |
| 534 |
| 535 |
| 536 // Bind the render target view and depth/stencil view to the pipeline. |
| 537 ID3D10RenderTargetView* target_view = render_target_view_.get(); |
| 538 device_->OMSetRenderTargets(1, &target_view, depth_stencil_view_.get()); |
| 539 |
| 540 // Set the viewport transform. |
| 541 D3D10_VIEWPORT vp; |
| 542 vp.TopLeftX = bounds.x(); |
| 543 vp.TopLeftY = bounds.y(); |
| 544 vp.Width = bounds.width(); |
| 545 vp.Height = bounds.height(); |
| 546 vp.MinDepth = 0.0f; |
| 547 vp.MaxDepth = 1.0f; |
| 548 |
| 549 device_->RSSetViewports(1, &vp); |
| 550 |
| 551 last_bounds_ = bounds; |
| 552 } |
| 553 |
| 554 } // namespace |
| 555 |
| 556 // static |
| 557 Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { |
| 558 CompositorWin* compositor = new CompositorWin(widget); |
| 559 compositor->Init(); |
| 560 return compositor; |
| 561 } |
| 562 |
| 563 } // namespace ui |
OLD | NEW |