diff options
-rw-r--r-- | addons/resource.language.en_gb/resources/strings.po | 18 | ||||
-rwxr-xr-x | system/settings/settings.xml | 10 | ||||
-rw-r--r-- | xbmc/Application.cpp | 2 | ||||
-rw-r--r-- | xbmc/guilib/GUIWindowManager.cpp | 13 | ||||
-rw-r--r-- | xbmc/guilib/WindowIDs.dox | 1 | ||||
-rw-r--r-- | xbmc/guilib/WindowIDs.h | 1 | ||||
-rw-r--r-- | xbmc/input/WindowTranslator.cpp | 1 | ||||
-rw-r--r-- | xbmc/rendering/dx/CMakeLists.txt | 2 | ||||
-rw-r--r-- | xbmc/rendering/dx/GUIWindowTestPatternDX.cpp | 376 | ||||
-rw-r--r-- | xbmc/rendering/dx/GUIWindowTestPatternDX.h | 42 | ||||
-rw-r--r-- | xbmc/rendering/gl/CMakeLists.txt | 6 | ||||
-rw-r--r-- | xbmc/rendering/gl/GUIWindowTestPatternGL.cpp | 185 | ||||
-rw-r--r-- | xbmc/rendering/gl/GUIWindowTestPatternGL.h | 31 | ||||
-rw-r--r-- | xbmc/settings/windows/CMakeLists.txt | 6 | ||||
-rw-r--r-- | xbmc/settings/windows/GUIWindowTestPattern.cpp | 126 | ||||
-rw-r--r-- | xbmc/settings/windows/GUIWindowTestPattern.h | 48 |
16 files changed, 861 insertions, 7 deletions
diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po index 0357593630..1f862ceaa9 100644 --- a/addons/resource.language.en_gb/resources/strings.po +++ b/addons/resource.language.en_gb/resources/strings.po @@ -1046,7 +1046,10 @@ msgctxt "#225" msgid "Vertical shift" msgstr "" -#empty string with id 226 +#: system/settings/settings.xml +msgctxt "#226" +msgid "Test patterns..." +msgstr "" #: system/settings/settings.xml msgctxt "#227" @@ -4813,7 +4816,12 @@ msgctxt "#10007" msgid "System information" msgstr "" -#empty strings from id 10008 to 10010 +#: xbmc/guilib/WindowIDs.h +msgctxt "#10008" +msgid "Settings - Test patterns" +msgstr "" + +#empty strings from id 10009 to 10010 #: xbmc/guilib/WindowIDs.h msgctxt "#10011" @@ -19284,7 +19292,11 @@ msgctxt "#36357" msgid "Calibrate the user interface by adjusting the overscan. Use this tool if the image being displayed is too large or small for your display." msgstr "" -#empty string with id 36358 +#. Description of setting with label #226 "Test patterns..." +#: system/settings/settings.xml +msgctxt "#36358" +msgid "Test patterns for display hardware calibration." +msgstr "" #. Description of setting with label #36042 "Use limited colour range (16-235)" #: system/settings/settings.xml diff --git a/system/settings/settings.xml b/system/settings/settings.xml index c5945132a2..395d5816c2 100755 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -2397,6 +2397,16 @@ <level>3</level> <control type="button" format="action" /> </setting> + <setting id="videoscreen.testpattern" type="action" label="226" help="36358"> + <requirement> + <or> + <condition>HAS_GL</condition> + <condition>HAS_DX</condition> + </or> + </requirement> + <level>3</level> + <control type="button" format="action" /> + </setting> </group> </category> <category id="audio" label="14221" help="36360"> diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index baf6405f0f..c6441673a9 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -1074,6 +1074,8 @@ void CApplication::OnSettingAction(std::shared_ptr<const CSetting> setting) } else if (settingId == CSettings::SETTING_VIDEOSCREEN_GUICALIBRATION) CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_SCREEN_CALIBRATION); + else if (settingId == CSettings::SETTING_VIDEOSCREEN_TESTPATTERN) + CServiceBroker::GetGUI()->GetWindowManager().ActivateWindow(WINDOW_TEST_PATTERN); else if (settingId == CSettings::SETTING_SOURCE_VIDEOS) { std::vector<std::string> params{"library://video/files.xml", "return"}; diff --git a/xbmc/guilib/GUIWindowManager.cpp b/xbmc/guilib/GUIWindowManager.cpp index d5fbae93c2..652aa4d9f7 100644 --- a/xbmc/guilib/GUIWindowManager.cpp +++ b/xbmc/guilib/GUIWindowManager.cpp @@ -40,6 +40,12 @@ #include "video/dialogs/GUIDialogVideoInfo.h" #include "video/windows/GUIWindowVideoNav.h" #include "profiles/windows/GUIWindowSettingsProfile.h" +#ifdef HAS_GL +#include "rendering/gl/GUIWindowTestPatternGL.h" +#endif +#ifdef HAS_DX +#include "rendering/dx/GUIWindowTestPatternDX.h" +#endif #include "settings/windows/GUIWindowSettingsScreenCalibration.h" #include "programs/GUIWindowPrograms.h" #include "pictures/GUIWindowPictures.h" @@ -178,6 +184,12 @@ void CGUIWindowManager::CreateWindows() Add(new CGUIWindowFileManager); Add(new CGUIWindowSettings); Add(new CGUIWindowSystemInfo); +#ifdef HAS_GL + Add(new CGUIWindowTestPatternGL); +#endif +#ifdef HAS_DX + Add(new CGUIWindowTestPatternDX); +#endif Add(new CGUIWindowSettingsScreenCalibration); Add(new CGUIWindowSettingsCategory); Add(new CGUIWindowVideoNav); @@ -395,6 +407,7 @@ bool CGUIWindowManager::DestroyWindows() DestroyWindow(WINDOW_VISUALISATION); DestroyWindow(WINDOW_SETTINGS_MENU); DestroyWindow(WINDOW_SETTINGS_PROFILES); + DestroyWindow(WINDOW_TEST_PATTERN); DestroyWindow(WINDOW_SCREEN_CALIBRATION); DestroyWindow(WINDOW_SYSTEM_INFORMATION); DestroyWindow(WINDOW_SCREENSAVER); diff --git a/xbmc/guilib/WindowIDs.dox b/xbmc/guilib/WindowIDs.dox index dd7e7f694a..3e75572523 100644 --- a/xbmc/guilib/WindowIDs.dox +++ b/xbmc/guilib/WindowIDs.dox @@ -14,6 +14,7 @@ This page shows the window names, the window definition, the window ID and the s | FileManager | WINDOW_FILES | 10003 | FileManager.xml | | Settings | WINDOW_SETTINGS_MENU | 10004 | Settings.xml | | SystemInfo | WINDOW_SYSTEM_INFORMATION | 10007 | SettingsSystemInfo.xml | +| TestPattern | WINDOW_TEST_PATTERN | 10008 | none | | ScreenCalibration | WINDOW_SCREEN_CALIBRATION | 10011 | SettingsScreenCalibration.xml | | SystemSettings | WINDOW_SETTINGS_SYSTEM | 10016 | SettingsCategory.xml | | ServiceSettings | WINDOW_SETTINGS_SERVICE | 10018 | SettingsCategory.xml | diff --git a/xbmc/guilib/WindowIDs.h b/xbmc/guilib/WindowIDs.h index 83b499b682..4df484bbf6 100644 --- a/xbmc/guilib/WindowIDs.h +++ b/xbmc/guilib/WindowIDs.h @@ -16,6 +16,7 @@ #define WINDOW_FILES 10003 #define WINDOW_SETTINGS_MENU 10004 #define WINDOW_SYSTEM_INFORMATION 10007 +#define WINDOW_TEST_PATTERN 10008 #define WINDOW_SCREEN_CALIBRATION 10011 #define WINDOW_SETTINGS_START 10016 diff --git a/xbmc/input/WindowTranslator.cpp b/xbmc/input/WindowTranslator.cpp index 0238e3c2e6..9d7a28129d 100644 --- a/xbmc/input/WindowTranslator.cpp +++ b/xbmc/input/WindowTranslator.cpp @@ -54,6 +54,7 @@ const CWindowTranslator::WindowMapByName CWindowTranslator::WindowMappingByName { "pvrosdguide" , WINDOW_DIALOG_PVR_CHANNEL_GUIDE }, // backward compatibility to v17 { "pvrosdteletext" , WINDOW_DIALOG_OSD_TELETEXT }, { "systeminfo" , WINDOW_SYSTEM_INFORMATION }, + { "testpattern" , WINDOW_TEST_PATTERN }, { "screencalibration" , WINDOW_SCREEN_CALIBRATION }, { "systemsettings" , WINDOW_SETTINGS_SYSTEM }, { "servicesettings" , WINDOW_SETTINGS_SERVICE }, diff --git a/xbmc/rendering/dx/CMakeLists.txt b/xbmc/rendering/dx/CMakeLists.txt index bf3dbf0181..8fabdf3eb3 100644 --- a/xbmc/rendering/dx/CMakeLists.txt +++ b/xbmc/rendering/dx/CMakeLists.txt @@ -1,8 +1,10 @@ set(SOURCES DeviceResources.cpp + GUIWindowTestPatternDX.cpp RenderSystemDX.cpp) set(HEADERS DeviceResources.h DirectXHelper.h + GUIWindowTestPatternDX.h RenderContext.h RenderSystemDX.h) diff --git a/xbmc/rendering/dx/GUIWindowTestPatternDX.cpp b/xbmc/rendering/dx/GUIWindowTestPatternDX.cpp new file mode 100644 index 0000000000..07cbb09e9e --- /dev/null +++ b/xbmc/rendering/dx/GUIWindowTestPatternDX.cpp @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * Test patterns designed by Ofer LaOr - hometheater.co.il + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "GUIWindowTestPatternDX.h" +#include "rendering/dx/DeviceResources.h" +#include "rendering/dx/RenderContext.h" +#ifndef M_PI + #define M_PI 3.14159265358979323846 +#endif + +#ifndef _d3d9TYPES_H_ +#include "DirectXPackedVector.h" +using namespace DirectX; +using namespace DirectX::PackedVector; +using namespace Microsoft::WRL; + +DWORD D3DCOLOR_COLORVALUE(float r, float g, float b, float a) +{ + XMCOLOR xColor; + XMVECTOR xVector = XMVectorSet(r, g, b, a); + XMStoreColor(&xColor, xVector); + DWORD color = xColor; + return color; +} +#endif + +CGUIWindowTestPatternDX::CGUIWindowTestPatternDX(void) : CGUIWindowTestPattern() +{ + m_vb = nullptr; + m_bufferWidth = 0; +} + +CGUIWindowTestPatternDX::~CGUIWindowTestPatternDX(void) +{ + m_vb = nullptr; + m_bufferWidth = 0; +} + +void CGUIWindowTestPatternDX::DrawVerticalLines(int top, int left, int bottom, int right) +{ + Vertex* vert = new Vertex[2 + (right - left)]; + int p = 0; + for (int i = left; i <= right; i += 2) + { + vert[p].pos.x = (float)i; + vert[p].pos.y = (float)top; + vert[p].pos.z = 0.5f; + vert[p].color = XMFLOAT4(m_white, m_white, m_white, 1.0f); + ++p; + vert[p].pos.x = (float)i; + vert[p].pos.y = (float)bottom; + vert[p].pos.z = 0.5f; + vert[p].color = XMFLOAT4(m_white, m_white, m_white, 1.0f); + ++p; + } + UpdateVertexBuffer(vert, p); + + ComPtr<ID3D11DeviceContext> pContext = DX::DeviceResources::Get()->GetD3DContext(); + CGUIShaderDX* pGUIShader = DX::Windowing()->GetGUIShader(); + + pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT); + unsigned stride = sizeof(Vertex), offset = 0; + pContext->IASetVertexBuffers(0, 1, m_vb.GetAddressOf(), &stride, &offset); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + pGUIShader->Draw(p, 0); + + delete [] vert; +} + +void CGUIWindowTestPatternDX::DrawHorizontalLines(int top, int left, int bottom, int right) +{ + Vertex* vert = new Vertex[2 + (bottom - top)]; + int p = 0; + for (int i = top; i <= bottom; i += 2) + { + vert[p].pos.x = (float)left; + vert[p].pos.y = (float)i; + vert[p].pos.z = 0.5f; + vert[p].color = XMFLOAT4(m_white, m_white, m_white, 1.0f); + ++p; + vert[p].pos.x = (float)right; + vert[p].pos.y = (float)i; + vert[p].pos.z = 0.5f; + vert[p].color = XMFLOAT4(m_white, m_white, m_white, 1.0f); + ++p; + } + UpdateVertexBuffer(vert, p); + + ComPtr<ID3D11DeviceContext> pContext = DX::DeviceResources::Get()->GetD3DContext(); + CGUIShaderDX* pGUIShader = DX::Windowing()->GetGUIShader(); + + pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT); + unsigned stride = sizeof(Vertex), offset = 0; + pContext->IASetVertexBuffers(0, 1, m_vb.GetAddressOf(), &stride, &offset); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + pGUIShader->Draw(p, 0); + + delete [] vert; +} + +void CGUIWindowTestPatternDX::DrawCheckers(int top, int left, int bottom, int right) +{ + int c = (bottom-top+1)*(1+(right-left)/2); + if (c < 1) + return; + Vertex* vert = new Vertex[c]; + int i=0; + for (int y = top; y <= bottom; y++) + { + for (int x = left; x <= right; x += 2) + { + if (y % 2 == 0) + { + vert[i].pos.x = (float)x; + vert[i].pos.y = (float)y; + vert[i].pos.z = 0.5f; + vert[i].color = XMFLOAT4(m_white, m_white, m_white, 1.0f); + } + else + { + vert[i].pos.x = (float)x+1.0f; + vert[i].pos.y = (float)y; + vert[i].pos.z = 0.5f; + vert[i].color = XMFLOAT4(m_white, m_white, m_white, 1.0f); + } + ++i; + } + } + UpdateVertexBuffer(vert, i); + + ComPtr<ID3D11DeviceContext> pContext = DX::DeviceResources::Get()->GetD3DContext(); + CGUIShaderDX* pGUIShader = DX::Windowing()->GetGUIShader(); + + pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT); + unsigned stride = sizeof(Vertex), offset = 0; + pContext->IASetVertexBuffers(0, 1, m_vb.GetAddressOf(), &stride, &offset); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); + pGUIShader->Draw(i, 0); + + delete [] vert; +} + +void CGUIWindowTestPatternDX::DrawBouncingRectangle(int top, int left, int bottom, int right) +{ + m_bounceX += m_bounceDirectionX; + m_bounceY += m_bounceDirectionY; + + if ((m_bounceDirectionX == 1 && m_bounceX + TEST_PATTERNS_BOUNCE_SQUARE_SIZE == right) || (m_bounceDirectionX == -1 && m_bounceX == left)) + m_bounceDirectionX = -m_bounceDirectionX; + + if ((m_bounceDirectionY == 1 && m_bounceY + TEST_PATTERNS_BOUNCE_SQUARE_SIZE == bottom) || (m_bounceDirectionY == -1 && m_bounceY == top)) + m_bounceDirectionY = -m_bounceDirectionY; + + DrawRectangle((float)m_bounceX, (float)m_bounceY, (float)(m_bounceX + TEST_PATTERNS_BOUNCE_SQUARE_SIZE), (float)(m_bounceY + TEST_PATTERNS_BOUNCE_SQUARE_SIZE), D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f)); +} + +void CGUIWindowTestPatternDX::DrawContrastBrightnessPattern(int top, int left, int bottom, int right) +{ + DWORD color; + DWORD color_white = D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f); + DWORD color_black = D3DCOLOR_COLORVALUE(m_black, m_black, m_black, 1.0f); + float x5p = (float) (left + (0.05f * (right - left))); + float y5p = (float) (top + (0.05f * (bottom - top))); + float x12p = (float) (left + (0.125f * (right - left))); + float y12p = (float) (top + (0.125f * (bottom - top))); + float x25p = (float) (left + (0.25f * (right - left))); + float y25p = (float) (top + (0.25f * (bottom - top))); + float x37p = (float) (left + (0.375f * (right - left))); + float y37p = (float) (top + (0.375f * (bottom - top))); + float x50p = (float)(left + (right - left) / 2); + float y50p = (float)(top + (bottom - top) / 2); + float x62p = (float) (left + (0.625f * (right - left))); + float y62p = (float) (top + (0.625f * (bottom - top))); + float x75p = (float) (left + (0.75f * (right - left))); + float y75p = (float) (top + (0.75f * (bottom - top))); + float x87p = (float) (left + (0.875f * (right - left))); + float y87p = (float) (top + (0.875f * (bottom - top))); + float x95p = (float) (left + (0.95f * (right - left))); + float y95p = (float) (top + (0.95f * (bottom - top))); + + m_blinkFrame = (m_blinkFrame + 1) % TEST_PATTERNS_BLINK_CYCLE; + + // draw main quadrants + DrawRectangle(x50p, (float)top, (float)right, y50p, color_white); + DrawRectangle((float)left, (float)y50p, x50p, (float)bottom, color_white); + + XMFLOAT4 xcolor_white, xcolor_black; + CD3DHelper::XMStoreColor(&xcolor_white, color_white); + CD3DHelper::XMStoreColor(&xcolor_black, color_black); + + // draw border lines + Vertex vert[] = + { + { XMFLOAT3((float)left, y5p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x50p, y5p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x5p, (float)top, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x5p, y50p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x50p, y95p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3((float)right, y95p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x95p, y50p, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x95p, (float)bottom, 0.5f), xcolor_white, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + + { XMFLOAT3(x50p, y5p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3((float)right, y5p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x5p, y50p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x5p, (float)bottom, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3((float)left, y95p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x50p, y95p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x95p, (float)top, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x95p, y50p, 0.5f), xcolor_black, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + }; + UpdateVertexBuffer(vert, ARRAYSIZE(vert)); + + ComPtr<ID3D11DeviceContext> pContext = DX::DeviceResources::Get()->GetD3DContext(); + CGUIShaderDX* pGUIShader = DX::Windowing()->GetGUIShader(); + + pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT); + unsigned stride = sizeof(Vertex), offset = 0; + pContext->IASetVertexBuffers(0, 1, m_vb.GetAddressOf(), &stride, &offset); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); + pGUIShader->Draw(ARRAYSIZE(vert), 0); + + // draw inner rectangles + DrawRectangle(x12p, y12p, x37p, y37p, color_white); + DrawRectangle(x62p, y62p, x87p, y87p, color_white); + + DrawRectangle(x62p, y12p, x87p, y37p, color_black); + DrawRectangle(x12p, y62p, x37p, y87p, color_black); + + // draw inner circles + if (m_blinkFrame < TEST_PATTERNS_BLINK_CYCLE / 2) + color = D3DCOLOR_COLORVALUE(m_black + 0.05f, m_black + 0.05f, m_black + 0.05f, 1.0f); + else + color = D3DCOLOR_COLORVALUE(0.0f, 0.0f, 0.0f, 1.0f); // BTB + DrawCircleEx(x25p, y75p, (y37p - y12p) / 3, color); + DrawCircleEx(x75p, y25p, (y37p - y12p) / 3, color); + + if (m_blinkFrame < TEST_PATTERNS_BLINK_CYCLE / 2) + color = D3DCOLOR_COLORVALUE(m_white - 0.05f, m_white - 0.05f, m_white - 0.05f, 1.0f); + else + color = D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f); // WTW + DrawCircleEx(x25p, y25p, (y37p - y12p) / 3, color); + DrawCircleEx(x75p, y75p, (y37p - y12p) / 3, color); +} + +void CGUIWindowTestPatternDX::DrawCircle(int originX, int originY, int radius) +{ + DrawCircleEx((float)originX, (float)originY, (float)radius, D3DCOLOR_COLORVALUE(m_white, m_white, m_white, 1.0f)); +} + +void CGUIWindowTestPatternDX::DrawCircleEx(float originX, float originY, float radius, DWORD color) +{ + float angle; + float vectorX; + float vectorY; + float vectorY1 = originY; + float vectorX1 = originX; + Vertex vert[1084]; // 361*3 + 1 + int p = 0; + + for (int i = 0; i <= 360; i++) + { + angle = (float)(((double)i)/57.29577957795135); + vectorX = originX + (radius*(float)sin((double)angle)); + vectorY = originY + (radius*(float)cos((double)angle)); + vert[p].pos.x = originX; + vert[p].pos.y = originY; + vert[p].pos.z = 0.5f; + CD3DHelper::XMStoreColor(&vert[p].color, color); + ++p; + vert[p].pos.x = vectorX1; + vert[p].pos.y = vectorY1; + vert[p].pos.z = 0.5f; + CD3DHelper::XMStoreColor(&vert[p].color, color); + ++p; + vert[p].pos.x = vectorX; + vert[p].pos.y = vectorY; + vert[p].pos.z = 0.5f; + CD3DHelper::XMStoreColor(&vert[p].color, color); + ++p; + vectorY1 = vectorY; + vectorX1 = vectorX; + } + vert[1083] = vert[0]; + + UpdateVertexBuffer(vert, ARRAYSIZE(vert)); + + ComPtr<ID3D11DeviceContext> pContext = DX::DeviceResources::Get()->GetD3DContext(); + CGUIShaderDX* pGUIShader = DX::Windowing()->GetGUIShader(); + + pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT); + unsigned stride = sizeof(Vertex), offset = 0; + pContext->IASetVertexBuffers(0, 1, m_vb.GetAddressOf(), &stride, &offset); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + pGUIShader->Draw(ARRAYSIZE(vert), 0); +} + +void CGUIWindowTestPatternDX::BeginRender() +{ + ComPtr<ID3D11DeviceContext> pContext = DX::DeviceResources::Get()->GetD3DContext(); + ID3D11RenderTargetView* renderTarget; + + pContext->OMGetRenderTargets(1, &renderTarget, NULL); + float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + pContext->ClearRenderTargetView(renderTarget, color); + renderTarget->Release(); +} + +void CGUIWindowTestPatternDX::EndRender() +{ + DX::Windowing()->GetGUIShader()->RestoreBuffers(); +} + +void CGUIWindowTestPatternDX::DrawRectangle(float x, float y, float x2, float y2, DWORD color) +{ + XMFLOAT4 float4; + CD3DHelper::XMStoreColor(&float4, color); + + Vertex vert[] = + { + { XMFLOAT3( x, y, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x2, y, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x2, y2, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x2, y2, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3(x, y2, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + { XMFLOAT3( x, y, 0.5f), float4, XMFLOAT2(0.0f, 0.0f), XMFLOAT2(0.0f, 0.0f) }, + }; + + UpdateVertexBuffer(vert, ARRAYSIZE(vert)); + + ComPtr<ID3D11DeviceContext> pContext = DX::DeviceResources::Get()->GetD3DContext(); + CGUIShaderDX* pGUIShader = DX::Windowing()->GetGUIShader(); + + pGUIShader->Begin(SHADER_METHOD_RENDER_DEFAULT); + unsigned stride = sizeof(Vertex), offset = 0; + pContext->IASetVertexBuffers(0, 1, m_vb.GetAddressOf(), &stride, &offset); + pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + pGUIShader->Draw(ARRAYSIZE(vert), 0); +} + +void CGUIWindowTestPatternDX::UpdateVertexBuffer(Vertex *vertices, unsigned count) +{ + unsigned width = sizeof(Vertex) * count; + + if (!m_vb || width > m_bufferWidth) // create new + { + CD3D11_BUFFER_DESC desc(width, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE); + D3D11_SUBRESOURCE_DATA initData = {}; + initData.pSysMem = vertices; + initData.SysMemPitch = width; + + ComPtr<ID3D11Device1> pDevice = DX::DeviceResources::Get()->GetD3DDevice(); + if (SUCCEEDED(pDevice->CreateBuffer(&desc, &initData, m_vb.ReleaseAndGetAddressOf()))) + { + m_bufferWidth = width; + } + return; + } + else // update + { + ComPtr<ID3D11DeviceContext> pContext = DX::DeviceResources::Get()->GetD3DContext(); + D3D11_MAPPED_SUBRESOURCE res; + if (SUCCEEDED(pContext->Map(m_vb.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &res))) + { + memcpy(res.pData, vertices, sizeof(Vertex) * count); + pContext->Unmap(m_vb.Get(), 0); + } + } +} diff --git a/xbmc/rendering/dx/GUIWindowTestPatternDX.h b/xbmc/rendering/dx/GUIWindowTestPatternDX.h new file mode 100644 index 0000000000..33bb01373e --- /dev/null +++ b/xbmc/rendering/dx/GUIWindowTestPatternDX.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * Test patterns designed by Ofer LaOr - hometheater.co.il + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "settings/windows/GUIWindowTestPattern.h" +#include "guilib/GUIShaderDX.h" + +#include <wrl/client.h> + +class CGUIWindowTestPatternDX : public CGUIWindowTestPattern +{ +public: + CGUIWindowTestPatternDX(void); + virtual ~CGUIWindowTestPatternDX(void); + +protected: + void DrawVerticalLines(int top, int left, int bottom, int right) override; + void DrawHorizontalLines(int top, int left, int bottom, int right) override; + void DrawCheckers(int top, int left, int bottom, int right) override; + void DrawBouncingRectangle(int top, int left, int bottom, int right) override; + void DrawContrastBrightnessPattern(int top, int left, int bottom, int right) override; + void DrawCircle(int originX, int originY, int radius) override; + void BeginRender() override; + void EndRender() override; + +private: + void UpdateVertexBuffer(Vertex *vertices, unsigned count); + void DrawRectangle(float x, float y, float x2, float y2, DWORD color); + void DrawCircleEx(float originX, float originY, float radius, DWORD color); + + unsigned m_bufferWidth; + Microsoft::WRL::ComPtr<ID3D11Buffer> m_vb; +}; + diff --git a/xbmc/rendering/gl/CMakeLists.txt b/xbmc/rendering/gl/CMakeLists.txt index f2b1e2dbb5..00fff7668f 100644 --- a/xbmc/rendering/gl/CMakeLists.txt +++ b/xbmc/rendering/gl/CMakeLists.txt @@ -1,8 +1,10 @@ -set(SOURCES RenderSystemGL.cpp +set(SOURCES GUIWindowTestPatternGL.cpp + RenderSystemGL.cpp ../MatrixGL.cpp GLShader.cpp) -set(HEADERS RenderSystemGL.h +set(HEADERS GUIWindowTestPatternGL.h + RenderSystemGL.h ../MatrixGL.h GLShader.h) diff --git a/xbmc/rendering/gl/GUIWindowTestPatternGL.cpp b/xbmc/rendering/gl/GUIWindowTestPatternGL.cpp new file mode 100644 index 0000000000..41158bbc59 --- /dev/null +++ b/xbmc/rendering/gl/GUIWindowTestPatternGL.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * Test patterns designed by Ofer LaOr - hometheater.co.il + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "system_gl.h" +#include "GUIWindowTestPatternGL.h" + +CGUIWindowTestPatternGL::CGUIWindowTestPatternGL(void) : CGUIWindowTestPattern() +{ +} + +CGUIWindowTestPatternGL::~CGUIWindowTestPatternGL(void) = default; + +void CGUIWindowTestPatternGL::DrawVerticalLines(int top, int left, int bottom, int right) +{ + glBegin(GL_LINES); + glColor3f(m_white, m_white, m_white); + for (int i = left; i <= right; i += 2) + { + glVertex2d(i, top); + glVertex2d(i, bottom); + } + glEnd(); +} + +void CGUIWindowTestPatternGL::DrawHorizontalLines(int top, int left, int bottom, int right) +{ + glBegin(GL_LINES); + glColor3f(m_white, m_white, m_white); + for (int i = top; i <= bottom; i += 2) + { + glVertex2d(left, i); + glVertex2d(right, i); + } + glEnd(); +} + +void CGUIWindowTestPatternGL::DrawCheckers(int top, int left, int bottom, int right) +{ + glBegin(GL_POINTS); + glColor3f(m_white, m_white, m_white); + for (int y = top; y <= bottom; y++) + { + for (int x = left; x <= right; x += 2) + { + if (y % 2 == 0) + glVertex2d(x, y); + else + glVertex2d(x+1, y); + } + } + glEnd(); +} + +void CGUIWindowTestPatternGL::DrawBouncingRectangle(int top, int left, int bottom, int right) +{ + m_bounceX += m_bounceDirectionX; + m_bounceY += m_bounceDirectionY; + + if ((m_bounceDirectionX == 1 && m_bounceX + TEST_PATTERNS_BOUNCE_SQUARE_SIZE == right) || (m_bounceDirectionX == -1 && m_bounceX == left)) + m_bounceDirectionX = -m_bounceDirectionX; + + if ((m_bounceDirectionY == 1 && m_bounceY + TEST_PATTERNS_BOUNCE_SQUARE_SIZE == bottom) || (m_bounceDirectionY == -1 && m_bounceY == top)) + m_bounceDirectionY = -m_bounceDirectionY; + + glColor3f(m_white, m_white, m_white); + glRecti(m_bounceX, m_bounceY, m_bounceX + TEST_PATTERNS_BOUNCE_SQUARE_SIZE, m_bounceY + TEST_PATTERNS_BOUNCE_SQUARE_SIZE); +} + +void CGUIWindowTestPatternGL::DrawContrastBrightnessPattern(int top, int left, int bottom, int right) +{ + int x5p = (int) (left + (0.05f * (right - left))); + int y5p = (int) (top + (0.05f * (bottom - top))); + int x12p = (int) (left + (0.125f * (right - left))); + int y12p = (int) (top + (0.125f * (bottom - top))); + int x25p = (int) (left + (0.25f * (right - left))); + int y25p = (int) (top + (0.25f * (bottom - top))); + int x37p = (int) (left + (0.375f * (right - left))); + int y37p = (int) (top + (0.375f * (bottom - top))); + int x50p = left + (right - left) / 2; + int y50p = top + (bottom - top) / 2; + int x62p = (int) (left + (0.625f * (right - left))); + int y62p = (int) (top + (0.625f * (bottom - top))); + int x75p = (int) (left + (0.75f * (right - left))); + int y75p = (int) (top + (0.75f * (bottom - top))); + int x87p = (int) (left + (0.875f * (right - left))); + int y87p = (int) (top + (0.875f * (bottom - top))); + int x95p = (int) (left + (0.95f * (right - left))); + int y95p = (int) (top + (0.95f * (bottom - top))); + + m_blinkFrame = (m_blinkFrame + 1) % TEST_PATTERNS_BLINK_CYCLE; + + // draw main quadrants + glColor3f(m_white, m_white, m_white); + glRecti(x50p, top, right, y50p); + glRecti(left, y50p, x50p, bottom); + + // draw border lines + glBegin(GL_LINES); + glColor3f(m_white, m_white, m_white); + glVertex2d(left, y5p); + glVertex2d(x50p, y5p); + glVertex2d(x5p, top); + glVertex2d(x5p, y50p); + glVertex2d(x50p, y95p); + glVertex2d(right, y95p); + glVertex2d(x95p, y50p); + glVertex2d(x95p, bottom); + + glColor3f(m_black, m_black, m_black); + glVertex2d(x50p, y5p); + glVertex2d(right, y5p); + glVertex2d(x5p, y50p); + glVertex2d(x5p, bottom); + glVertex2d(left, y95p); + glVertex2d(x50p, y95p); + glVertex2d(x95p, top); + glVertex2d(x95p, y50p); + glEnd(); + + // draw inner rectangles + glColor3f(m_white, m_white, m_white); + glRecti(x12p, y12p, x37p, y37p); + glRecti(x62p, y62p, x87p, y87p); + + glColor3f(m_black, m_black, m_black); + glRecti(x62p, y12p, x87p, y37p); + glRecti(x12p, y62p, x37p, y87p); + + // draw inner circles + if (m_blinkFrame < TEST_PATTERNS_BLINK_CYCLE / 2) + glColor3f(m_black + 0.05f, m_black + 0.05f, m_black + 0.05f); + else + glColor3f(0.0f, 0.0f, 0.0f); //BTB + DrawCircle(x25p, y75p, (y37p - y12p) / 3); + DrawCircle(x75p, y25p, (y37p - y12p) / 3); + + if (m_blinkFrame < TEST_PATTERNS_BLINK_CYCLE / 2) + glColor3f(m_white - 0.05f, m_white - 0.05f, m_white - 0.05f); + else + glColor3f(1.0f, 1.0f, 1.0f); //WTW + DrawCircle(x25p, y25p, (y37p - y12p) / 3); + DrawCircle(x75p, y75p, (y37p - y12p) / 3); +} + +void CGUIWindowTestPatternGL::DrawCircle(int originX, int originY, int radius) +{ + float angle; + int vectorX; + int vectorY; + int vectorY1 = originY; + int vectorX1 = originX; + + glBegin(GL_TRIANGLES); + for (int i = 0; i <= 360; i++) + { + angle = (float)(((double)i)/57.29577957795135); + vectorX = (int) (originX + (radius*(float)sin((double)angle))); + vectorY = (int) (originY + (radius*(float)cos((double)angle))); + glVertex2d(originX, originY); + glVertex2d(vectorX1, vectorY1); + glVertex2d(vectorX, vectorY); + vectorY1 = vectorY; + vectorX1 = vectorX; + } + glEnd(); +} + +void CGUIWindowTestPatternGL::BeginRender() +{ + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + +void CGUIWindowTestPatternGL::EndRender() +{ + +} diff --git a/xbmc/rendering/gl/GUIWindowTestPatternGL.h b/xbmc/rendering/gl/GUIWindowTestPatternGL.h new file mode 100644 index 0000000000..7665722270 --- /dev/null +++ b/xbmc/rendering/gl/GUIWindowTestPatternGL.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * Test patterns designed by Ofer LaOr - hometheater.co.il + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "settings/windows/GUIWindowTestPattern.h" + +class CGUIWindowTestPatternGL : public CGUIWindowTestPattern +{ +public: + CGUIWindowTestPatternGL(void); + ~CGUIWindowTestPatternGL(void) override; + +private: + void DrawVerticalLines(int top, int left, int bottom, int right) override; + void DrawHorizontalLines(int top, int left, int bottom, int right) override; + void DrawCheckers(int top, int left, int bottom, int right) override; + void DrawBouncingRectangle(int top, int left, int bottom, int right) override; + void DrawContrastBrightnessPattern(int top, int left, int bottom, int right) override; + void DrawCircle(int originX, int originY, int radius) override; + void BeginRender() override; + void EndRender() override; +}; + diff --git a/xbmc/settings/windows/CMakeLists.txt b/xbmc/settings/windows/CMakeLists.txt index c1b69ac04f..b258610875 100644 --- a/xbmc/settings/windows/CMakeLists.txt +++ b/xbmc/settings/windows/CMakeLists.txt @@ -1,11 +1,13 @@ set(SOURCES GUIControlSettings.cpp GUIWindowSettings.cpp GUIWindowSettingsCategory.cpp - GUIWindowSettingsScreenCalibration.cpp) + GUIWindowSettingsScreenCalibration.cpp + GUIWindowTestPattern.cpp) set(HEADERS GUIControlSettings.h GUIWindowSettings.h GUIWindowSettingsCategory.h - GUIWindowSettingsScreenCalibration.h) + GUIWindowSettingsScreenCalibration.h + GUIWindowTestPattern.h) core_add_library(settings_windows) diff --git a/xbmc/settings/windows/GUIWindowTestPattern.cpp b/xbmc/settings/windows/GUIWindowTestPattern.cpp new file mode 100644 index 0000000000..a391413975 --- /dev/null +++ b/xbmc/settings/windows/GUIWindowTestPattern.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "GUIWindowTestPattern.h" +#include "ServiceBroker.h" +#include "input/Key.h" +#include "guilib/GUIMessage.h" +#include "guilib/WindowIDs.h" +#include "windowing/WinSystem.h" + + +CGUIWindowTestPattern::CGUIWindowTestPattern(void) + : CGUIWindow(WINDOW_TEST_PATTERN, "") +{ + m_pattern = 0; + m_bounceX = 0; + m_bounceY = 0; + m_bounceDirectionX = 0; + m_bounceDirectionY = 0; + m_blinkFrame = 0; + m_needsScaling = false; +} + +CGUIWindowTestPattern::~CGUIWindowTestPattern(void) = default; + + +bool CGUIWindowTestPattern::OnAction(const CAction &action) +{ + switch (action.GetID()) + { + case ACTION_MOVE_UP: + case ACTION_MOVE_LEFT: + m_pattern = m_pattern > 0 ? m_pattern - 1 : TEST_PATTERNS_COUNT - 1; + SetInvalid(); + return true; + + case ACTION_MOVE_DOWN: + case ACTION_MOVE_RIGHT: + m_pattern = (m_pattern + 1) % TEST_PATTERNS_COUNT; + SetInvalid(); + return true; + } + return CGUIWindow::OnAction(action); // base class to handle basic movement etc. +} + +bool CGUIWindowTestPattern::OnMessage(CGUIMessage& message) +{ + switch (message.GetMessage()) + { + case GUI_MSG_WINDOW_INIT: + m_pattern = 0; + m_bounceDirectionX = 1; + m_bounceDirectionY = 1; + m_bounceX = 0; + m_bounceY = 0; + m_blinkFrame = 0; + break; + + } + return CGUIWindow::OnMessage(message); +} + +void CGUIWindowTestPattern::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) +{ + if (m_pattern == 0 || m_pattern == 4) + MarkDirtyRegion(); + CGUIWindow::Process(currentTime, dirtyregions); + m_renderRegion.SetRect(0, 0, (float)CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth(), (float)CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight()); + +#ifndef HAS_DX + if(CServiceBroker::GetWinSystem()->UseLimitedColor()) + { + m_white = 235.0f / 255; + m_black = 16.0f / 255; + } + else +#endif + { + m_white = 1.0f; + m_black = 0.0f; + } +} + +void CGUIWindowTestPattern::Render() +{ + BeginRender(); + const RESOLUTION_INFO info = CServiceBroker::GetWinSystem()->GetGfxContext().GetResInfo(); + + int top = info.Overscan.top; + int bottom = info.Overscan.bottom; + int left = info.Overscan.left; + int right = info.Overscan.right; + + switch (m_pattern) + { + case 0: + DrawContrastBrightnessPattern(top, left, bottom, right); + break; + + case 1: + DrawVerticalLines(top, left, bottom, right); + break; + + case 2: + DrawHorizontalLines(top, left, bottom, right); + break; + + case 3: + DrawCheckers(top, left, bottom, right); + break; + + case 4: + DrawBouncingRectangle(top, left, bottom, right); + break; + } + + EndRender(); + + CGUIWindow::Render(); +} + diff --git a/xbmc/settings/windows/GUIWindowTestPattern.h b/xbmc/settings/windows/GUIWindowTestPattern.h new file mode 100644 index 0000000000..7a96cdef29 --- /dev/null +++ b/xbmc/settings/windows/GUIWindowTestPattern.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "guilib/GUIWindow.h" + +#define TEST_PATTERNS_COUNT 5 +#define TEST_PATTERNS_BOUNCE_SQUARE_SIZE 100 +#define TEST_PATTERNS_BLINK_CYCLE 100 + +class CGUIWindowTestPattern : public CGUIWindow +{ +public: + CGUIWindowTestPattern(void); + ~CGUIWindowTestPattern(void) override; + bool OnMessage(CGUIMessage& message) override; + bool OnAction(const CAction &action) override; + void Render() override; + void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) override; + +protected: + virtual void DrawVerticalLines(int top, int left, int bottom, int right) = 0; + virtual void DrawHorizontalLines(int top, int left, int bottom, int right) = 0; + virtual void DrawCheckers(int top, int left, int bottom, int right) = 0; + virtual void DrawBouncingRectangle(int top, int left, int bottom, int right) = 0; + virtual void DrawContrastBrightnessPattern(int top, int left, int bottom, int right) = 0; + virtual void DrawCircle(int originX, int originY, int radius) = 0; + virtual void BeginRender() = 0; + virtual void EndRender() = 0; + + int m_pattern; + int m_bounceX; + int m_bounceY; + int m_bounceDirectionX; + int m_bounceDirectionY; + int m_blinkFrame; + + float m_white = 1.0; + float m_black = 0.0; +}; + + |