Index: ui/gfx/compositor/compositor_win.cc |
diff --git a/ui/gfx/compositor/compositor_win.cc b/ui/gfx/compositor/compositor_win.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a303f7bba088c15a25b3adc5f7cba971c3b5c77c |
--- /dev/null |
+++ b/ui/gfx/compositor/compositor_win.cc |
@@ -0,0 +1,563 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/gfx/compositor/compositor.h" |
+ |
+#include <algorithm> |
+#include <d3dx10.h> |
+#include <vector> |
+ |
+#include "base/compiler_specific.h" |
+#include "base/stl_util-inl.h" |
+#include "base/string_piece.h" |
+#include "base/win/scoped_comptr.h" |
+#include "grit/gfx_resources.h" |
+#include "third_party/skia/include/core/SkBitmap.h" |
+#include "ui/base/resource/resource_bundle.h" |
+#include "ui/gfx/canvas_skia.h" |
+#include "ui/gfx/rect.h" |
+#include "ui/gfx/transform.h" |
+ |
+// TODO(sky): this is a hack, figure out real error handling. |
+#define RETURN_IF_FAILED(error) \ |
+ if (error != S_OK) { \ |
+ this->Errored(error); \ |
+ VLOG(1) << "D3D failed" << error; \ |
+ return; \ |
+ } |
+ |
+using base::win::ScopedComPtr; |
+ |
+namespace ui { |
+ |
+namespace { |
+ |
+class ViewTexture; |
+ |
+// ViewTexture talks to its host by way of this interface. |
+class ViewTextureHost { |
+ public: |
+ // Invoked to update the perspective needed by this texture. |transform| is |
+ // the transform for the texture, and |size| the size of the texture. |
+ virtual void UpdatePerspective(const ui::Transform& transform, |
+ const gfx::Size& size) = 0; |
+ |
+ // Returns the overall size of the compositor. |
+ virtual const gfx::Size& GetHostSize() = 0; |
+ |
+ protected: |
+ virtual ~ViewTextureHost() {} |
+}; |
+ |
+// D3D 10 Texture implementation. Creates a quad representing the view and |
+// a texture with the bitmap data. The quad has an origin of 0,0,0 with a size |
+// matching that of |SetBitmap|. |
+class ViewTexture : public Texture { |
+ public: |
+ ViewTexture(ViewTextureHost* host, |
+ ID3D10Device* device, |
+ ID3D10Effect* effect); |
+ |
+ ~ViewTexture(); |
+ |
+ void Init(); |
+ |
+ // Texture: |
+ virtual void SetBitmap(const SkBitmap& bitmap, |
+ const gfx::Point& origin, |
+ const gfx::Size& overall_size) OVERRIDE; |
+ virtual void Draw(const ui::Transform& transform) OVERRIDE; |
+ |
+ private: |
+ struct Vertex { |
+ D3DXVECTOR3 position; |
+ D3DXVECTOR2 texture_offset; |
+ }; |
+ |
+ void Errored(HRESULT result); |
+ |
+ void ConvertBitmapToD3DData(const SkBitmap& bitmap, |
+ scoped_array<uint32>* converted_data); |
+ |
+ void CreateVertexBuffer(const gfx::Size& size); |
+ |
+ // TODO: this should be shared among all textures. |
+ void CreateIndexBuffer(); |
+ |
+ ViewTextureHost* host_; |
+ |
+ // Size of the corresponding View. |
+ gfx::Size view_size_; |
+ |
+ ScopedComPtr<ID3D10Device> device_; |
+ ScopedComPtr<ID3D10Effect, NULL> effect_; |
+ ScopedComPtr<ID3D10Texture2D> texture_; |
+ ScopedComPtr<ID3D10ShaderResourceView> shader_view_; |
+ ScopedComPtr<ID3D10Buffer> vertex_buffer_; |
+ ScopedComPtr<ID3D10Buffer> index_buffer_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ViewTexture); |
+}; |
+ |
+ViewTexture::ViewTexture(ViewTextureHost* host, |
+ ID3D10Device* device, |
+ ID3D10Effect* effect) |
+ : host_(host), |
+ device_(device), |
+ effect_(effect) { |
+} |
+ |
+ViewTexture::~ViewTexture() { |
+} |
+ |
+void ViewTexture::Init() { |
+ CreateIndexBuffer(); |
+} |
+ |
+void ViewTexture::SetBitmap(const SkBitmap& bitmap, |
+ const gfx::Point& origin, |
+ const gfx::Size& overall_size) { |
+ if (view_size_ != overall_size) |
+ CreateVertexBuffer(overall_size); |
+ view_size_ = overall_size; |
+ |
+ scoped_array<uint32> converted_data; |
+ ConvertBitmapToD3DData(bitmap, &converted_data); |
+ if (gfx::Size(bitmap.width(), bitmap.height()) == overall_size) { |
+ shader_view_.Release(); |
+ texture_.Release(); |
+ |
+ D3D10_TEXTURE2D_DESC texture_desc; |
+ texture_desc.Width = bitmap.width(); |
+ texture_desc.Height = bitmap.height(); |
+ texture_desc.MipLevels = 1; |
+ texture_desc.ArraySize = 1; |
+ texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; |
+ texture_desc.SampleDesc.Count = 1; |
+ texture_desc.SampleDesc.Quality = 0; |
+ texture_desc.Usage = D3D10_USAGE_DEFAULT; |
+ texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE; |
+ texture_desc.CPUAccessFlags = 0; |
+ texture_desc.MiscFlags = 0; |
+ D3D10_SUBRESOURCE_DATA texture_data; |
+ texture_data.pSysMem = converted_data.get(); |
+ texture_data.SysMemPitch = texture_desc.Width * 4; |
+ texture_data.SysMemSlicePitch = 0; |
+ RETURN_IF_FAILED(device_->CreateTexture2D(&texture_desc, |
+ &texture_data, |
+ texture_.Receive())); |
+ RETURN_IF_FAILED( |
+ device_->CreateShaderResourceView(texture_.get(), NULL, |
+ shader_view_.Receive())); |
+ } else { |
+ // Only part of the texture was updated. |
+ DCHECK(texture_.get()); |
+ D3D10_BOX dst_box = { origin.x(), origin.y(), 0, |
+ origin.x() + bitmap.width(), |
+ origin.y() + bitmap.height(), 0 }; |
+ device_->UpdateSubresource(texture_.get(), 0, &dst_box, |
+ converted_data.get(), bitmap.width() * 4, 0); |
+ } |
+} |
+ |
+void ViewTexture::Draw(const ui::Transform& transform) { |
+ host_->UpdatePerspective(transform, view_size_); |
+ |
+ // Make texture active. |
+ RETURN_IF_FAILED( |
+ effect_->GetVariableByName("textureMap")->AsShaderResource()-> |
+ SetResource(shader_view_.get())); |
+ |
+ ID3D10EffectTechnique* technique = effect_->GetTechniqueByName("ViewTech"); |
+ DCHECK(technique); |
+ D3D10_TECHNIQUE_DESC tech_desc; |
+ technique->GetDesc(&tech_desc); |
+ for(UINT p = 0; p < tech_desc.Passes; ++p) |
+ technique->GetPassByIndex(p)->Apply(0); |
+ |
+ UINT stride = sizeof(Vertex); |
+ UINT offset = 0; |
+ ID3D10Buffer* vertex_buffer = vertex_buffer_.get(); |
+ device_->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset); |
+ device_->IASetIndexBuffer(index_buffer_.get(), DXGI_FORMAT_R32_UINT, 0); |
+ device_->DrawIndexed(6, 0, 0); |
+} |
+ |
+void ViewTexture::Errored(HRESULT result) { |
+ // TODO: figure out error handling. |
+ DCHECK(false); |
+} |
+ |
+void ViewTexture::ConvertBitmapToD3DData(const SkBitmap& bitmap, |
+ scoped_array<uint32>* converted_data) { |
+ int width = bitmap.width(); |
+ int height = bitmap.height(); |
+ SkAutoLockPixels pixel_lock(bitmap); |
+ // D3D wants the data in a different format (and not pre-multiplied). |
+ converted_data->reset(new uint32[width * height]); |
+ for (int x = 0; x < width; ++x) { |
+ for (int y = 0; y < height; ++y) { |
+ SkColor color = bitmap.getColor(x, y); |
+ int alpha = SkColorGetA(color); |
+ (*converted_data)[y * width + x] = |
+ (SkColorGetA(color) << 24) | |
+ (SkColorGetB(color) << 16) | |
+ (SkColorGetG(color) << 8) | |
+ (SkColorGetR(color)); |
+ } |
+ } |
+} |
+ |
+void ViewTexture::CreateVertexBuffer(const gfx::Size& size) { |
+ vertex_buffer_.Release(); |
+ const gfx::Size& host_size = host_->GetHostSize(); |
+ float x = static_cast<float>(host_size.width()) / 2.0f; |
+ float y = static_cast<float>(host_size.height()) / 2.0f; |
+ float w = static_cast<float>(size.width()); |
+ float h = static_cast<float>(size.height()); |
+ Vertex vertices[] = { |
+ { D3DXVECTOR3(0.0f, -h, 0.0f), D3DXVECTOR2(0.0f, 1.0f) }, |
+ { D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR2(0.0f, 0.0f) }, |
+ { D3DXVECTOR3( w, 0.0f, 0.0f), D3DXVECTOR2(1.0f, 0.0f) }, |
+ { D3DXVECTOR3( w, -h, 0.0f), D3DXVECTOR2(1.0f, 1.0f) }, |
+ }; |
+ |
+ // Create the vertex buffer containing the points. |
+ D3D10_BUFFER_DESC buffer_desc; |
+ buffer_desc.Usage = D3D10_USAGE_IMMUTABLE; |
+ buffer_desc.ByteWidth = sizeof(Vertex) * ARRAYSIZE_UNSAFE(vertices); |
+ buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER; |
+ buffer_desc.CPUAccessFlags = 0; |
+ buffer_desc.MiscFlags = 0; |
+ D3D10_SUBRESOURCE_DATA init_data; |
+ init_data.pSysMem = vertices; |
+ RETURN_IF_FAILED(device_->CreateBuffer(&buffer_desc, &init_data, |
+ vertex_buffer_.Receive())); |
+} |
+ |
+void ViewTexture::CreateIndexBuffer() { |
+ index_buffer_.Release(); |
+ |
+ // Then the index buffer. |
+ DWORD indices[] = { |
+ 0, 1, 2, |
+ 0, 2, 3, |
+ }; |
+ D3D10_BUFFER_DESC index_buffer; |
+ index_buffer.Usage = D3D10_USAGE_IMMUTABLE; |
+ index_buffer.ByteWidth = sizeof(DWORD) * ARRAYSIZE_UNSAFE(indices); |
+ index_buffer.BindFlags = D3D10_BIND_INDEX_BUFFER; |
+ index_buffer.CPUAccessFlags = 0; |
+ index_buffer.MiscFlags = 0; |
+ D3D10_SUBRESOURCE_DATA init_data2; |
+ init_data2.pSysMem = indices; |
+ RETURN_IF_FAILED(device_->CreateBuffer(&index_buffer, &init_data2, |
+ index_buffer_.Receive())); |
+} |
+ |
+// D3D 10 Compositor implementation. |
+class CompositorWin : public Compositor, public ViewTextureHost { |
+ public: |
+ explicit CompositorWin(gfx::AcceleratedWidget widget); |
+ |
+ void Init(); |
+ |
+ // ViewTextureHost. |
+ virtual void UpdatePerspective(const ui::Transform& transform, |
+ const gfx::Size& view_size) OVERRIDE; |
+ virtual const gfx::Size& GetHostSize() OVERRIDE; |
+ |
+ // Compositor: |
+ virtual Texture* CreateTexture() OVERRIDE; |
+ virtual void NotifyStart() OVERRIDE; |
+ virtual void NotifyEnd() OVERRIDE; |
+ |
+ private: |
+ ~CompositorWin(); |
+ |
+ void Errored(HRESULT error_code); |
+ |
+ // Returns the bounds of the hosting window. |
+ gfx::Rect HostBounds(); |
+ |
+ void CreateDevice(); |
+ |
+ void LoadEffects(); |
+ |
+ void InitVertexLayout(); |
+ |
+ void Resize(const gfx::Rect& bounds); |
+ |
+ gfx::AcceleratedWidget host_; |
+ |
+ // Bounds the device was last created at. |
+ gfx::Rect last_bounds_; |
+ |
+ ScopedComPtr<ID3D10Device> device_; |
+ ScopedComPtr<IDXGISwapChain> swap_chain_; |
+ ScopedComPtr<ID3D10RenderTargetView> render_target_view_; |
+ ScopedComPtr<ID3D10Texture2D> depth_stencil_buffer_; |
+ ScopedComPtr<ID3D10DepthStencilView> depth_stencil_view_; |
+ ScopedComPtr<ID3D10Effect, NULL> fx_; |
+ ID3D10EffectTechnique* technique_; |
+ ScopedComPtr<ID3D10InputLayout> vertex_layout_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CompositorWin); |
+}; |
+ |
+CompositorWin::CompositorWin(gfx::AcceleratedWidget widget) |
+ : host_(widget), |
+ technique_(NULL) { |
+} |
+ |
+void CompositorWin::Init() { |
+ CreateDevice(); |
+ LoadEffects(); |
+ Resize(last_bounds_); |
+ InitVertexLayout(); |
+} |
+ |
+void CompositorWin::UpdatePerspective(const ui::Transform& transform, |
+ const gfx::Size& view_size) { |
+ // Apply transform from view. |
+ const SkMatrix& sk_matrix(transform.matrix()); |
+ // Use -1 * kMTransY for y-translation as origin for views is upper left. |
+ D3DXMATRIX transform_matrix( |
+ // row 1 |
+ sk_matrix[SkMatrix::kMScaleX], sk_matrix[SkMatrix::kMSkewX], 0.0f, |
+ sk_matrix[SkMatrix::kMPersp0], |
+ // row 2 |
+ sk_matrix[SkMatrix::kMSkewY], sk_matrix[SkMatrix::kMScaleY], 0.0f, |
+ sk_matrix[SkMatrix::kMPersp1], |
+ // row 3 |
+ 0.0f, 0.0f, 1.0f, sk_matrix[SkMatrix::kMPersp2], |
+ // row 4. |
+ sk_matrix[SkMatrix::kMTransX], -sk_matrix[SkMatrix::kMTransY], 0.0f, |
+ 1.0f); |
+ |
+ // Scale so x and y are from 0-2. |
+ D3DXMATRIX scale_matrix; |
+ D3DXMatrixScaling( |
+ &scale_matrix, |
+ 2.0f / static_cast<float>(last_bounds_.width()), |
+ 2.0f / static_cast<float>(last_bounds_.height()), |
+ 1.0f); |
+ |
+ // Translate so x and y are from -1,-1 to 1,1. |
+ D3DXMATRIX translate_matrix; |
+ D3DXMatrixTranslation(&translate_matrix, -1.0f, 1.0f, 0.0f); |
+ |
+ D3DXMATRIX projection_matrix; |
+ D3DXMatrixIdentity(&projection_matrix); |
+ D3DXMatrixPerspectiveFovLH(&projection_matrix, |
+ atanf(.5f) * 2.0f, 1.0f, 1.0f, 1000.0f); |
+ D3DXVECTOR3 pos(0.0f, 0.0f, -2.0f); |
+ D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); |
+ D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); |
+ D3DXMATRIX view; |
+ D3DXMatrixIdentity(&view); |
+ D3DXMatrixLookAtLH(&view, &pos, &target, &up); |
+ |
+ D3DXMATRIX wvp = transform_matrix * scale_matrix * translate_matrix * view * |
+ projection_matrix; |
+ fx_->GetVariableByName("gWVP")->AsMatrix()->SetMatrix((float*)&wvp); |
+} |
+ |
+const gfx::Size& CompositorWin::GetHostSize() { |
+ return last_bounds_.size(); |
+} |
+ |
+Texture* CompositorWin::CreateTexture() { |
+ ViewTexture* texture = new ViewTexture(this, device_.get(), fx_.get()); |
+ texture->Init(); |
+ return texture; |
+} |
+ |
+void CompositorWin::NotifyStart() { |
+ gfx::Rect bounds = HostBounds(); |
+ if (bounds != last_bounds_) |
+ Resize(bounds); |
+ |
+ // Clear the background and stencil view. |
+ device_->ClearRenderTargetView(render_target_view_.get(), |
+ D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f)); |
+ device_->ClearDepthStencilView( |
+ depth_stencil_view_.get(), D3D10_CLEAR_DEPTH|D3D10_CLEAR_STENCIL, |
+ 1.0f, 0); |
+ |
+ // TODO: these steps may not be necessary each time through. |
+ device_->OMSetDepthStencilState(0, 0); |
+ float blend_factors[] = {0.0f, 0.0f, 0.0f, 0.0f}; |
+ device_->OMSetBlendState(0, blend_factors, 0xffffffff); |
+ device_->IASetInputLayout(vertex_layout_.get()); |
+ device_->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST); |
+} |
+ |
+void CompositorWin::NotifyEnd() { |
+ swap_chain_->Present(0, 0); |
+ |
+ // We may delete the shader resource view before drawing again. Unset it so |
+ // that d3d doesn't generate a warning when we do that. |
+ fx_->GetVariableByName("textureMap")->AsShaderResource()-> |
+ SetResource(NULL); |
+ D3D10_TECHNIQUE_DESC tech_desc; |
+ technique_->GetDesc(&tech_desc); |
+ for(UINT i = 0; i < tech_desc.Passes; ++i) |
+ technique_->GetPassByIndex(i)->Apply(0); |
+} |
+ |
+CompositorWin::~CompositorWin() { |
+} |
+ |
+void CompositorWin::Errored(HRESULT error_code) { |
+ // TODO: figure out error handling. |
+ DCHECK(false); |
+} |
+ |
+gfx::Rect CompositorWin::HostBounds() { |
+ RECT client_rect; |
+ GetClientRect(host_, &client_rect); |
+ return gfx::Rect(client_rect); |
+} |
+ |
+void CompositorWin::CreateDevice() { |
+ last_bounds_ = HostBounds(); |
+ |
+ DXGI_SWAP_CHAIN_DESC sd; |
+ sd.BufferDesc.Width = last_bounds_.width(); |
+ sd.BufferDesc.Height = last_bounds_.height(); |
+ sd.BufferDesc.RefreshRate.Numerator = 60; |
+ sd.BufferDesc.RefreshRate.Denominator = 1; |
+ sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; |
+ sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; |
+ sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; |
+ |
+ // No multisampling. |
+ sd.SampleDesc.Count = 1; |
+ sd.SampleDesc.Quality = 0; |
+ |
+ sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; |
+ sd.BufferCount = 1; |
+ sd.OutputWindow = host_; |
+ sd.Windowed = true; |
+ sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; |
+ sd.Flags = 0; |
+ |
+ // Create the device. |
+ UINT createDeviceFlags = 0; |
+#if !defined(NDEBUG) |
+ createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG; |
+#endif |
+ RETURN_IF_FAILED( |
+ D3D10CreateDeviceAndSwapChain( |
+ 0, //default adapter |
+ D3D10_DRIVER_TYPE_HARDWARE, |
+ 0, // no software device |
+ createDeviceFlags, |
+ D3D10_SDK_VERSION, |
+ &sd, |
+ swap_chain_.Receive(), |
+ device_.Receive())); |
+} |
+ |
+void CompositorWin::LoadEffects() { |
+ DWORD shader_flags = D3D10_SHADER_ENABLE_STRICTNESS; |
+#if !defined(NDEBUG) |
+ shader_flags |= D3D10_SHADER_DEBUG | D3D10_SHADER_SKIP_OPTIMIZATION; |
+#endif |
+ ScopedComPtr<ID3D10Blob> compilation_errors; |
+ const base::StringPiece& fx_data = ResourceBundle::GetSharedInstance(). |
+ GetRawDataResource(IDR_COMPOSITOR_FX); |
+ DCHECK(!fx_data.empty()); |
+ RETURN_IF_FAILED( |
+ D3DX10CreateEffectFromMemory( |
+ fx_data.data(), fx_data.size(), "compositor.fx", NULL, NULL, |
+ "fx_4_0", shader_flags, 0, device_.get(), NULL, NULL, fx_.Receive(), |
+ compilation_errors.Receive(), NULL)); |
+ technique_ = fx_->GetTechniqueByName("ViewTech"); |
+ DCHECK(technique_); |
+} |
+ |
+void CompositorWin::InitVertexLayout() { |
+ D3D10_INPUT_ELEMENT_DESC vertex_desc[] = { |
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, |
+ D3D10_INPUT_PER_VERTEX_DATA, 0 }, |
+ { "TEXC", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, |
+ D3D10_INPUT_PER_VERTEX_DATA, 0 }, |
+ }; |
+ |
+ // Create the input layout |
+ D3D10_PASS_DESC pass_desc; |
+ RETURN_IF_FAILED(technique_->GetPassByIndex(0)->GetDesc(&pass_desc)); |
+ RETURN_IF_FAILED( |
+ device_->CreateInputLayout(vertex_desc, ARRAYSIZE_UNSAFE(vertex_desc), |
+ pass_desc.pIAInputSignature, |
+ pass_desc.IAInputSignatureSize, |
+ vertex_layout_.Receive())); |
+} |
+ |
+void CompositorWin::Resize(const gfx::Rect& bounds) { |
+ render_target_view_ = NULL; |
+ depth_stencil_buffer_ = NULL; |
+ depth_stencil_view_ = NULL; |
+ |
+ // Resize the swap chain and recreate the render target view. |
+ RETURN_IF_FAILED(swap_chain_->ResizeBuffers( |
+ 1, bounds.width(), bounds.height(), DXGI_FORMAT_R8G8B8A8_UNORM, 0)); |
+ ScopedComPtr<ID3D10Texture2D> back_buffer; |
+ RETURN_IF_FAILED(swap_chain_->GetBuffer( |
+ 0, __uuidof(ID3D10Texture2D), |
+ reinterpret_cast<void**>(back_buffer.Receive()))); |
+ RETURN_IF_FAILED(device_->CreateRenderTargetView( |
+ back_buffer.get(), 0, render_target_view_.Receive())); |
+ |
+ // Create the depth/stencil buffer and view. |
+ D3D10_TEXTURE2D_DESC depth_stencil_desc; |
+ depth_stencil_desc.Width = bounds.width(); |
+ depth_stencil_desc.Height = bounds.height(); |
+ depth_stencil_desc.MipLevels = 1; |
+ depth_stencil_desc.ArraySize = 1; |
+ depth_stencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; |
+ depth_stencil_desc.SampleDesc.Count = 1; // multisampling must match |
+ depth_stencil_desc.SampleDesc.Quality = 0; // swap chain values. |
+ depth_stencil_desc.Usage = D3D10_USAGE_DEFAULT; |
+ depth_stencil_desc.BindFlags = D3D10_BIND_DEPTH_STENCIL; |
+ depth_stencil_desc.CPUAccessFlags = 0; |
+ depth_stencil_desc.MiscFlags = 0; |
+ |
+ RETURN_IF_FAILED(device_->CreateTexture2D(&depth_stencil_desc, 0, |
+ depth_stencil_buffer_.Receive())); |
+ RETURN_IF_FAILED(device_->CreateDepthStencilView( |
+ depth_stencil_buffer_.get(), 0, |
+ depth_stencil_view_.Receive())); |
+ |
+ |
+ // Bind the render target view and depth/stencil view to the pipeline. |
+ ID3D10RenderTargetView* target_view = render_target_view_.get(); |
+ device_->OMSetRenderTargets(1, &target_view, depth_stencil_view_.get()); |
+ |
+ // Set the viewport transform. |
+ D3D10_VIEWPORT vp; |
+ vp.TopLeftX = bounds.x(); |
+ vp.TopLeftY = bounds.y(); |
+ vp.Width = bounds.width(); |
+ vp.Height = bounds.height(); |
+ vp.MinDepth = 0.0f; |
+ vp.MaxDepth = 1.0f; |
+ |
+ device_->RSSetViewports(1, &vp); |
+ |
+ last_bounds_ = bounds; |
+} |
+ |
+} // namespace |
+ |
+// static |
+Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { |
+ CompositorWin* compositor = new CompositorWin(widget); |
+ compositor->Init(); |
+ return compositor; |
+} |
+ |
+} // namespace ui |