mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-24 12:30:17 +00:00
Tidied up a little, mostly bumping things out of just-in-time creation that I can just do well in advance.
This commit is contained in:
parent
069ec2e889
commit
fe8b0ebc7e
@ -12,52 +12,6 @@
|
|||||||
#include "CRTOpenGL.hpp"
|
#include "CRTOpenGL.hpp"
|
||||||
#include "../../../SignalProcessing/FIRFilter.hpp"
|
#include "../../../SignalProcessing/FIRFilter.hpp"
|
||||||
|
|
||||||
using namespace Outputs::CRT;
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
static const GLenum first_supplied_buffer_texture_unit = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int buffer_depth) :
|
|
||||||
_run_write_pointer(0),
|
|
||||||
_output_mutex(new std::mutex),
|
|
||||||
_visible_area(Rect(0, 0, 1, 1)),
|
|
||||||
_composite_src_output_y(0),
|
|
||||||
_composite_shader(nullptr),
|
|
||||||
_rgb_shader(nullptr),
|
|
||||||
_output_buffer_data(nullptr),
|
|
||||||
_output_buffer_sync(nullptr),
|
|
||||||
_input_texture_data(nullptr)
|
|
||||||
{
|
|
||||||
_run_builders = new CRTRunBuilder *[NumberOfFields];
|
|
||||||
for(int builder = 0; builder < NumberOfFields; builder++)
|
|
||||||
{
|
|
||||||
_run_builders[builder] = new CRTRunBuilder();
|
|
||||||
}
|
|
||||||
// _composite_src_runs = std::unique_ptr<CRTRunBuilder>(new CRTRunBuilder(InputVertexSize));
|
|
||||||
|
|
||||||
_buffer_builder = std::unique_ptr<CRTInputBufferBuilder>(new CRTInputBufferBuilder(buffer_depth));
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenGLOutputBuilder::~OpenGLOutputBuilder()
|
|
||||||
{
|
|
||||||
for(int builder = 0; builder < NumberOfFields; builder++)
|
|
||||||
{
|
|
||||||
delete _run_builders[builder];
|
|
||||||
}
|
|
||||||
delete[] _run_builders;
|
|
||||||
|
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
||||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
|
||||||
glDeleteTextures(1, &textureName);
|
|
||||||
glDeleteBuffers(1, &_input_texture_array);
|
|
||||||
glDeleteBuffers(1, &output_array_buffer);
|
|
||||||
glDeleteVertexArrays(1, &output_vertex_array);
|
|
||||||
|
|
||||||
free(_composite_shader);
|
|
||||||
free(_rgb_shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const GLint internalFormatForDepth(size_t depth)
|
static const GLint internalFormatForDepth(size_t depth)
|
||||||
{
|
{
|
||||||
switch(depth)
|
switch(depth)
|
||||||
@ -82,46 +36,62 @@ static const GLenum formatForDepth(size_t depth)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty)
|
|
||||||
|
using namespace Outputs::CRT;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static const GLenum first_supplied_buffer_texture_unit = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int buffer_depth) :
|
||||||
|
_run_write_pointer(0),
|
||||||
|
_output_mutex(new std::mutex),
|
||||||
|
_visible_area(Rect(0, 0, 1, 1)),
|
||||||
|
_composite_src_output_y(0),
|
||||||
|
_composite_shader(nullptr),
|
||||||
|
_rgb_shader(nullptr),
|
||||||
|
_output_buffer_data(nullptr),
|
||||||
|
_output_buffer_sync(nullptr),
|
||||||
|
_input_texture_data(nullptr),
|
||||||
|
_output_buffer_data_pointer(0)
|
||||||
{
|
{
|
||||||
// establish essentials
|
_run_builders = new CRTRunBuilder *[NumberOfFields];
|
||||||
if(!composite_input_shader_program && !rgb_shader_program)
|
for(int builder = 0; builder < NumberOfFields; builder++)
|
||||||
{
|
{
|
||||||
// generate and bind texture for input data
|
_run_builders[builder] = new CRTRunBuilder();
|
||||||
glGenTextures(1, &textureName);
|
}
|
||||||
glActiveTexture(GL_TEXTURE0 + first_supplied_buffer_texture_unit);
|
_buffer_builder = std::unique_ptr<CRTInputBufferBuilder>(new CRTInputBufferBuilder(buffer_depth));
|
||||||
glBindTexture(GL_TEXTURE_2D, textureName);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
glGenBuffers(1, &_input_texture_array);
|
// create the surce texture
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _input_texture_array);
|
glGenTextures(1, &textureName);
|
||||||
_input_texture_array_size = (GLsizeiptr)(InputBufferBuilderWidth * InputBufferBuilderHeight * _buffer_builder->bytes_per_pixel);
|
glActiveTexture(GL_TEXTURE0 + first_supplied_buffer_texture_unit);
|
||||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, _input_texture_array_size, NULL, GL_STREAM_DRAW);
|
glBindTexture(GL_TEXTURE_2D, textureName);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, internalFormatForDepth(_buffer_builder->bytes_per_pixel), InputBufferBuilderWidth, InputBufferBuilderHeight, 0, formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormatForDepth(_buffer_builder->bytes_per_pixel), InputBufferBuilderWidth, InputBufferBuilderHeight, 0, formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE, nullptr);
|
// create a pixel unpack buffer
|
||||||
|
glGenBuffers(1, &_input_texture_array);
|
||||||
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _input_texture_array);
|
||||||
|
_input_texture_array_size = (GLsizeiptr)(InputBufferBuilderWidth * InputBufferBuilderHeight * _buffer_builder->bytes_per_pixel);
|
||||||
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, _input_texture_array_size, NULL, GL_STREAM_DRAW);
|
||||||
|
|
||||||
prepare_composite_input_shader();
|
// map the buffer for clients
|
||||||
prepare_rgb_output_shader();
|
_input_texture_data = (uint8_t *)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _input_texture_array_size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||||
|
|
||||||
glGenVertexArrays(1, &output_vertex_array);
|
// create the output vertex array
|
||||||
glGenBuffers(1, &output_array_buffer);
|
glGenVertexArrays(1, &output_vertex_array);
|
||||||
output_vertices_per_slice = 0;
|
glBindVertexArray(output_vertex_array);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer);
|
// create a buffer for output vertex attributes
|
||||||
|
glGenBuffers(1, &output_array_buffer);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, OutputVertexBufferDataSize, NULL, GL_STREAM_DRAW);
|
||||||
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, OutputVertexBufferDataSize, NULL, GL_STREAM_DRAW);
|
// map that buffer too, for any CRT activity that may occur before the first draw
|
||||||
_output_buffer_data_pointer = 0;
|
_output_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, OutputVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||||
|
|
||||||
glBindVertexArray(output_vertex_array);
|
|
||||||
prepare_output_vertex_array();
|
|
||||||
|
|
||||||
// This should return either an actual framebuffer number, if this is a target with a framebuffer intended for output,
|
|
||||||
// or 0 if no framebuffer is bound, in which case 0 is also what we want to supply to bind the implied framebuffer. So
|
|
||||||
// it works either way.
|
|
||||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&defaultFramebuffer);
|
|
||||||
|
|
||||||
// Create intermediate textures and bind to slots 0, 1 and 2
|
// Create intermediate textures and bind to slots 0, 1 and 2
|
||||||
// glActiveTexture(GL_TEXTURE0);
|
// glActiveTexture(GL_TEXTURE0);
|
||||||
@ -130,6 +100,40 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
// filteredYTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight));
|
// filteredYTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight));
|
||||||
// glActiveTexture(GL_TEXTURE2);
|
// glActiveTexture(GL_TEXTURE2);
|
||||||
// filteredTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight));
|
// filteredTexture = std::unique_ptr<OpenGL::TextureTarget>(new OpenGL::TextureTarget(IntermediateBufferWidth, IntermediateBufferHeight));
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLOutputBuilder::~OpenGLOutputBuilder()
|
||||||
|
{
|
||||||
|
for(int builder = 0; builder < NumberOfFields; builder++)
|
||||||
|
{
|
||||||
|
delete _run_builders[builder];
|
||||||
|
}
|
||||||
|
delete[] _run_builders;
|
||||||
|
|
||||||
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
glDeleteTextures(1, &textureName);
|
||||||
|
glDeleteBuffers(1, &_input_texture_array);
|
||||||
|
glDeleteBuffers(1, &output_array_buffer);
|
||||||
|
glDeleteVertexArrays(1, &output_vertex_array);
|
||||||
|
|
||||||
|
free(_composite_shader);
|
||||||
|
free(_rgb_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty)
|
||||||
|
{
|
||||||
|
// establish essentials
|
||||||
|
if(!composite_input_shader_program && !rgb_shader_program)
|
||||||
|
{
|
||||||
|
prepare_composite_input_shader();
|
||||||
|
prepare_rgb_output_shader();
|
||||||
|
prepare_output_vertex_array();
|
||||||
|
|
||||||
|
// This should return either an actual framebuffer number, if this is a target with a framebuffer intended for output,
|
||||||
|
// or 0 if no framebuffer is bound, in which case 0 is also what we want to supply to bind the implied framebuffer. So
|
||||||
|
// it works either way.
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&defaultFramebuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// lock down any further work on the current frame
|
// lock down any further work on the current frame
|
||||||
@ -145,29 +149,25 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
|
|
||||||
// upload more source pixel data if any; we'll always resubmit the last line submitted last
|
// upload more source pixel data if any; we'll always resubmit the last line submitted last
|
||||||
// time as it may have had extra data appended to it
|
// time as it may have had extra data appended to it
|
||||||
// for(unsigned int buffer = 0; buffer < _buffer_builder->number_of_buffers; buffer++)
|
if(_buffer_builder->_next_write_y_position < _buffer_builder->last_uploaded_line)
|
||||||
// {
|
{
|
||||||
// glActiveTexture(GL_TEXTURE0 + first_supplied_buffer_texture_unit + buffer);
|
glTexSubImage2D( GL_TEXTURE_2D, 0,
|
||||||
if(_buffer_builder->_next_write_y_position < _buffer_builder->last_uploaded_line)
|
0, (GLint)_buffer_builder->last_uploaded_line,
|
||||||
{
|
InputBufferBuilderWidth, (GLint)(InputBufferBuilderHeight - _buffer_builder->last_uploaded_line),
|
||||||
glTexSubImage2D( GL_TEXTURE_2D, 0,
|
formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE,
|
||||||
0, (GLint)_buffer_builder->last_uploaded_line,
|
(void *)(_buffer_builder->last_uploaded_line * InputBufferBuilderWidth * _buffer_builder->bytes_per_pixel));
|
||||||
InputBufferBuilderWidth, (GLint)(InputBufferBuilderHeight - _buffer_builder->last_uploaded_line),
|
_buffer_builder->last_uploaded_line = 0;
|
||||||
formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE,
|
}
|
||||||
(void *)(_buffer_builder->last_uploaded_line * InputBufferBuilderWidth * _buffer_builder->bytes_per_pixel));
|
|
||||||
_buffer_builder->last_uploaded_line = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_buffer_builder->_next_write_y_position > _buffer_builder->last_uploaded_line)
|
if(_buffer_builder->_next_write_y_position > _buffer_builder->last_uploaded_line)
|
||||||
{
|
{
|
||||||
glTexSubImage2D( GL_TEXTURE_2D, 0,
|
glTexSubImage2D( GL_TEXTURE_2D, 0,
|
||||||
0, (GLint)_buffer_builder->last_uploaded_line,
|
0, (GLint)_buffer_builder->last_uploaded_line,
|
||||||
InputBufferBuilderWidth, (GLint)(1 + _buffer_builder->_next_write_y_position - _buffer_builder->last_uploaded_line),
|
InputBufferBuilderWidth, (GLint)(1 + _buffer_builder->_next_write_y_position - _buffer_builder->last_uploaded_line),
|
||||||
formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE,
|
formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE,
|
||||||
(void *)(_buffer_builder->last_uploaded_line * InputBufferBuilderWidth * _buffer_builder->bytes_per_pixel));
|
(void *)(_buffer_builder->last_uploaded_line * InputBufferBuilderWidth * _buffer_builder->bytes_per_pixel));
|
||||||
_buffer_builder->last_uploaded_line = _buffer_builder->_next_write_y_position;
|
_buffer_builder->last_uploaded_line = _buffer_builder->_next_write_y_position;
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// check for anything to decode from composite
|
// check for anything to decode from composite
|
||||||
// if(_composite_src_runs->number_of_vertices)
|
// if(_composite_src_runs->number_of_vertices)
|
||||||
@ -230,7 +230,6 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
}
|
}
|
||||||
|
|
||||||
// drawing commands having been issued, reclaim the array buffer pointer
|
// drawing commands having been issued, reclaim the array buffer pointer
|
||||||
// _buffer_builder->move_to_new_line();
|
|
||||||
_output_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, OutputVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
_output_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, OutputVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||||
_input_texture_data = (uint8_t *)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _input_texture_array_size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
_input_texture_data = (uint8_t *)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _input_texture_array_size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||||
_output_mutex->unlock();
|
_output_mutex->unlock();
|
||||||
|
@ -75,7 +75,6 @@ class OpenGLOutputBuilder {
|
|||||||
std::unique_ptr<OpenGL::Shader> composite_input_shader_program, composite_output_shader_program;
|
std::unique_ptr<OpenGL::Shader> composite_input_shader_program, composite_output_shader_program;
|
||||||
|
|
||||||
GLuint output_array_buffer, output_vertex_array;
|
GLuint output_array_buffer, output_vertex_array;
|
||||||
size_t output_vertices_per_slice;
|
|
||||||
|
|
||||||
GLint windowSizeUniform, timestampBaseUniform;
|
GLint windowSizeUniform, timestampBaseUniform;
|
||||||
GLint boundsOriginUniform, boundsSizeUniform;
|
GLint boundsOriginUniform, boundsSizeUniform;
|
||||||
|
Loading…
Reference in New Issue
Block a user