Home | History | Annotate | Download | only in metro_driver
      1 // Copyright 2012 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 "stdafx.h"
      6 #include "win8/metro_driver/direct3d_helper.h"
      7 #include "win8/metro_driver/winrt_utils.h"
      8 
      9 #include "base/logging.h"
     10 
     11 #include <windows.graphics.display.h>
     12 
     13 namespace {
     14 
     15 void CheckIfFailed(HRESULT hr) {
     16   DCHECK(!FAILED(hr));
     17   if (FAILED(hr))
     18     DVLOG(0) << "Direct3D call failed, hr = " << hr;
     19 }
     20 
     21 float GetLogicalDpi() {
     22   mswr::ComPtr<wingfx::Display::IDisplayPropertiesStatics> display_properties;
     23   CheckIfFailed(winrt_utils::CreateActivationFactory(
     24       RuntimeClass_Windows_Graphics_Display_DisplayProperties,
     25       display_properties.GetAddressOf()));
     26   float dpi = 0.0;
     27   CheckIfFailed(display_properties->get_LogicalDpi(&dpi));
     28   return dpi;
     29 }
     30 
     31 float ConvertDipsToPixels(float dips) {
     32   static const float dips_per_inch = 96.f;
     33   float logical_dpi = GetLogicalDpi();
     34   return floor(dips * logical_dpi / dips_per_inch + 0.5f);
     35 }
     36 
     37 }
     38 
     39 namespace metro_driver {
     40 
     41 Direct3DHelper::Direct3DHelper() {
     42 }
     43 
     44 Direct3DHelper::~Direct3DHelper() {
     45 }
     46 
     47 void Direct3DHelper::Initialize(winui::Core::ICoreWindow* window) {
     48   window_ = window;
     49   CreateDeviceResources();
     50   CreateWindowSizeDependentResources();
     51 }
     52 
     53 // TODO(scottmg): Need to handle resize messages and recreation.
     54 
     55 void Direct3DHelper::CreateDeviceResources() {
     56   unsigned int creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
     57   D3D_FEATURE_LEVEL feature_levels[] = {
     58     D3D_FEATURE_LEVEL_11_1,
     59     D3D_FEATURE_LEVEL_11_0,
     60     D3D_FEATURE_LEVEL_10_1,
     61     D3D_FEATURE_LEVEL_10_0,
     62     D3D_FEATURE_LEVEL_9_3,
     63     D3D_FEATURE_LEVEL_9_2,
     64     D3D_FEATURE_LEVEL_9_1,
     65   };
     66 
     67   mswr::ComPtr<ID3D11Device> device;
     68   mswr::ComPtr<ID3D11DeviceContext> context;
     69   CheckIfFailed(
     70       D3D11CreateDevice(
     71           nullptr,
     72           D3D_DRIVER_TYPE_HARDWARE,
     73           nullptr,
     74           creation_flags,
     75           feature_levels,
     76           ARRAYSIZE(feature_levels),
     77           D3D11_SDK_VERSION,
     78           &device,
     79           &feature_level_,
     80           &context));
     81   CheckIfFailed(device.As(&d3d_device_));
     82   CheckIfFailed(context.As(&d3d_context_));
     83 }
     84 
     85 void Direct3DHelper::CreateWindowSizeDependentResources() {
     86   CheckIfFailed(window_->get_Bounds(&window_bounds_));
     87   float window_width = ConvertDipsToPixels(window_bounds_.Width);
     88   float window_height = ConvertDipsToPixels(window_bounds_.Height);
     89 
     90   // TODO(scottmg): Orientation.
     91 
     92   if (swap_chain_ != nullptr) {
     93     // TODO(scottmg): Resize if it already exists.
     94     NOTIMPLEMENTED();
     95   } else {
     96     DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = { 0 };
     97     swap_chain_desc.Width = window_width;
     98     swap_chain_desc.Height = window_height;
     99     swap_chain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    100     swap_chain_desc.Stereo = false;
    101     swap_chain_desc.SampleDesc.Count = 1;
    102     swap_chain_desc.SampleDesc.Quality = 0;
    103     swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    104     swap_chain_desc.BufferCount = 2; // TODO(scottmg): Probably 1 is fine.
    105     swap_chain_desc.Scaling = DXGI_SCALING_NONE;
    106     swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
    107     swap_chain_desc.Flags = 0;
    108 
    109     mswr::ComPtr<IDXGIDevice1> dxgi_device;
    110     CheckIfFailed(d3d_device_.As(&dxgi_device));
    111 
    112     mswr::ComPtr<IDXGIAdapter> dxgi_adapter;
    113     CheckIfFailed(dxgi_device->GetAdapter(&dxgi_adapter));
    114 
    115     mswr::ComPtr<IDXGIFactory2> dxgi_factory;
    116     CheckIfFailed(dxgi_adapter->GetParent(
    117         __uuidof(IDXGIFactory2), &dxgi_factory));
    118 
    119     CheckIfFailed(dxgi_factory->CreateSwapChainForCoreWindow(
    120         d3d_device_.Get(),
    121         reinterpret_cast<IUnknown*>(window_),
    122         &swap_chain_desc,
    123         nullptr,
    124         &swap_chain_));
    125   }
    126 }
    127 
    128 }  // namespace metro_driver
    129