#include "stdafx.h" #include "OutputDevice.h" #include "DisplayMode.h" OutputDevice::OutputDevice(IDXGIOutput* ar_Output_, ID3D10Device* ar_Device_) : m_Output(ar_Output_) , m_Device(ar_Device_) , m_HasEnumerated(false) , m_DesiredWidth(0) , m_DesiredHeight(0) , m_DesiredRefreshRate(0) , m_DesiredFormat(DataFormat::Unknown) { if (m_Output != NULL) { m_Output->AddRef(); m_Output->GetDesc(&m_OutputDesc); } } OutputDevice::~OutputDevice() { for (uint32 i = 0; i < m_DisplayModes.size(); ++i) delete m_DisplayModes[i]; if (m_Output != NULL) m_Output->Release(); m_Output = NULL; } bool OutputDevice::TryEnumerate(uint32 argDesiredWidth, uint32 argDesiredHeight, uint32 argDesiredRefreshRate, DataFormat::Enumeration argDesiredFormat) { if (m_HasEnumerated) { if (m_DesiredWidth == argDesiredWidth || m_DesiredHeight == argDesiredHeight || m_DesiredRefreshRate == argDesiredRefreshRate || m_DesiredFormat == argDesiredFormat) { return true; } else m_HasEnumerated = false; } for (int formatIndex = (int)argDesiredFormat; formatIndex <= (argDesiredFormat == DataFormat::Unknown ? DXGI_FORMAT_B8G8R8X8_UNORM : (int)argDesiredFormat); ++formatIndex) { DXGI_FORMAT format = (DXGI_FORMAT)formatIndex; uint32 flags = DXGI_ENUM_MODES_SCALING; uint32 displayModeCount = 0; if (m_Output->GetDisplayModeList(format, flags, &displayModeCount, 0) == S_OK && displayModeCount > 0) { DXGI_MODE_DESC* descs = new DXGI_MODE_DESC[displayModeCount]; if (m_Output->GetDisplayModeList(format, flags, &displayModeCount, descs) == S_OK) { for (uint32 i = 0; i < displayModeCount; ++i) { IDisplayMode* displayMode = new DisplayMode(descs[i]); bool keepDisplayMode = false; if ((argDesiredWidth == 0 || argDesiredWidth <= displayMode->get_Width()) && (argDesiredHeight == 0 || argDesiredHeight <= displayMode->get_Height()) && (argDesiredRefreshRate == 0 || argDesiredRefreshRate <= displayMode->get_RefreshRate()) && (argDesiredFormat == DataFormat::Unknown || argDesiredFormat == displayMode->get_Format())) { if (m_Device != NULL) { uint32 supportBits = 0; m_Device->CheckFormatSupport((DXGI_FORMAT)format, &supportBits); if ((supportBits & D3D10_FORMAT_SUPPORT_DISPLAY) != 0) keepDisplayMode = true; } else keepDisplayMode = true; } if (keepDisplayMode) m_DisplayModes.push_back(displayMode); else delete displayMode; } delete [] descs; } } } m_DesiredWidth = argDesiredWidth; m_DesiredHeight = argDesiredHeight; m_DesiredRefreshRate = argDesiredRefreshRate; m_DesiredFormat = argDesiredFormat; m_HasEnumerated = !m_DisplayModes.empty(); return m_HasEnumerated; } IDisplayMode* OutputDevice::FindBestDisplayMode(bool argAllowToEnumerate, uint32 argDesiredWidth, uint32 argDesiredHeight, uint32 argDesiredRefreshRate, DataFormat::Enumeration argDesiredFormat) { if (argAllowToEnumerate && !this->TryEnumerate(argDesiredWidth, argDesiredHeight, argDesiredRefreshRate, argDesiredFormat)) return NULL; if (!m_HasEnumerated) return NULL; return m_DisplayModes.back(); }