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.
9 #include "RenderSystemGL.h"
11 #include "ServiceBroker.h"
13 #include "guilib/GUITextureGL.h"
14 #include "platform/MessagePrinter.h"
15 #include "rendering/MatrixGL.h"
16 #include "settings/AdvancedSettings.h"
17 #include "settings/SettingsComponent.h"
18 #include "utils/FileUtils.h"
19 #include "utils/GLUtils.h"
20 #include "utils/MathUtils.h"
21 #include "utils/XTimeUtils.h"
22 #include "utils/log.h"
23 #include "windowing/WinSystem.h"
27 #if defined(TARGET_LINUX)
28 #include "utils/EGLUtils.h"
31 using namespace std::chrono_literals
;
33 CRenderSystemGL::CRenderSystemGL() : CRenderSystemBase()
37 CRenderSystemGL::~CRenderSystemGL() = default;
39 bool CRenderSystemGL::InitRenderSystem()
43 m_maxTextureSize
= 2048;
45 // Get the GL version number
46 m_RenderVersionMajor
= 0;
47 m_RenderVersionMinor
= 0;
48 m_RenderVersion
= "<none>";
49 const char* ver
= reinterpret_cast<const char*>(glGetString(GL_VERSION
));
52 sscanf(ver
, "%d.%d", &m_RenderVersionMajor
, &m_RenderVersionMinor
);
53 m_RenderVersion
= ver
;
56 CLog::Log(LOGINFO
, "CRenderSystemGL::{} - Version: {}, Major: {}, Minor: {}", __FUNCTION__
,
57 m_RenderVersion
, m_RenderVersionMajor
, m_RenderVersionMinor
);
59 m_RenderExtensions
= "";
60 if (m_RenderVersionMajor
> 3 ||
61 (m_RenderVersionMajor
== 3 && m_RenderVersionMinor
>= 2))
64 glGetIntegerv(GL_NUM_EXTENSIONS
, &n
);
68 for (i
= 0; i
< n
; i
++)
70 const char* extension
= reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS
, i
));
73 m_RenderExtensions
+= extension
;
74 m_RenderExtensions
+= " ";
81 const char* extensions
= reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS
));
84 m_RenderExtensions
+= extensions
;
85 m_RenderExtensions
+= " ";
89 ver
= reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION
));
92 sscanf(ver
, "%d.%d", &m_glslMajor
, &m_glslMinor
);
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,
118 CLog::Log(LOGDEBUG
, "OpenGL: debugging enabled");
122 CLog::Log(LOGDEBUG
, "OpenGL: debugging requested but the required extension isn't "
123 "available (GL_KHR_debug)");
128 // Shut down gracefully if OpenGL context could not be allocated
129 if (m_RenderVersionMajor
== 0)
131 CLog::Log(LOGFATAL
, "Can not initialize OpenGL context. Exiting");
132 CMessagePrinter::DisplayError("ERROR: Can not initialize OpenGL context. Exiting");
138 // Get our driver vendor and renderer
139 const char* tmpVendor
= reinterpret_cast<const char*>(glGetString(GL_VENDOR
));
140 m_RenderVendor
.clear();
142 m_RenderVendor
= tmpVendor
;
144 const char* tmpRenderer
= reinterpret_cast<const char*>(glGetString(GL_RENDERER
));
145 m_RenderRenderer
.clear();
147 m_RenderRenderer
= tmpRenderer
;
149 m_bRenderCreated
= true;
151 if (m_RenderVersionMajor
> 3 ||
152 (m_RenderVersionMajor
== 3 && m_RenderVersionMinor
>= 2))
154 glGenVertexArrays(1, &m_vertexArray
);
155 glBindVertexArray(m_vertexArray
);
160 CGUITextureGL::Register();
165 bool CRenderSystemGL::ResetRenderSystem(int width
, int height
)
167 if (!m_bRenderCreated
)
173 if (m_RenderVersionMajor
> 3 ||
174 (m_RenderVersionMajor
== 3 && m_RenderVersionMinor
>= 2))
176 glBindVertexArray(0);
177 glDeleteVertexArrays(1, &m_vertexArray
);
178 glGenVertexArrays(1, &m_vertexArray
);
179 glBindVertexArray(m_vertexArray
);
185 glClearColor( 0.0f
, 0.0f
, 0.0f
, 0.0f
);
187 CalculateMaxTexturesize();
189 CRect
rect( 0, 0, width
, height
);
192 glEnable(GL_SCISSOR_TEST
);
194 glMatrixProject
.Clear();
195 glMatrixProject
->LoadIdentity();
196 glMatrixProject
->Ortho(0.0f
, width
-1, height
-1, 0.0f
, -1.0f
, 1.0f
);
197 glMatrixProject
.Load();
199 glMatrixModview
.Clear();
200 glMatrixModview
->LoadIdentity();
201 glMatrixModview
.Load();
203 glMatrixTexture
.Clear();
204 glMatrixTexture
->LoadIdentity();
205 glMatrixTexture
.Load();
207 if (IsExtSupported("GL_ARB_multitexture"))
213 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS
, &maxtex
);
216 GLenum error
= glGetError();
217 if (error
!= GL_NO_ERROR
)
219 CLog::Log(LOGERROR
, "ResetRenderSystem() GL_MAX_TEXTURE_IMAGE_UNITS returned error {}",
223 else if (maxtex
< 1 || maxtex
> 32)
226 "ResetRenderSystem() GL_MAX_TEXTURE_IMAGE_UNITS returned invalid value {}",
231 //reset texture matrix for all textures
232 for (GLint i
= 0; i
< maxtex
; i
++)
234 glActiveTexture(GL_TEXTURE0
+ i
);
235 glMatrixTexture
.Load();
237 glActiveTexture(GL_TEXTURE0
);
240 glBlendFunc(GL_SRC_ALPHA
, GL_ONE
);
241 glEnable(GL_BLEND
); // Turn Blending On
246 bool CRenderSystemGL::DestroyRenderSystem()
248 if (m_vertexArray
!= GL_NONE
)
250 glDeleteVertexArrays(1, &m_vertexArray
);
254 m_bRenderCreated
= false;
259 bool CRenderSystemGL::BeginRender()
261 if (!m_bRenderCreated
)
264 bool useLimited
= CServiceBroker::GetWinSystem()->UseLimitedColor();
266 if (m_limitedColorRange
!= useLimited
)
272 m_limitedColorRange
= useLimited
;
276 bool CRenderSystemGL::EndRender()
278 if (!m_bRenderCreated
)
284 void CRenderSystemGL::InvalidateColorBuffer()
286 if (!m_bRenderCreated
)
289 /* clear is not affected by stipple pattern, so we can only clear on first frame */
290 if (m_stereoMode
== RENDER_STEREO_MODE_INTERLACED
&& m_stereoView
== RENDER_STEREO_VIEW_RIGHT
)
293 // some platforms prefer a clear, instead of rendering over
294 if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiGeometryClear
)
300 if (!CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering
)
304 glDepthMask(GL_TRUE
);
305 glClear(GL_DEPTH_BUFFER_BIT
);
308 bool CRenderSystemGL::ClearBuffers(KODI::UTILS::COLOR::Color color
)
310 if (!m_bRenderCreated
)
313 /* clear is not affected by stipple pattern, so we can only clear on first frame */
314 if(m_stereoMode
== RENDER_STEREO_MODE_INTERLACED
&& m_stereoView
== RENDER_STEREO_VIEW_RIGHT
)
317 float r
= KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::R
, color
) / 255.0f
;
318 float g
= KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::G
, color
) / 255.0f
;
319 float b
= KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::B
, color
) / 255.0f
;
320 float a
= KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A
, color
) / 255.0f
;
322 glClearColor(r
, g
, b
, a
);
324 GLbitfield flags
= GL_COLOR_BUFFER_BIT
;
326 if (CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_guiFrontToBackRendering
)
329 glDepthMask(GL_TRUE
);
330 flags
|= GL_DEPTH_BUFFER_BIT
;
338 bool CRenderSystemGL::IsExtSupported(const char* extension
) const
340 if (m_RenderVersionMajor
> 3 ||
341 (m_RenderVersionMajor
== 3 && m_RenderVersionMinor
>= 2))
343 if (strcmp( extension
, "GL_EXT_framebuffer_object") == 0)
347 if (strcmp( extension
, "GL_ARB_texture_non_power_of_two") == 0)
358 return m_RenderExtensions
.find(name
) != std::string::npos
;
361 bool CRenderSystemGL::SupportsNPOT(bool dxt
) const
366 void CRenderSystemGL::PresentRender(bool rendered
, bool videoLayer
)
370 if (!m_bRenderCreated
)
373 PresentRenderImpl(rendered
);
376 KODI::TIME::Sleep(40ms
);
379 void CRenderSystemGL::SetVSync(bool enable
)
381 if (m_bVSync
== enable
&& m_bVsyncInit
== true)
384 if (!m_bRenderCreated
)
388 CLog::Log(LOGINFO
, "GL: Enabling VSYNC");
390 CLog::Log(LOGINFO
, "GL: Disabling VSYNC");
395 SetVSyncImpl(enable
);
398 void CRenderSystemGL::CaptureStateBlock()
400 if (!m_bRenderCreated
)
403 glMatrixProject
.Push();
404 glMatrixModview
.Push();
405 glMatrixTexture
.Push();
407 glDisable(GL_SCISSOR_TEST
); // fixes FBO corruption on Macs
408 glActiveTexture(GL_TEXTURE0
);
411 void CRenderSystemGL::ApplyStateBlock()
413 if (!m_bRenderCreated
)
416 glBindVertexArray(m_vertexArray
);
418 glViewport(m_viewPort
[0], m_viewPort
[1], m_viewPort
[2], m_viewPort
[3]);
420 glMatrixProject
.PopLoad();
421 glMatrixModview
.PopLoad();
422 glMatrixTexture
.PopLoad();
424 glActiveTexture(GL_TEXTURE0
);
426 glEnable(GL_SCISSOR_TEST
);
429 void CRenderSystemGL::SetCameraPosition(const CPoint
&camera
, int screenWidth
, int screenHeight
, float stereoFactor
)
431 if (!m_bRenderCreated
)
434 CPoint offset
= camera
- CPoint(screenWidth
*0.5f
, screenHeight
*0.5f
);
437 float w
= (float)m_viewPort
[2]*0.5f
;
438 float h
= (float)m_viewPort
[3]*0.5f
;
440 glMatrixModview
->LoadIdentity();
441 glMatrixModview
->Translatef(-(w
+ offset
.x
- stereoFactor
), +(h
+ offset
.y
), 0);
442 glMatrixModview
->LookAt(0.0f
, 0.0f
, -2.0f
* h
, 0.0f
, 0.0f
, 0.0f
, 0.0f
, -1.0f
, 0.0f
);
443 glMatrixModview
.Load();
445 glMatrixProject
->LoadIdentity();
446 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
);
447 glMatrixProject
.Load();
450 void CRenderSystemGL::Project(float &x
, float &y
, float &z
)
452 GLfloat coordX
, coordY
, coordZ
;
453 if (CMatrixGL::Project(x
, y
, z
, glMatrixModview
.Get(), glMatrixProject
.Get(), m_viewPort
, &coordX
, &coordY
, &coordZ
))
456 y
= (float)(m_viewPort
[1] + m_viewPort
[3] - coordY
);
461 void CRenderSystemGL::CalculateMaxTexturesize()
465 // reset any previous GL errors
468 // max out at 2^(8+8)
469 for (int i
= 0 ; i
<8 ; i
++)
471 glTexImage2D(GL_PROXY_TEXTURE_2D
, 0, GL_RGBA
, width
, width
, 0, GL_BGRA
,
472 GL_UNSIGNED_BYTE
, NULL
);
473 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D
, 0, GL_TEXTURE_WIDTH
,
476 // GMA950 on OS X sets error instead
477 if (width
== 0 || (glGetError() != GL_NO_ERROR
) )
480 m_maxTextureSize
= width
;
482 if (width
> 65536) // have an upper limit in case driver acts stupid
484 CLog::Log(LOGERROR
, "GL: Could not determine maximum texture width, falling back to 2048");
485 m_maxTextureSize
= 2048;
490 CLog::Log(LOGINFO
, "GL: Maximum texture width: {}", m_maxTextureSize
);
493 void CRenderSystemGL::GetViewPort(CRect
& viewPort
)
495 if (!m_bRenderCreated
)
498 viewPort
.x1
= m_viewPort
[0];
499 viewPort
.y1
= m_height
- m_viewPort
[1] - m_viewPort
[3];
500 viewPort
.x2
= m_viewPort
[0] + m_viewPort
[2];
501 viewPort
.y2
= viewPort
.y1
+ m_viewPort
[3];
504 void CRenderSystemGL::SetViewPort(const CRect
& viewPort
)
506 if (!m_bRenderCreated
)
509 glScissor((GLint
) viewPort
.x1
, (GLint
) (m_height
- viewPort
.y1
- viewPort
.Height()), (GLsizei
) viewPort
.Width(), (GLsizei
) viewPort
.Height());
510 glViewport((GLint
) viewPort
.x1
, (GLint
) (m_height
- viewPort
.y1
- viewPort
.Height()), (GLsizei
) viewPort
.Width(), (GLsizei
) viewPort
.Height());
511 m_viewPort
[0] = viewPort
.x1
;
512 m_viewPort
[1] = m_height
- viewPort
.y1
- viewPort
.Height();
513 m_viewPort
[2] = viewPort
.Width();
514 m_viewPort
[3] = viewPort
.Height();
517 bool CRenderSystemGL::ScissorsCanEffectClipping()
519 if (m_pShader
[m_method
])
520 return m_pShader
[m_method
]->HardwareClipIsPossible();
525 CRect
CRenderSystemGL::ClipRectToScissorRect(const CRect
&rect
)
527 if (!m_pShader
[m_method
])
529 float xFactor
= m_pShader
[m_method
]->GetClipXFactor();
530 float xOffset
= m_pShader
[m_method
]->GetClipXOffset();
531 float yFactor
= m_pShader
[m_method
]->GetClipYFactor();
532 float yOffset
= m_pShader
[m_method
]->GetClipYOffset();
533 return CRect(rect
.x1
* xFactor
+ xOffset
,
534 rect
.y1
* yFactor
+ yOffset
,
535 rect
.x2
* xFactor
+ xOffset
,
536 rect
.y2
* yFactor
+ yOffset
);
539 void CRenderSystemGL::SetScissors(const CRect
&rect
)
541 if (!m_bRenderCreated
)
543 GLint x1
= MathUtils::round_int(static_cast<double>(rect
.x1
));
544 GLint y1
= MathUtils::round_int(static_cast<double>(rect
.y1
));
545 GLint x2
= MathUtils::round_int(static_cast<double>(rect
.x2
));
546 GLint y2
= MathUtils::round_int(static_cast<double>(rect
.y2
));
547 glScissor(x1
, m_height
- y2
, x2
-x1
, y2
-y1
);
550 void CRenderSystemGL::ResetScissors()
552 SetScissors(CRect(0, 0, (float)m_width
, (float)m_height
));
555 void CRenderSystemGL::SetDepthCulling(DEPTH_CULLING culling
)
557 if (culling
== DEPTH_CULLING_OFF
)
559 glDisable(GL_DEPTH_TEST
);
560 glDepthMask(GL_FALSE
);
562 else if (culling
== DEPTH_CULLING_BACK_TO_FRONT
)
564 glEnable(GL_DEPTH_TEST
);
565 glDepthMask(GL_FALSE
);
566 glDepthFunc(GL_GEQUAL
);
568 else if (culling
== DEPTH_CULLING_FRONT_TO_BACK
)
570 glEnable(GL_DEPTH_TEST
);
571 glDepthMask(GL_TRUE
);
572 glDepthFunc(GL_GREATER
);
576 void CRenderSystemGL::GetGLSLVersion(int& major
, int& minor
)
582 void CRenderSystemGL::ResetGLErrors()
585 while (glGetError() != GL_NO_ERROR
)
592 "CRenderSystemGL::ResetGLErrors glGetError didn't return GL_NO_ERROR after {} iterations",
598 static const GLubyte stipple_3d
[] = {
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,
624 0xFF, 0xFF, 0xFF, 0xFF,
625 0x00, 0x00, 0x00, 0x00,
626 0xFF, 0xFF, 0xFF, 0xFF,
627 0x00, 0x00, 0x00, 0x00,
628 0xFF, 0xFF, 0xFF, 0xFF,
629 0x00, 0x00, 0x00, 0x00,
630 0xFF, 0xFF, 0xFF, 0xFF,
631 0x00, 0x00, 0x00, 0x00,
634 void CRenderSystemGL::SetStereoMode(RENDER_STEREO_MODE mode
, RENDER_STEREO_VIEW view
)
636 CRenderSystemBase::SetStereoMode(mode
, view
);
638 glColorMask(GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
639 glDrawBuffer(GL_BACK
);
641 if(m_stereoMode
== RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN
)
643 if(m_stereoView
== RENDER_STEREO_VIEW_LEFT
)
644 glColorMask(GL_TRUE
, GL_FALSE
, GL_FALSE
, GL_TRUE
);
645 else if(m_stereoView
== RENDER_STEREO_VIEW_RIGHT
)
646 glColorMask(GL_FALSE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
648 if(m_stereoMode
== RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA
)
650 if(m_stereoView
== RENDER_STEREO_VIEW_LEFT
)
651 glColorMask(GL_FALSE
, GL_TRUE
, GL_FALSE
, GL_TRUE
);
652 else if(m_stereoView
== RENDER_STEREO_VIEW_RIGHT
)
653 glColorMask(GL_TRUE
, GL_FALSE
, GL_TRUE
, GL_TRUE
);
655 if(m_stereoMode
== RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE
)
657 if(m_stereoView
== RENDER_STEREO_VIEW_LEFT
)
658 glColorMask(GL_TRUE
, GL_TRUE
, GL_FALSE
, GL_TRUE
);
659 else if(m_stereoView
== RENDER_STEREO_VIEW_RIGHT
)
660 glColorMask(GL_FALSE
, GL_FALSE
, GL_TRUE
, GL_TRUE
);
663 if(m_stereoMode
== RENDER_STEREO_MODE_INTERLACED
)
665 glEnable(GL_POLYGON_STIPPLE
);
666 if(m_stereoView
== RENDER_STEREO_VIEW_LEFT
)
667 glPolygonStipple(stipple_3d
);
668 else if(m_stereoView
== RENDER_STEREO_VIEW_RIGHT
)
669 glPolygonStipple(stipple_3d
+4);
672 if(m_stereoMode
== RENDER_STEREO_MODE_HARDWAREBASED
)
674 if(m_stereoView
== RENDER_STEREO_VIEW_LEFT
)
675 glDrawBuffer(GL_BACK_LEFT
);
676 else if(m_stereoView
== RENDER_STEREO_VIEW_RIGHT
)
677 glDrawBuffer(GL_BACK_RIGHT
);
682 bool CRenderSystemGL::SupportsStereo(RENDER_STEREO_MODE mode
) const
686 case RENDER_STEREO_MODE_ANAGLYPH_RED_CYAN
:
687 case RENDER_STEREO_MODE_ANAGLYPH_GREEN_MAGENTA
:
688 case RENDER_STEREO_MODE_ANAGLYPH_YELLOW_BLUE
:
689 case RENDER_STEREO_MODE_INTERLACED
:
691 case RENDER_STEREO_MODE_HARDWAREBASED
: {
692 //This is called by setting init, at which point GL is not inited
693 //luckily if GL doesn't support this, it will just behave as if
694 //it was not in effect.
695 //GLboolean stereo = GL_FALSE;
696 //glGetBooleanv(GL_STEREO, &stereo);
697 //return stereo == GL_TRUE ? true : false;
701 return CRenderSystemBase::SupportsStereo(mode
);
705 // -----------------------------------------------------------------------------
707 // -----------------------------------------------------------------------------
708 void CRenderSystemGL::InitialiseShaders()
711 m_limitedColorRange
= CServiceBroker::GetWinSystem()->UseLimitedColor();
712 if (m_limitedColorRange
)
714 defines
+= "#define KODI_LIMITED_RANGE 1\n";
717 m_pShader
[ShaderMethodGL::SM_DEFAULT
] = std::make_unique
<CGLShader
>(
718 "gl_shader_vert_default.glsl", "gl_shader_frag_default.glsl", defines
);
719 if (!m_pShader
[ShaderMethodGL::SM_DEFAULT
]->CompileAndLink())
721 m_pShader
[ShaderMethodGL::SM_DEFAULT
]->Free();
722 m_pShader
[ShaderMethodGL::SM_DEFAULT
].reset();
723 CLog::Log(LOGERROR
, "GUI Shader gl_shader_frag_default.glsl - compile and link failed");
726 m_pShader
[ShaderMethodGL::SM_TEXTURE
] =
727 std::make_unique
<CGLShader
>("gl_shader_frag_texture.glsl", defines
);
728 if (!m_pShader
[ShaderMethodGL::SM_TEXTURE
]->CompileAndLink())
730 m_pShader
[ShaderMethodGL::SM_TEXTURE
]->Free();
731 m_pShader
[ShaderMethodGL::SM_TEXTURE
].reset();
732 CLog::Log(LOGERROR
, "GUI Shader gl_shader_frag_texture.glsl - compile and link failed");
735 m_pShader
[ShaderMethodGL::SM_TEXTURE_LIM
] =
736 std::make_unique
<CGLShader
>("gl_shader_frag_texture_lim.glsl", defines
);
737 if (!m_pShader
[ShaderMethodGL::SM_TEXTURE_LIM
]->CompileAndLink())
739 m_pShader
[ShaderMethodGL::SM_TEXTURE_LIM
]->Free();
740 m_pShader
[ShaderMethodGL::SM_TEXTURE_LIM
].reset();
741 CLog::Log(LOGERROR
, "GUI Shader gl_shader_frag_texture_lim.glsl - compile and link failed");
744 m_pShader
[ShaderMethodGL::SM_MULTI
] =
745 std::make_unique
<CGLShader
>("gl_shader_frag_multi.glsl", defines
);
746 if (!m_pShader
[ShaderMethodGL::SM_MULTI
]->CompileAndLink())
748 m_pShader
[ShaderMethodGL::SM_MULTI
]->Free();
749 m_pShader
[ShaderMethodGL::SM_MULTI
].reset();
750 CLog::Log(LOGERROR
, "GUI Shader gl_shader_frag_multi.glsl - compile and link failed");
753 m_pShader
[ShaderMethodGL::SM_FONTS
] = std::make_unique
<CGLShader
>(
754 "gl_shader_vert_simple.glsl", "gl_shader_frag_fonts.glsl", defines
);
755 if (!m_pShader
[ShaderMethodGL::SM_FONTS
]->CompileAndLink())
757 m_pShader
[ShaderMethodGL::SM_FONTS
]->Free();
758 m_pShader
[ShaderMethodGL::SM_FONTS
].reset();
759 CLog::Log(LOGERROR
, "GUI Shader gl_shader_vert_simple.glsl + gl_shader_frag_fonts.glsl - "
760 "compile and link failed");
763 m_pShader
[ShaderMethodGL::SM_FONTS_SHADER_CLIP
] =
764 std::make_unique
<CGLShader
>("gl_shader_vert_clip.glsl", "gl_shader_frag_fonts.glsl", defines
);
765 if (!m_pShader
[ShaderMethodGL::SM_FONTS_SHADER_CLIP
]->CompileAndLink())
767 m_pShader
[ShaderMethodGL::SM_FONTS_SHADER_CLIP
]->Free();
768 m_pShader
[ShaderMethodGL::SM_FONTS_SHADER_CLIP
].reset();
769 CLog::Log(LOGERROR
, "GUI Shader gl_shader_vert_clip.glsl + gl_shader_frag_fonts.glsl - compile "
773 m_pShader
[ShaderMethodGL::SM_TEXTURE_NOBLEND
] =
774 std::make_unique
<CGLShader
>("gl_shader_frag_texture_noblend.glsl", defines
);
775 if (!m_pShader
[ShaderMethodGL::SM_TEXTURE_NOBLEND
]->CompileAndLink())
777 m_pShader
[ShaderMethodGL::SM_TEXTURE_NOBLEND
]->Free();
778 m_pShader
[ShaderMethodGL::SM_TEXTURE_NOBLEND
].reset();
779 CLog::Log(LOGERROR
, "GUI Shader gl_shader_frag_texture_noblend.glsl - compile and link failed");
782 m_pShader
[ShaderMethodGL::SM_MULTI_BLENDCOLOR
] =
783 std::make_unique
<CGLShader
>("gl_shader_frag_multi_blendcolor.glsl", defines
);
784 if (!m_pShader
[ShaderMethodGL::SM_MULTI_BLENDCOLOR
]->CompileAndLink())
786 m_pShader
[ShaderMethodGL::SM_MULTI_BLENDCOLOR
]->Free();
787 m_pShader
[ShaderMethodGL::SM_MULTI_BLENDCOLOR
].reset();
788 CLog::Log(LOGERROR
, "GUI Shader gl_shader_frag_multi_blendcolor.glsl - compile and link failed");
792 void CRenderSystemGL::ReleaseShaders()
794 if (m_pShader
[ShaderMethodGL::SM_DEFAULT
])
795 m_pShader
[ShaderMethodGL::SM_DEFAULT
]->Free();
796 m_pShader
[ShaderMethodGL::SM_DEFAULT
].reset();
798 if (m_pShader
[ShaderMethodGL::SM_TEXTURE
])
799 m_pShader
[ShaderMethodGL::SM_TEXTURE
]->Free();
800 m_pShader
[ShaderMethodGL::SM_TEXTURE
].reset();
802 if (m_pShader
[ShaderMethodGL::SM_TEXTURE_LIM
])
803 m_pShader
[ShaderMethodGL::SM_TEXTURE_LIM
]->Free();
804 m_pShader
[ShaderMethodGL::SM_TEXTURE_LIM
].reset();
806 if (m_pShader
[ShaderMethodGL::SM_MULTI
])
807 m_pShader
[ShaderMethodGL::SM_MULTI
]->Free();
808 m_pShader
[ShaderMethodGL::SM_MULTI
].reset();
810 if (m_pShader
[ShaderMethodGL::SM_FONTS
])
811 m_pShader
[ShaderMethodGL::SM_FONTS
]->Free();
812 m_pShader
[ShaderMethodGL::SM_FONTS
].reset();
814 if (m_pShader
[ShaderMethodGL::SM_FONTS_SHADER_CLIP
])
815 m_pShader
[ShaderMethodGL::SM_FONTS_SHADER_CLIP
]->Free();
816 m_pShader
[ShaderMethodGL::SM_FONTS_SHADER_CLIP
].reset();
818 if (m_pShader
[ShaderMethodGL::SM_TEXTURE_NOBLEND
])
819 m_pShader
[ShaderMethodGL::SM_TEXTURE_NOBLEND
]->Free();
820 m_pShader
[ShaderMethodGL::SM_TEXTURE_NOBLEND
].reset();
822 if (m_pShader
[ShaderMethodGL::SM_MULTI_BLENDCOLOR
])
823 m_pShader
[ShaderMethodGL::SM_MULTI_BLENDCOLOR
]->Free();
824 m_pShader
[ShaderMethodGL::SM_MULTI_BLENDCOLOR
].reset();
827 void CRenderSystemGL::EnableShader(ShaderMethodGL method
)
830 if (m_pShader
[m_method
])
832 m_pShader
[m_method
]->Enable();
836 CLog::Log(LOGERROR
, "Invalid GUI Shader selected {}", method
);
840 void CRenderSystemGL::DisableShader()
842 if (m_pShader
[m_method
])
844 m_pShader
[m_method
]->Disable();
846 m_method
= ShaderMethodGL::SM_DEFAULT
;
849 GLint
CRenderSystemGL::ShaderGetPos()
851 if (m_pShader
[m_method
])
852 return m_pShader
[m_method
]->GetPosLoc();
857 GLint
CRenderSystemGL::ShaderGetCol()
859 if (m_pShader
[m_method
])
860 return m_pShader
[m_method
]->GetColLoc();
865 GLint
CRenderSystemGL::ShaderGetCoord0()
867 if (m_pShader
[m_method
])
868 return m_pShader
[m_method
]->GetCord0Loc();
873 GLint
CRenderSystemGL::ShaderGetCoord1()
875 if (m_pShader
[m_method
])
876 return m_pShader
[m_method
]->GetCord1Loc();
881 GLint
CRenderSystemGL::ShaderGetDepth()
883 if (m_pShader
[m_method
])
884 return m_pShader
[m_method
]->GetDepthLoc();
889 GLint
CRenderSystemGL::ShaderGetUniCol()
891 if (m_pShader
[m_method
])
892 return m_pShader
[m_method
]->GetUniColLoc();
897 GLint
CRenderSystemGL::ShaderGetModel()
899 if (m_pShader
[m_method
])
900 return m_pShader
[m_method
]->GetModelLoc();
905 GLint
CRenderSystemGL::ShaderGetMatrix()
907 if (m_pShader
[m_method
])
908 return m_pShader
[m_method
]->GetMatrixLoc();
913 GLint
CRenderSystemGL::ShaderGetClip()
915 if (m_pShader
[m_method
])
916 return m_pShader
[m_method
]->GetShaderClipLoc();
921 GLint
CRenderSystemGL::ShaderGetCoordStep()
923 if (m_pShader
[m_method
])
924 return m_pShader
[m_method
]->GetShaderCoordStepLoc();
929 std::string
CRenderSystemGL::GetShaderPath(const std::string
&filename
)
931 std::string path
= "GL/1.2/";
933 if (m_glslMajor
>= 4)
935 std::string file
= "special://xbmc/system/shaders/GL/4.0/" + filename
;
936 const CURL
pathToUrl(file
);
937 if (CFileUtils::Exists(pathToUrl
.Get()))
940 if (m_glslMajor
>= 2 || (m_glslMajor
== 1 && m_glslMinor
>= 50))