MythTV master
mythopengltonemap.cpp
Go to the documentation of this file.
1// MythTV
5
6#define LOC QString("Tonemap: ")
7
8#ifndef GL_SHADER_STORAGE_BUFFER
9#define GL_SHADER_STORAGE_BUFFER 0x90D2
10#endif
11#ifndef GL_ALL_BARRIER_BITS
12#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
13#endif
14#ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
15#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
16#endif
17#ifndef GL_STREAM_COPY
18#define GL_STREAM_COPY 0x88E2
19#endif
20#ifndef GL_WRITE_ONLY
21#define GL_WRITE_ONLY 0x88B9
22#endif
23
25{
26 if (Render)
27 {
28 Render->IncrRef();
29 m_render = Render;
30 m_extra = Render->extraFunctions();
31 }
32
33 if (ColourSpace)
34 {
35 ColourSpace->IncrRef();
36 m_colourSpace = ColourSpace;
38 }
39}
40
42{
43 if (m_render)
44 {
47 m_render->glDeleteBuffers(1, &m_storageBuffer);
48 delete m_shader;
49 delete m_texture;
52 }
53
54 if (m_colourSpace)
56}
57
58void MythOpenGLTonemap::UpdateColourSpace([[maybe_unused]] bool PrimariesChanged)
59{
60 OpenGLLocker locker(m_render);
61 if (m_shader)
62 {
65 }
66}
67
69{
70 return m_texture;
71}
72
73MythVideoTextureOpenGL* MythOpenGLTonemap::Map(std::vector<MythVideoTextureOpenGL*>& Inputs, QSize DisplaySize)
74{
75 size_t size = Inputs.size();
76 if (!size || !m_render || !m_extra)
77 return nullptr;
78
79 OpenGLLocker locker(m_render);
80 bool changed = m_outputSize != DisplaySize;
81
82 if (!m_texture || changed)
83 if (!CreateTexture(DisplaySize))
84 return nullptr;
85
86 changed |= (m_inputCount != size) || (m_inputType != Inputs[0]->m_frameFormat) ||
87 (m_inputSize != Inputs[0]->m_size);
88
89 if (!m_shader || changed)
90 if (!CreateShader(size, Inputs[0]->m_frameFormat, Inputs[0]->m_size))
91 return nullptr;
92
93 if (!m_storageBuffer)
94 {
95 m_render->glGenBuffers(1, &m_storageBuffer);
96 if (!m_storageBuffer)
97 {
98 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to allocate storage buffer");
99 return nullptr;
100 }
102 // Data structure passed to kernel. NOLINTNEXTLINE(modernize-avoid-c-arrays)
103 struct dummy { float a[2] {0.0F}; uint32_t b {0}; uint32_t c {0}; uint32_t d {0}; } buffer;
104 m_render->glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(dummy), &buffer, GL_STREAM_COPY);
105 m_render->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
106 }
107
109 for (size_t i = 0; i < size; ++i)
110 {
111 m_render->ActiveTexture(GL_TEXTURE0 + static_cast<GLuint>(i));
112 if (Inputs[i]->m_texture)
113 Inputs[i]->m_texture->bind();
114 else
115 m_render->glBindTexture(Inputs[i]->m_target, Inputs[i]->m_textureId);
116 }
117
118 m_extra->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_storageBuffer);
119 m_extra->glMemoryBarrier(GL_ALL_BARRIER_BITS);
120 m_extra->glBindImageTexture(0, m_texture->m_textureId, 0, GL_FALSE, 0, GL_WRITE_ONLY, QOpenGLTexture::RGBA16F);
121 m_extra->glDispatchCompute((static_cast<GLuint>(m_texture->m_size.width()) + 1) >> 3,
122 (static_cast<GLuint>(m_texture->m_size.height()) + 1) >> 3, 1);
124 m_extra->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
125 return m_texture;
126}
127
128bool MythOpenGLTonemap::CreateShader(size_t InputSize, VideoFrameType Type, QSize Size)
129{
130 delete m_shader;
131 m_shader = nullptr;
132 m_inputSize = Size;
133
134 QString source = (m_render->isOpenGLES() ? "#version 310 es\n" : "#version 430\n");
136 source.append("#define YV12\n");
137 if (m_render->isOpenGLES() && MythVideoFrame::ColorDepth(Type) > 8)
138 source.append("#define UNSIGNED\n");
139 source.append(GLSL430Tonemap);
140
142 if (m_shader)
143 {
144 m_inputCount = InputSize;
145 m_inputType = Type;
147 for (size_t i = 0; i < InputSize; ++i)
148 m_shader->setUniformValue(QString("texture%1").arg(i).toLatin1().constData(), static_cast<GLuint>(i));
149 LOG(VB_GENERAL, LOG_INFO, QString("Created tonemapping compute shader (%1 inputs)")
150 .arg(InputSize));
151 UpdateColourSpace(false);
152 return true;
153 }
154
155 return false;
156}
157
159{
160 delete m_texture;
161 m_texture = nullptr;
162 m_outputSize = Size;
163 GLuint textureid = 0;
164 m_render->glGenTextures(1, &textureid);
165 if (!textureid)
166 return false;
167
168 m_texture = new MythVideoTextureOpenGL(textureid);
169 if (!m_texture)
170 return false;
171
174 m_texture->m_target = QOpenGLTexture::Target2D;
175 m_texture->m_size = Size;
176 m_texture->m_totalSize = m_render->GetTextureSize(Size, m_texture->m_target != QOpenGLTexture::TargetRectangle);
179 m_extra->glTexStorage2D(m_texture->m_target, 1, QOpenGLTexture::RGBA16F,
180 static_cast<GLsizei>(Size.width()), static_cast<GLsizei>(Size.height()));
181 m_render->SetTextureFilters(m_texture, QOpenGLTexture::Linear);
182 return true;
183}
QOpenGLBuffer * m_vbo
bool CreateShader(size_t InputSize, VideoFrameType Type, QSize Size)
MythVideoColourSpace * m_colourSpace
MythRenderOpenGL * m_render
MythVideoTextureOpenGL * GetTexture()
MythOpenGLTonemap(MythRenderOpenGL *Render, MythVideoColourSpace *ColourSpace)
MythVideoTextureOpenGL * m_texture
QOpenGLShaderProgram * m_shader
~MythOpenGLTonemap() override
VideoFrameType m_inputType
QOpenGLExtraFunctions * m_extra
MythVideoTextureOpenGL * Map(std::vector< MythVideoTextureOpenGL * > &Inputs, QSize DisplaySize)
void UpdateColourSpace(bool PrimariesChanged)
bool CreateTexture(QSize Size)
void SetShaderProgramParams(QOpenGLShaderProgram *Program, const QMatrix4x4 &Value, const char *Uniform)
static constexpr GLuint kVertexSize
void ActiveTexture(GLuint ActiveTex)
bool EnableShaderProgram(QOpenGLShaderProgram *Program)
QOpenGLBuffer * CreateVBO(int Size, bool Release=true)
QSize GetTextureSize(QSize Size, bool Normalised)
void SetTextureFilters(MythGLTexture *Texture, QOpenGLTexture::Filter Filter, QOpenGLTexture::WrapMode Wrap=QOpenGLTexture::ClampToEdge)
QOpenGLShaderProgram * CreateComputeShader(const QString &Source)
MythVideoColourSpace contains a QMatrix4x4 that can convert YCbCr data to RGB.
void Updated(bool PrimariesChanged)
QMatrix4x4 GetPrimaryMatrix(void)
static bool FormatIs422(VideoFrameType Type)
Definition: mythframe.h:443
static bool FormatIs444(VideoFrameType Type)
Definition: mythframe.h:449
static bool FormatIs420(VideoFrameType Type)
Definition: mythframe.h:437
static int ColorDepth(int Format)
Definition: mythframe.h:398
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
virtual int IncrRef(void)
Increments reference count.
static const iso6937table * d
VideoFrameType
Definition: mythframe.h:20
@ FMT_RGBA32
Definition: mythframe.h:34
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
static const QString GLSL430Tonemap
#define LOC
#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
#define GL_STREAM_COPY
#define GL_SHADER_STORAGE_BUFFER
#define GL_ALL_BARRIER_BITS
#define GL_WRITE_ONLY
#define GL_TEXTURE0