[videodb] remove unused seasons table from episode_view
[xbmc.git] / xbmc / rendering / gl / RenderSystemGL.cpp
blob467cc038c0eac24cab10741efd910b4f45fd3d25
1 /*
2 * Copyright (C) 2005-2024 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "RenderSystemGL.h"
11 #include "ServiceBroker.h"
12 #include "URL.h"
13 #include "guilib/GUITextureGL.h"
14 #include "rendering/MatrixGL.h"
15 #include "settings/AdvancedSettings.h"
16 #include "settings/SettingsComponent.h"
17 #include "utils/FileUtils.h"
18 #include "utils/GLUtils.h"
19 #include "utils/MathUtils.h"
20 #include "utils/XTimeUtils.h"
21 #include "utils/log.h"
22 #include "windowing/WinSystem.h"
24 #include <exception>
26 #if defined(TARGET_LINUX)
27 #include "utils/EGLUtils.h"
28 #endif
30 using namespace std::chrono_literals;
32 CRenderSystemGL::CRenderSystemGL() : CRenderSystemBase()
36 CRenderSystemGL::~CRenderSystemGL() = default;
38 bool CRenderSystemGL::InitRenderSystem()
40 m_bVSync = false;
41 m_bVsyncInit = false;
42 m_maxTextureSize = 2048;
44 // Get the GL version number
45 m_RenderVersionMajor = 0;
46 m_RenderVersionMinor = 0;
47 const char* ver = (const char*)glGetString(GL_VERSION);
48 if (ver != 0)
50 sscanf(ver, "%d.%d", &m_RenderVersionMajor, &m_RenderVersionMinor);
51 m_RenderVersion = ver;
53 else
55 CLog::Log(LOGFATAL, "CRenderSystemGL::{} - glGetString(GL_VERSION) returned NULL, exiting",
56 __FUNCTION__);
57 std::terminate();
60 CLog::Log(LOGINFO, "CRenderSystemGL::{} - Version: {}, Major: {}, Minor: {}", __FUNCTION__, ver,
61 m_RenderVersionMajor, m_RenderVersionMinor);
63 m_RenderExtensions = " ";
64 if (m_RenderVersionMajor > 3 ||
65 (m_RenderVersionMajor == 3 && m_RenderVersionMinor >= 2))
67 GLint n = 0;
68 glGetIntegerv(GL_NUM_EXTENSIONS, &n);
69 if (n > 0)
71 GLint i;
72 for (i = 0; i < n; i++)
74 m_RenderExtensions += (const char*) glGetStringi(GL_EXTENSIONS, i);
75 m_RenderExtensions += " ";
79 else
81 auto extensions = (const char*) glGetString(GL_EXTENSIONS);
82 if (extensions)
84 m_RenderExtensions += extensions;
87 m_RenderExtensions += " ";
89 ver = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
90 if (ver)
92 sscanf(ver, "%d.%d", &m_glslMajor, &m_glslMinor);
94 else
96 m_glslMajor = 1;
97 m_glslMinor = 0;
100 #if defined(GL_KHR_debug) && defined(TARGET_LINUX)
101 if (CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_openGlDebugging)
103 if (IsExtSupported("GL_KHR_debug"))
105 auto glDebugMessageCallback =
106 CEGLUtils::GetRequiredProcAddress<PFNGLDEBUGMESSAGECALLBACKPROC>(
107 "glDebugMessageCallback");
108 auto glDebugMessageControl =
109 CEGLUtils::GetRequiredProcAddress<PFNGLDEBUGMESSAGECONTROLPROC>("glDebugMessageControl");
111 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
112 glDebugMessageCallback(KODI::UTILS::GL::GlErrorCallback, nullptr);
114 // ignore shader compilation information
115 glDebugMessageControl(GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DEBUG_TYPE_OTHER, GL_DONT_CARE, 0,
116 nullptr, GL_FALSE);
118 CLog::Log(LOGDEBUG, "OpenGL: debugging enabled");
120 else
122 CLog::Log(LOGDEBUG, "OpenGL: debugging requested but the required extension isn't "
123 "available (GL_KHR_debug)");
126 #endif
128 LogGraphicsInfo();
130 // Get our driver vendor and renderer
131 const char* tmpVendor = (const char*) glGetString(GL_VENDOR);
132 m_RenderVendor.clear();
133 if (tmpVendor != NULL)
134 m_RenderVendor = tmpVendor;
136 const char* tmpRenderer = (const char*) glGetString(GL_RENDERER);
137 m_RenderRenderer.clear();
138 if (tmpRenderer != NULL)
139 m_RenderRenderer = tmpRenderer;
141 m_bRenderCreated = true;
143 if (m_RenderVersionMajor > 3 ||
144 (m_RenderVersionMajor == 3 && m_RenderVersionMinor >= 2))
146 glGenVertexArrays(1, &m_vertexArray);
147 glBindVertexArray(m_vertexArray);
150 InitialiseShaders();
152 CGUITextureGL::Register();
154 return true;
157 bool CRenderSystemGL::ResetRenderSystem(int width, int height)
159 if (!m_bRenderCreated)
160 return false;
162 m_width = width;
163 m_height = height;
165 if (m_RenderVersionMajor > 3 ||
166 (m_RenderVersionMajor == 3 && m_RenderVersionMinor >= 2))
168 glBindVertexArray(0);
169 glDeleteVertexArrays(1, &m_vertexArray);
170 glGenVertexArrays(1, &m_vertexArray);
171 glBindVertexArray(m_vertexArray);
174 ReleaseShaders();
175 InitialiseShaders();
177 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
179 CalculateMaxTexturesize();
181 CRect rect( 0, 0, width, height );
182 SetViewPort( rect );
184 glEnable(GL_SCISSOR_TEST);
186 glMatrixProject.Clear();
187 glMatrixProject->LoadIdentity();
188 glMatrixProject->Ortho(0.0f, width-1, height-1, 0.0f, -1.0f, 1.0f);
189 glMatrixProject.Load();
191 glMatrixModview.Clear();
192 glMatrixModview->LoadIdentity();
193 glMatrixModview.Load();
195 glMatrixTexture.Clear();
196 glMatrixTexture->LoadIdentity();
197 glMatrixTexture.Load();
199 if (IsExtSupported("GL_ARB_multitexture"))
201 //clear error flags
202 ResetGLErrors();
204 GLint maxtex;
205 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxtex);
207 //some sanity checks
208 GLenum error = glGetError();
209 if (error != GL_NO_ERROR)
211 CLog::Log(LOGERROR, "ResetRenderSystem() GL_MAX_TEXTURE_IMAGE_UNITS returned error {}",
212 (int)error);
213 maxtex = 3;
215 else if (maxtex < 1 || maxtex > 32)
217 CLog::Log(LOGERROR,
218 "ResetRenderSystem() GL_MAX_TEXTURE_IMAGE_UNITS returned invalid value {}",
219 (int)maxtex);
220 maxtex = 3;
223 //reset texture matrix for all textures
224 for (GLint i = 0; i < maxtex; i++)
226 glActiveTexture(GL_TEXTURE0 + i);
227 glMatrixTexture.Load();
229 glActiveTexture(GL_TEXTURE0);
232 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
233 glEnable(GL_BLEND); // Turn Blending On
235 return true;
238 bool CRenderSystemGL::DestroyRenderSystem()
240 if (m_vertexArray != GL_NONE)
242 glDeleteVertexArrays(1, &m_vertexArray);
245 ReleaseShaders();
246 m_bRenderCreated = false;
248 return true;
251 bool CRenderSystemGL::BeginRender()
253 if (!m_bRenderCreated)
254 return false;
256 bool useLimited = CServiceBroker::GetWinSystem()->UseLimitedColor();
258 if (m_limitedColorRange != useLimited)
260 ReleaseShaders();
261 InitialiseShaders();
264 m_limitedColorRange = useLimited;
265 return true;
268 bool CRenderSystemGL::EndRender()
270 if (!m_bRenderCreated)
271 return false;
273 return true;
276 void CRenderSystemGL::InvalidateColorBuffer()
278 if (!m_bRenderCreated)
279 return;
281 /* clear is not affected by stipple pattern, so we can only clear on first frame */
282 if (m_stereoMode == RENDER_STEREO_MODE_INTERLACED && m_stereoView == RENDER_STEREO_VIEW_RIGHT)
283 return;
285 // some platforms prefer a clear, instead of rendering over
286 if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiGeometryClear)
288 ClearBuffers(0);
289 return;
292 if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering)
293 return;
295 glClearDepthf(0);
296 glDepthMask(GL_TRUE);
297 glClear(GL_DEPTH_BUFFER_BIT);
300 bool CRenderSystemGL::ClearBuffers(KODI::UTILS::COLOR::Color color)
302 if (!m_bRenderCreated)
303 return false;
305 /* clear is not affected by stipple pattern, so we can only clear on first frame */
306 if(m_stereoMode == RENDER_STEREO_MODE_INTERLACED && m_stereoView == RENDER_STEREO_VIEW_RIGHT)
307 return true;
309 float r = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::R, color) / 255.0f;
310 float g = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::G, color) / 255.0f;
311 float b = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::B, color) / 255.0f;
312 float a = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A, color) / 255.0f;
314 glClearColor(r, g, b, a);
316 GLbitfield flags = GL_COLOR_BUFFER_BIT;
318 if (CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering)
320 glClearDepthf(0);
321 glDepthMask(GL_TRUE);
322 flags |= GL_DEPTH_BUFFER_BIT;
325 glClear(flags);
327 return true;
330 bool CRenderSystemGL::IsExtSupported(const char* extension) const
332 if (m_RenderVersionMajor > 3 ||
333 (m_RenderVersionMajor == 3 && m_RenderVersionMinor >= 2))
335 if (strcmp( extension, "GL_EXT_framebuffer_object") == 0)
337 return true;
339 if (strcmp( extension, "GL_ARB_texture_non_power_of_two") == 0)
341 return true;
345 std::string name;
346 name = " ";
347 name += extension;
348 name += " ";
350 return m_RenderExtensions.find(name) != std::string::npos;
353 bool CRenderSystemGL::SupportsNPOT(bool dxt) const
355 return true;
358 void CRenderSystemGL::PresentRender(bool rendered, bool videoLayer)
360 SetVSync(true);
362 if (!m_bRenderCreated)
363 return;
365 PresentRenderImpl(rendered);
367 if (!rendered)
368 KODI::TIME::Sleep(40ms);
371 void CRenderSystemGL::SetVSync(bool enable)
373 if (m_bVSync == enable && m_bVsyncInit == true)
374 return;
376 if (!m_bRenderCreated)
377 return;
379 if (enable)
380 CLog::Log(LOGINFO, "GL: Enabling VSYNC");
381 else
382 CLog::Log(LOGINFO, "GL: Disabling VSYNC");
384 m_bVSync = enable;
385 m_bVsyncInit = true;
387 SetVSyncImpl(enable);
390 void CRenderSystemGL::CaptureStateBlock()
392 if (!m_bRenderCreated)
393 return;
395 glMatrixProject.Push();
396 glMatrixModview.Push();
397 glMatrixTexture.Push();
399 glDisable(GL_SCISSOR_TEST); // fixes FBO corruption on Macs
400 glActiveTexture(GL_TEXTURE0);
403 void CRenderSystemGL::ApplyStateBlock()
405 if (!m_bRenderCreated)
406 return;
408 glBindVertexArray(m_vertexArray);
410 glViewport(m_viewPort[0], m_viewPort[1], m_viewPort[2], m_viewPort[3]);
412 glMatrixProject.PopLoad();
413 glMatrixModview.PopLoad();
414 glMatrixTexture.PopLoad();
416 glActiveTexture(GL_TEXTURE0);
417 glEnable(GL_BLEND);
418 glEnable(GL_SCISSOR_TEST);
421 void CRenderSystemGL::SetCameraPosition(const CPoint &camera, int screenWidth, int screenHeight, float stereoFactor)
423 if (!m_bRenderCreated)
424 return;
426 CPoint offset = camera - CPoint(screenWidth*0.5f, screenHeight*0.5f);
429 float w = (float)m_viewPort[2]*0.5f;
430 float h = (float)m_viewPort[3]*0.5f;
432 glMatrixModview->LoadIdentity();
433 glMatrixModview->Translatef(-(w + offset.x - stereoFactor), +(h + offset.y), 0);
434 glMatrixModview->LookAt(0.0f, 0.0f, -2.0f * h, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f);
435 glMatrixModview.Load();
437 glMatrixProject->LoadIdentity();
438 glMatrixProject->Frustum( (-w - offset.x)*0.5f, (w - offset.x)*0.5f, (-h + offset.y)*0.5f, (h + offset.y)*0.5f, h, 100*h);
439 glMatrixProject.Load();
442 void CRenderSystemGL::Project(float &x, float &y, float &z)
444 GLfloat coordX, coordY, coordZ;
445 if (CMatrixGL::Project(x, y, z, glMatrixModview.Get(), glMatrixProject.Get(), m_viewPort, &coordX, &coordY, &coordZ))
447 x = coordX;
448 y = (float)(m_viewPort[1] + m_viewPort[3] - coordY);
449 z = 0;
453 void CRenderSystemGL::CalculateMaxTexturesize()
455 GLint width = 256;
457 // reset any previous GL errors
458 ResetGLErrors();
460 // max out at 2^(8+8)
461 for (int i = 0 ; i<8 ; i++)
463 glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, width, width, 0, GL_BGRA,
464 GL_UNSIGNED_BYTE, NULL);
465 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH,
466 &width);
468 // GMA950 on OS X sets error instead
469 if (width == 0 || (glGetError() != GL_NO_ERROR) )
470 break;
472 m_maxTextureSize = width;
473 width *= 2;
474 if (width > 65536) // have an upper limit in case driver acts stupid
476 CLog::Log(LOGERROR, "GL: Could not determine maximum texture width, falling back to 2048");
477 m_maxTextureSize = 2048;
478 break;
482 CLog::Log(LOGINFO, "GL: Maximum texture width: {}", m_maxTextureSize);
485 void CRenderSystemGL::GetViewPort(CRect& viewPort)
487 if (!m_bRenderCreated)
488 return;
490 viewPort.x1 = m_viewPort[0];
491 viewPort.y1 = m_height - m_viewPort[1] - m_viewPort[3];
492 viewPort.x2 = m_viewPort[0] + m_viewPort[2];
493 viewPort.y2 = viewPort.y1 + m_viewPort[3];
496 void CRenderSystemGL::SetViewPort(const CRect& viewPort)
498 if (!m_bRenderCreated)
499 return;
501 glScissor((GLint) viewPort.x1, (GLint) (m_height - viewPort.y1 - viewPort.Height()), (GLsizei) viewPort.Width(), (GLsizei) viewPort.Height());
502 glViewport((GLint) viewPort.x1, (GLint) (m_height - viewPort.y1 - viewPort.Height()), (GLsizei) viewPort.Width(), (GLsizei) viewPort.Height());
503 m_viewPort[0] = viewPort.x1;
504 m_viewPort[1] = m_height - viewPort.y1 - viewPort.Height();
505 m_viewPort[2] = viewPort.Width();
506 m_viewPort[3] = viewPort.Height();
509 bool CRenderSystemGL::ScissorsCanEffectClipping()
511 if (m_pShader[m_method])
512 return m_pShader[m_method]->HardwareClipIsPossible();
514 return false;
517 CRect CRenderSystemGL::ClipRectToScissorRect(const CRect &rect)
519 if (!m_pShader[m_method])
520 return CRect();
521 float xFactor = m_pShader[m_method]->GetClipXFactor();
522 float xOffset = m_pShader[m_method]->GetClipXOffset();
523 float yFactor = m_pShader[m_method]->GetClipYFactor();
524 float yOffset = m_pShader[m_method]->GetClipYOffset();
525 return CRect(rect.x1 * xFactor + xOffset,
526 rect.y1 * yFactor + yOffset,
527 rect.x2 * xFactor + xOffset,
528 rect.y2 * yFactor + yOffset);
531 void CRenderSystemGL::SetScissors(const CRect &rect)
533 if (!m_bRenderCreated)
534 return;
535 GLint x1 = MathUtils::round_int(static_cast<double>(rect.x1));
536 GLint y1 = MathUtils::round_int(static_cast<double>(rect.y1));
537 GLint x2 = MathUtils::round_int(static_cast<double>(rect.x2));
538 GLint y2 = MathUtils::round_int(static_cast<double>(rect.y2));
539 glScissor(x1, m_height - y2, x2-x1, y2-y1);
542 void CRenderSystemGL::ResetScissors()
544 SetScissors(CRect(0, 0, (float)m_width, (float)m_height));
547 void CRenderSystemGL::SetDepthCulling(DEPTH_CULLING culling)
549 if (culling == DEPTH_CULLING_OFF)
551 glDisable(GL_DEPTH_TEST);
552 glDepthMask(GL_FALSE);
554 else if (culling == DEPTH_CULLING_BACK_TO_FRONT)
556 glEnable(GL_DEPTH_TEST);
557 glDepthMask(GL_FALSE);
558 glDepthFunc(GL_GEQUAL);
560 else if (culling == DEPTH_CULLING_FRONT_TO_BACK)
562 glEnable(GL_DEPTH_TEST);
563 glDepthMask(GL_TRUE);
564 glDepthFunc(GL_GREATER);
568 void CRenderSystemGL::GetGLSLVersion(int& major, int& minor)
570 major = m_glslMajor;
571 minor = m_glslMinor;
574 void CRenderSystemGL::ResetGLErrors()
576 int count = 0;
577 while (glGetError() != GL_NO_ERROR)
579 count++;
580 if (count >= 100)
582 CLog::Log(
583 LOGWARNING,
584 "CRenderSystemGL::ResetGLErrors glGetError didn't return GL_NO_ERROR after {} iterations",
585 count);
586 break;
590 static const GLubyte stipple_3d[] = {
591 0x00, 0x00, 0x00, 0x00,
592 0xFF, 0xFF, 0xFF, 0xFF,
593 0x00, 0x00, 0x00, 0x00,
594 0xFF, 0xFF, 0xFF, 0xFF,
595 0x00, 0x00, 0x00, 0x00,
596 0xFF, 0xFF, 0xFF, 0xFF,
597 0x00, 0x00, 0x00, 0x00,
598 0xFF, 0xFF, 0xFF, 0xFF,
599 0x00, 0x00, 0x00, 0x00,
600 0xFF, 0xFF, 0xFF, 0xFF,
601 0x00, 0x00, 0x00, 0x00,
602 0xFF, 0xFF, 0xFF, 0xFF,
603 0x00, 0x00, 0x00, 0x00,
604 0xFF, 0xFF, 0xFF, 0xFF,
605 0x00, 0x00, 0x00, 0x00,
606 0xFF, 0xFF, 0xFF, 0xFF,
607 0x00, 0x00, 0x00, 0x00,
608 0xFF, 0xFF, 0xFF, 0xFF,
609 0x00, 0x00, 0x00, 0x00,
610 0xFF, 0xFF, 0xFF, 0xFF,
611 0x00, 0x00, 0x00, 0x00,
612 0xFF, 0xFF, 0xFF, 0xFF,
613 0x00, 0x00, 0x00, 0x00,
614 0xFF, 0xFF, 0xFF, 0xFF,
615 0x00, 0x00, 0x00, 0x00,
616 0xFF, 0xFF, 0xFF, 0xFF,
617 0x00, 0x00, 0x00, 0x00,
618 0xFF, 0xFF, 0xFF, 0xFF,
619 0x00, 0x00, 0x00, 0x00,
620 0xFF, 0xFF, 0xFF, 0xFF,
621 0x00, 0x00, 0x00, 0x00,
622 0xFF, 0xFF, 0xFF, 0xFF,
623 0x00, 0x00, 0x00, 0x00,
626 void CRenderSystemGL::SetStereoMode(RENDER_STEREO_MODE mode, RENDER_STEREO_VIEW view)
628 CRenderSystemBase::SetStereoMode(mode, view);
630 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
631 glDrawBuffer(GL_BACK);
633 if(m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN)
635 if(m_stereoView == RENDER_STEREO_VIEW_LEFT)
636 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
637 else if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
638 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
640 if(m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA)
642 if(m_stereoView == RENDER_STEREO_VIEW_LEFT)
643 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
644 else if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
645 glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
647 if(m_stereoMode == RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE)
649 if(m_stereoView == RENDER_STEREO_VIEW_LEFT)
650 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
651 else if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
652 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
655 if(m_stereoMode == RENDER_STEREO_MODE_INTERLACED)
657 glEnable(GL_POLYGON_STIPPLE);
658 if(m_stereoView == RENDER_STEREO_VIEW_LEFT)
659 glPolygonStipple(stipple_3d);
660 else if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
661 glPolygonStipple(stipple_3d+4);
664 if(m_stereoMode == RENDER_STEREO_MODE_HARDWAREBASED)
666 if(m_stereoView == RENDER_STEREO_VIEW_LEFT)
667 glDrawBuffer(GL_BACK_LEFT);
668 else if(m_stereoView == RENDER_STEREO_VIEW_RIGHT)
669 glDrawBuffer(GL_BACK_RIGHT);
674 bool CRenderSystemGL::SupportsStereo(RENDER_STEREO_MODE mode) const
676 switch(mode)
678 case RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN:
679 case RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA:
680 case RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE:
681 case RENDER_STEREO_MODE_INTERLACED:
682 return true;
683 case RENDER_STEREO_MODE_HARDWAREBASED: {
684 //This is called by setting init, at which point GL is not inited
685 //luckily if GL doesn't support this, it will just behave as if
686 //it was not in effect.
687 //GLboolean stereo = GL_FALSE;
688 //glGetBooleanv(GL_STEREO, &stereo);
689 //return stereo == GL_TRUE ? true : false;
690 return true;
692 default:
693 return CRenderSystemBase::SupportsStereo(mode);
697 // -----------------------------------------------------------------------------
698 // shaders
699 // -----------------------------------------------------------------------------
700 void CRenderSystemGL::InitialiseShaders()
702 std::string defines;
703 m_limitedColorRange = CServiceBroker::GetWinSystem()->UseLimitedColor();
704 if (m_limitedColorRange)
706 defines += "#define KODI_LIMITED_RANGE 1\n";
709 m_pShader[ShaderMethodGL::SM_DEFAULT] = std::make_unique<CGLShader>(
710 "gl_shader_vert_default.glsl", "gl_shader_frag_default.glsl", defines);
711 if (!m_pShader[ShaderMethodGL::SM_DEFAULT]->CompileAndLink())
713 m_pShader[ShaderMethodGL::SM_DEFAULT]->Free();
714 m_pShader[ShaderMethodGL::SM_DEFAULT].reset();
715 CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_default.glsl - compile and link failed");
718 m_pShader[ShaderMethodGL::SM_TEXTURE] =
719 std::make_unique<CGLShader>("gl_shader_frag_texture.glsl", defines);
720 if (!m_pShader[ShaderMethodGL::SM_TEXTURE]->CompileAndLink())
722 m_pShader[ShaderMethodGL::SM_TEXTURE]->Free();
723 m_pShader[ShaderMethodGL::SM_TEXTURE].reset();
724 CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_texture.glsl - compile and link failed");
727 m_pShader[ShaderMethodGL::SM_TEXTURE_LIM] =
728 std::make_unique<CGLShader>("gl_shader_frag_texture_lim.glsl", defines);
729 if (!m_pShader[ShaderMethodGL::SM_TEXTURE_LIM]->CompileAndLink())
731 m_pShader[ShaderMethodGL::SM_TEXTURE_LIM]->Free();
732 m_pShader[ShaderMethodGL::SM_TEXTURE_LIM].reset();
733 CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_texture_lim.glsl - compile and link failed");
736 m_pShader[ShaderMethodGL::SM_MULTI] =
737 std::make_unique<CGLShader>("gl_shader_frag_multi.glsl", defines);
738 if (!m_pShader[ShaderMethodGL::SM_MULTI]->CompileAndLink())
740 m_pShader[ShaderMethodGL::SM_MULTI]->Free();
741 m_pShader[ShaderMethodGL::SM_MULTI].reset();
742 CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_multi.glsl - compile and link failed");
745 m_pShader[ShaderMethodGL::SM_FONTS] = std::make_unique<CGLShader>(
746 "gl_shader_vert_simple.glsl", "gl_shader_frag_fonts.glsl", defines);
747 if (!m_pShader[ShaderMethodGL::SM_FONTS]->CompileAndLink())
749 m_pShader[ShaderMethodGL::SM_FONTS]->Free();
750 m_pShader[ShaderMethodGL::SM_FONTS].reset();
751 CLog::Log(LOGERROR, "GUI Shader gl_shader_vert_simple.glsl + gl_shader_frag_fonts.glsl - "
752 "compile and link failed");
755 m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP] =
756 std::make_unique<CGLShader>("gl_shader_vert_clip.glsl", "gl_shader_frag_fonts.glsl", defines);
757 if (!m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->CompileAndLink())
759 m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->Free();
760 m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP].reset();
761 CLog::Log(LOGERROR, "GUI Shader gl_shader_vert_clip.glsl + gl_shader_frag_fonts.glsl - compile "
762 "and link failed");
765 m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND] =
766 std::make_unique<CGLShader>("gl_shader_frag_texture_noblend.glsl", defines);
767 if (!m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND]->CompileAndLink())
769 m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND]->Free();
770 m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND].reset();
771 CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_texture_noblend.glsl - compile and link failed");
774 m_pShader[ShaderMethodGL::SM_MULTI_BLENDCOLOR] =
775 std::make_unique<CGLShader>("gl_shader_frag_multi_blendcolor.glsl", defines);
776 if (!m_pShader[ShaderMethodGL::SM_MULTI_BLENDCOLOR]->CompileAndLink())
778 m_pShader[ShaderMethodGL::SM_MULTI_BLENDCOLOR]->Free();
779 m_pShader[ShaderMethodGL::SM_MULTI_BLENDCOLOR].reset();
780 CLog::Log(LOGERROR, "GUI Shader gl_shader_frag_multi_blendcolor.glsl - compile and link failed");
784 void CRenderSystemGL::ReleaseShaders()
786 if (m_pShader[ShaderMethodGL::SM_DEFAULT])
787 m_pShader[ShaderMethodGL::SM_DEFAULT]->Free();
788 m_pShader[ShaderMethodGL::SM_DEFAULT].reset();
790 if (m_pShader[ShaderMethodGL::SM_TEXTURE])
791 m_pShader[ShaderMethodGL::SM_TEXTURE]->Free();
792 m_pShader[ShaderMethodGL::SM_TEXTURE].reset();
794 if (m_pShader[ShaderMethodGL::SM_TEXTURE_LIM])
795 m_pShader[ShaderMethodGL::SM_TEXTURE_LIM]->Free();
796 m_pShader[ShaderMethodGL::SM_TEXTURE_LIM].reset();
798 if (m_pShader[ShaderMethodGL::SM_MULTI])
799 m_pShader[ShaderMethodGL::SM_MULTI]->Free();
800 m_pShader[ShaderMethodGL::SM_MULTI].reset();
802 if (m_pShader[ShaderMethodGL::SM_FONTS])
803 m_pShader[ShaderMethodGL::SM_FONTS]->Free();
804 m_pShader[ShaderMethodGL::SM_FONTS].reset();
806 if (m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP])
807 m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP]->Free();
808 m_pShader[ShaderMethodGL::SM_FONTS_SHADER_CLIP].reset();
810 if (m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND])
811 m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND]->Free();
812 m_pShader[ShaderMethodGL::SM_TEXTURE_NOBLEND].reset();
814 if (m_pShader[ShaderMethodGL::SM_MULTI_BLENDCOLOR])
815 m_pShader[ShaderMethodGL::SM_MULTI_BLENDCOLOR]->Free();
816 m_pShader[ShaderMethodGL::SM_MULTI_BLENDCOLOR].reset();
819 void CRenderSystemGL::EnableShader(ShaderMethodGL method)
821 m_method = method;
822 if (m_pShader[m_method])
824 m_pShader[m_method]->Enable();
826 else
828 CLog::Log(LOGERROR, "Invalid GUI Shader selected {}", method);
832 void CRenderSystemGL::DisableShader()
834 if (m_pShader[m_method])
836 m_pShader[m_method]->Disable();
838 m_method = ShaderMethodGL::SM_DEFAULT;
841 GLint CRenderSystemGL::ShaderGetPos()
843 if (m_pShader[m_method])
844 return m_pShader[m_method]->GetPosLoc();
846 return -1;
849 GLint CRenderSystemGL::ShaderGetCol()
851 if (m_pShader[m_method])
852 return m_pShader[m_method]->GetColLoc();
854 return -1;
857 GLint CRenderSystemGL::ShaderGetCoord0()
859 if (m_pShader[m_method])
860 return m_pShader[m_method]->GetCord0Loc();
862 return -1;
865 GLint CRenderSystemGL::ShaderGetCoord1()
867 if (m_pShader[m_method])
868 return m_pShader[m_method]->GetCord1Loc();
870 return -1;
873 GLint CRenderSystemGL::ShaderGetDepth()
875 if (m_pShader[m_method])
876 return m_pShader[m_method]->GetDepthLoc();
878 return -1;
881 GLint CRenderSystemGL::ShaderGetUniCol()
883 if (m_pShader[m_method])
884 return m_pShader[m_method]->GetUniColLoc();
886 return -1;
889 GLint CRenderSystemGL::ShaderGetModel()
891 if (m_pShader[m_method])
892 return m_pShader[m_method]->GetModelLoc();
894 return -1;
897 GLint CRenderSystemGL::ShaderGetMatrix()
899 if (m_pShader[m_method])
900 return m_pShader[m_method]->GetMatrixLoc();
902 return -1;
905 GLint CRenderSystemGL::ShaderGetClip()
907 if (m_pShader[m_method])
908 return m_pShader[m_method]->GetShaderClipLoc();
910 return -1;
913 GLint CRenderSystemGL::ShaderGetCoordStep()
915 if (m_pShader[m_method])
916 return m_pShader[m_method]->GetShaderCoordStepLoc();
918 return -1;
921 std::string CRenderSystemGL::GetShaderPath(const std::string &filename)
923 std::string path = "GL/1.2/";
925 if (m_glslMajor >= 4)
927 std::string file = "special://xbmc/system/shaders/GL/4.0/" + filename;
928 const CURL pathToUrl(file);
929 if (CFileUtils::Exists(pathToUrl.Get()))
930 return "GL/4.0/";
932 if (m_glslMajor >= 2 || (m_glslMajor == 1 && m_glslMinor >= 50))
933 path = "GL/1.5/";
935 return path;