Skip to content

Commit

Permalink
Add OpenGL ES compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe authored and garbear committed Jul 7, 2023
1 parent 3ffc8a4 commit 02e5b94
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 59 deletions.
166 changes: 110 additions & 56 deletions xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "cores/RetroPlayer/buffers/RenderBufferPoolOpenGLES.h"
#include "cores/RetroPlayer/rendering/RenderContext.h"
#include "cores/RetroPlayer/rendering/RenderVideoSettings.h"
#include "cores/RetroPlayer/shaders/gl/ShaderPresetGL.h"
#include "utils/GLUtils.h"
#include "utils/log.h"

Expand Down Expand Up @@ -48,6 +49,9 @@ CRPRendererOpenGLES::CRPRendererOpenGLES(const CRenderSettings& renderSettings,
std::shared_ptr<IRenderBufferPool> bufferPool)
: CRPBaseRenderer(renderSettings, context, std::move(bufferPool))
{
// Initialize CRPBaseRenderer
m_shaderPreset.reset(new SHADER::CShaderPresetGL(m_context));

glGenBuffers(1, &m_mainIndexVBO);
glGenBuffers(1, &m_mainVertexVBO);
glGenBuffers(1, &m_blackbarsVertexVBO);
Expand Down Expand Up @@ -245,73 +249,123 @@ void CRPRendererOpenGLES::Render(uint8_t alpha)

const uint32_t color = (alpha << 24) | 0xFFFFFF;

glBindTexture(m_textureTarget, renderBuffer->TextureID());
RenderBufferTextures* rbTextures;
const auto it = m_RBTexturesMap.find(renderBuffer);
if (it != m_RBTexturesMap.end())
{
rbTextures = it->second.get();
}
else
{
// We can't copy or move CGLTexture, so construct source/target in-place
rbTextures = new RenderBufferTextures{
// Source texture
{
static_cast<unsigned int>(renderBuffer->GetWidth()),
static_cast<unsigned int>(renderBuffer->GetHeight()),
XB_FMT_RGB8,
renderBuffer->TextureID(),
},
// Target texture
{
static_cast<unsigned int>(m_context.GetScreenWidth()),
static_cast<unsigned int>(m_context.GetScreenHeight()),
},
};
m_RBTexturesMap.emplace(renderBuffer, rbTextures);
}

const auto sourceTexture = &rbTextures->source;
const auto targetTexture = &rbTextures->target;

glBindTexture(m_textureTarget, sourceTexture->getMTexture());

GLint filter = GL_NEAREST;
if (GetRenderSettings().VideoSettings().GetScalingMethod() == SCALINGMETHOD::LINEAR)
filter = GL_LINEAR;

glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(m_textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

m_context.EnableGUIShader(GL_SHADER_METHOD::TEXTURE_NOALPHA);
Updateshaders();

GLubyte colour[4];
GLubyte idx[4] = {0, 1, 3, 2}; // Determines order of triangle strip
struct PackedVertex
if (m_bUseShaderPreset)
{
float x, y, z;
float u1, v1;
} vertex[4];

GLint vertLoc = m_context.GUIShaderGetPos();
GLint loc = m_context.GUIShaderGetCoord0();
GLint uniColLoc = m_context.GUIShaderGetUniCol();

// Setup color values
colour[0] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::R, color);
colour[1] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::G, color);
colour[2] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::B, color);
colour[3] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::A, color);

for (unsigned int i = 0; i < 4; i++)
const CPoint destPoints[4] = {m_rotatedDestCoords[0], m_rotatedDestCoords[1],
m_rotatedDestCoords[2], m_rotatedDestCoords[3]};

targetTexture->CreateTextureObject();

SHADER::CShaderTextureGL source(*sourceTexture);
SHADER::CShaderTextureGL target(*targetTexture);
if (!m_shaderPreset->RenderUpdate(destPoints, &source, &target))
{
m_shadersNeedUpdate = false;
m_bUseShaderPreset = false;
}
}
else
{
// Setup vertex position values
vertex[i].x = m_rotatedDestCoords[i].x;
vertex[i].y = m_rotatedDestCoords[i].y;
vertex[i].z = 0.0f;
m_context.EnableGUIShader(GL_SHADER_METHOD::TEXTURE_NOALPHA);

GLubyte colour[4];
GLubyte idx[4] = {0, 1, 3, 2}; // Determines order of triangle strip
struct PackedVertex
{
float x, y, z;
float u1, v1;
} vertex[4];

GLint vertLoc = m_context.GUIShaderGetPos();
GLint loc = m_context.GUIShaderGetCoord0();
GLint uniColLoc = m_context.GUIShaderGetUniCol();

// Setup color values
colour[0] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::R, color);
colour[1] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::G, color);
colour[2] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::B, color);
colour[3] = UTILS::GL::GetChannelFromARGB(UTILS::GL::ColorChannel::A, color);

for (unsigned int i = 0; i < 4; i++)
{
// Setup vertex position values
vertex[i].x = m_rotatedDestCoords[i].x;
vertex[i].y = m_rotatedDestCoords[i].y;
vertex[i].z = 0.0f;
}

// Setup texture coordinates
vertex[0].u1 = vertex[3].u1 = rect.x1;
vertex[0].v1 = vertex[1].v1 = rect.y1;
vertex[1].u1 = vertex[2].u1 = rect.x2;
vertex[2].v1 = vertex[3].v1 = rect.y2;

glBindBuffer(GL_ARRAY_BUFFER, m_mainVertexVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex) * 4, &vertex[0], GL_STATIC_DRAW);

glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex),
reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x)));
glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex),
reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1)));

glEnableVertexAttribArray(vertLoc);
glEnableVertexAttribArray(loc);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_mainIndexVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 4, idx, GL_STATIC_DRAW);

glUniform4f(uniColLoc, (colour[0] / 255.0f), (colour[1] / 255.0f), (colour[2] / 255.0f),
(colour[3] / 255.0f));
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0);

glDisableVertexAttribArray(vertLoc);
glDisableVertexAttribArray(loc);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

m_context.DisableGUIShader();
}

// Setup texture coordinates
vertex[0].u1 = vertex[3].u1 = rect.x1;
vertex[0].v1 = vertex[1].v1 = rect.y1;
vertex[1].u1 = vertex[2].u1 = rect.x2;
vertex[2].v1 = vertex[3].v1 = rect.y2;

glBindBuffer(GL_ARRAY_BUFFER, m_mainVertexVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(PackedVertex) * 4, &vertex[0], GL_STATIC_DRAW);

glVertexAttribPointer(vertLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex),
reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, x)));
glVertexAttribPointer(loc, 2, GL_FLOAT, 0, sizeof(PackedVertex),
reinterpret_cast<const GLvoid*>(offsetof(PackedVertex, u1)));

glEnableVertexAttribArray(vertLoc);
glEnableVertexAttribArray(loc);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_mainIndexVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 4, idx, GL_STATIC_DRAW);

glUniform4f(uniColLoc, (colour[0] / 255.0f), (colour[1] / 255.0f), (colour[2] / 255.0f),
(colour[3] / 255.0f));
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0);

glDisableVertexAttribArray(vertLoc);
glDisableVertexAttribArray(loc);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

m_context.DisableGUIShader();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
#include "cores/RetroPlayer/buffers/BaseRenderBufferPool.h"
#include "cores/RetroPlayer/buffers/video/RenderBufferSysMem.h"
#include "cores/RetroPlayer/process/RPProcessInfo.h"
#include "guilib/TextureGL.h"

#include <atomic>
#include <map>
#include <memory>
#include <stdint.h>
#include <vector>

Expand All @@ -24,6 +27,8 @@ namespace KODI
{
namespace RETRO
{
class CRenderBufferOpenGLES;

class CRendererFactoryOpenGLES : public IRendererFactory
{
public:
Expand Down Expand Up @@ -76,6 +81,14 @@ class CRPRendererOpenGLES : public CRPBaseRenderer
GLuint m_blackbarsVertexVBO;
GLenum m_textureTarget = GL_TEXTURE_2D;
float m_clearColour = 0.0f;

struct RenderBufferTextures
{
CGLTexture source;
CGLTexture target;
};

std::map<CRenderBufferOpenGLES*, std::unique_ptr<RenderBufferTextures>> m_RBTexturesMap;
};
} // namespace RETRO
} // namespace KODI
6 changes: 6 additions & 0 deletions xbmc/cores/RetroPlayer/shaders/gl/ShaderGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ bool CShaderGL::Create(const std::string& shaderSource,

glUseProgram(m_shaderProgram);

#ifndef HAS_GLES
glGenVertexArrays(1, &VAO);
#endif
glGenBuffers(3, VBO);
glGenBuffers(1, &EBO);
return true;
Expand All @@ -112,7 +114,9 @@ void CShaderGL::Render(IShaderTexture* source, IShaderTexture* target)
// }
// }

#ifndef HAS_GLES
glBindVertexArray(VAO);
#endif
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

Expand All @@ -121,7 +125,9 @@ void CShaderGL::SetShaderParameters()
glUseProgram(m_shaderProgram);
glUniformMatrix4fv(m_MVPMatrixLoc, 1, GL_FALSE, reinterpret_cast<const GLfloat*>(&m_MVP));

#ifndef HAS_GLES
glBindVertexArray(VAO);
#endif

glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(m_VertexCoords), m_VertexCoords, GL_STATIC_DRAW);
Expand Down
2 changes: 2 additions & 0 deletions xbmc/cores/RetroPlayer/shaders/gl/ShaderGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ class CShaderGL : public IShader
GLint m_InputSizeLoc = -1;
GLint m_MVPMatrixLoc = -1;

#ifndef HAS_GLES
GLuint VAO = 0;
#endif
GLuint EBO = 0;
GLuint VBO[3] = {};

Expand Down
2 changes: 2 additions & 0 deletions xbmc/cores/RetroPlayer/shaders/gl/ShaderLutGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ std::unique_ptr<IShaderTexture> CShaderLutGL::CreateLUTTexture(RETRO::CRenderCon
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0.0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, MAX_FLOAT);

#ifndef HAS_GLES
GLfloat blackBorder[4] = {0.0f, 0.0f, 0.0f, 0.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, blackBorder);
#endif

if (lut.mipmap)
textureGL->SetMipmapping();
Expand Down
12 changes: 9 additions & 3 deletions xbmc/cores/RetroPlayer/shaders/gl/ShaderPresetGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "ShaderPresetGL.h"

#include "ServiceBroker.h"
#include "ShaderUtilsGL.h"
#include "cores/RetroPlayer/rendering/RenderContext.h"
#include "cores/RetroPlayer/shaders/ShaderPresetFactory.h"
#include "cores/RetroPlayer/shaders/ShaderUtils.h"
Expand Down Expand Up @@ -305,17 +306,22 @@ bool CShaderPresetGL::CreateShaderTextures()
return false;
}

auto wrapType = CShaderUtilsGL::TranslateWrapType(WRAP_TYPE_BORDER);

glBindTexture(GL_TEXTURE_2D, texture->getMTexture());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapType);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapType);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, wrapType);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0.0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, MAX_FLOAT);

#ifndef HAS_GLES
GLfloat blackBorder[4] = {0.0f, 0.0f, 0.0f, 0.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, blackBorder);
#endif

m_pShaderTextures.emplace_back(new CShaderTextureGL(*texture));
m_pShaders[shaderIdx]->SetSizes(prevSize, scaledSize);
Expand Down
4 changes: 4 additions & 0 deletions xbmc/cores/RetroPlayer/shaders/gl/ShaderUtilsGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ GLint CShaderUtilsGL::TranslateWrapType(WRAP_TYPE wrap)
break;
case WRAP_TYPE_BORDER:
default:
#ifdef HAS_GLES
glWrap = GL_CLAMP_TO_EDGE;
#else
glWrap = GL_CLAMP_TO_BORDER;
#endif
break;
}

Expand Down

0 comments on commit 02e5b94

Please sign in to comment.