diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index 7a7c56446..c8a47f563 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -23,14 +23,15 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int number_of_buffers, va_list _visible_area(Rect(0, 0, 1, 1)), _composite_src_output_y(0), _composite_shader(nullptr), - _rgb_shader(nullptr) + _rgb_shader(nullptr), + _output_buffer_data(nullptr) { _run_builders = new CRTRunBuilder *[NumberOfFields]; for(int builder = 0; builder < NumberOfFields; builder++) { - _run_builders[builder] = new CRTRunBuilder(OutputVertexSize); + _run_builders[builder] = new CRTRunBuilder(); } - _composite_src_runs = std::unique_ptr(new CRTRunBuilder(InputVertexSize)); +// _composite_src_runs = std::unique_ptr(new CRTRunBuilder(InputVertexSize)); va_list va; va_copy(va, sizes); @@ -45,6 +46,7 @@ OpenGLOutputBuilder::~OpenGLOutputBuilder() delete _run_builders[builder]; } delete[] _run_builders; + delete[] _output_buffer_data; free(_composite_shader); free(_rgb_shader); @@ -82,6 +84,8 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out glTexImage2D(GL_TEXTURE_2D, 0, (GLint)format, InputBufferBuilderWidth, InputBufferBuilderHeight, 0, format, GL_UNSIGNED_BYTE, _buffer_builder->buffers[buffer].data); } + printf("%s\n", glGetString(GL_VERSION)); + prepare_composite_input_shader(); prepare_rgb_output_shader(); @@ -92,7 +96,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer); glBufferData(GL_ARRAY_BUFFER, InputVertexBufferDataSize, NULL, GL_STREAM_DRAW); - _output_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, InputVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); + _output_buffer_data = new uint8_t[InputVertexBufferDataSize]; _output_buffer_data_pointer = 0; glBindVertexArray(output_vertex_array); prepare_output_vertex_array(); @@ -142,11 +146,11 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out } // check for anything to decode from composite - if(_composite_src_runs->number_of_vertices) - { +// if(_composite_src_runs->number_of_vertices) +// { // composite_input_shader_program->bind(); // _composite_src_runs->reset(); - } +// } // _output_mutex->unlock(); // return; @@ -178,12 +182,32 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out // update the total age at the start of this set of runs total_age += _run_builders[run]->duration; - if(_run_builders[run]->number_of_vertices > 0) + if(_run_builders[run]->amount_of_data > 0) { - glUniform1f(timestampBaseUniform, (GLfloat)total_age); + // upload if required + uint8_t *target = nullptr; + if(_run_builders[run]->amount_of_data != _run_builders[run]->amount_of_uploaded_data) + { + target = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, InputVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); - // draw this frame - GLsizei count = (GLsizei)_run_builders[run]->number_of_vertices; + size_t start = _run_builders[run]->start + _run_builders[run]->amount_of_uploaded_data; + size_t length = _run_builders[run]->amount_of_data + _run_builders[run]->amount_of_uploaded_data; + + if(start + length > InputVertexBufferDataSize) + { + memcpy(&target[start], &_output_buffer_data[start], InputVertexBufferDataSize - start); + memcpy(target, _output_buffer_data, length - (InputVertexBufferDataSize - start)); + } + else + memcpy(&target[start], &_output_buffer_data[start], length); + + glUnmapBuffer(GL_ARRAY_BUFFER); + _run_builders[run]->amount_of_uploaded_data = _run_builders[run]->amount_of_data; + } + + // draw + glUniform1f(timestampBaseUniform, (GLfloat)total_age); + GLsizei count = (GLsizei)(_run_builders[run]->amount_of_data / InputVertexSize); GLsizei max_count = (GLsizei)((InputVertexBufferDataSize - _run_builders[run]->start) / InputVertexSize); if(count < max_count) { diff --git a/Outputs/CRT/Internals/CRTOpenGL.hpp b/Outputs/CRT/Internals/CRTOpenGL.hpp index 11c955f54..95c1a18c6 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.hpp +++ b/Outputs/CRT/Internals/CRTOpenGL.hpp @@ -140,18 +140,17 @@ class OpenGLOutputBuilder { inline uint8_t *get_next_input_run() { - if (_output_buffer_data_pointer + 6 * InputVertexSize > InputVertexBufferDataSize) _output_buffer_data_pointer = 0; + _output_mutex->lock(); uint8_t *pointer = &_output_buffer_data[_output_buffer_data_pointer]; _output_buffer_data_pointer += 6 * InputVertexSize; + if(_output_buffer_data_pointer > InputVertexBufferDataSize) _output_buffer_data_pointer = 0; return pointer; -// _output_mutex->lock(); -// return (_output_device == Monitor) ? _run_builders[_run_write_pointer]->get_next_run(6) : _composite_src_runs->get_next_run(2); } inline void complete_input_run() { - _run_builders[_run_write_pointer]->number_of_vertices += 6; -// _output_mutex->unlock(); + _run_builders[_run_write_pointer]->amount_of_data += 6 * InputVertexSize; + _output_mutex->unlock(); } inline uint8_t *get_next_output_run() @@ -193,10 +192,11 @@ class OpenGLOutputBuilder { inline void increment_field() { + _output_mutex->lock(); _run_write_pointer = (_run_write_pointer + 1)%NumberOfFields; _run_builders[_run_write_pointer]->start = _output_buffer_data_pointer; - _run_builders[_run_write_pointer]->duration = 0; - _run_builders[_run_write_pointer]->number_of_vertices = 0; + _run_builders[_run_write_pointer]->reset(); + _output_mutex->unlock(); } inline void allocate_write_area(size_t required_length) @@ -244,6 +244,7 @@ class OpenGLOutputBuilder { uint8_t *_output_buffer_data; size_t _output_buffer_data_pointer; + GLsync _output_buffer_sync; }; } diff --git a/Outputs/CRT/Internals/CRTRunBuilder.cpp b/Outputs/CRT/Internals/CRTRunBuilder.cpp index 9d6df1384..5191a1c84 100644 --- a/Outputs/CRT/Internals/CRTRunBuilder.cpp +++ b/Outputs/CRT/Internals/CRTRunBuilder.cpp @@ -10,25 +10,3 @@ #include "CRTOpenGL.hpp" using namespace Outputs::CRT; - -/*void CRTRunBuilder::reset() -{ - number_of_vertices = 0; - uploaded_vertices = 0; - duration = 0; -} - -uint8_t *CRTRunBuilder::get_next_run(size_t number_of_vertices_in_run) -{ - // get a run from the allocated list, allocating more if we're about to overrun - if((number_of_vertices + number_of_vertices_in_run) * _vertex_size >= _runs.size()) - { - _runs.resize(_runs.size() + _vertex_size * 100); - } - - uint8_t *next_run = &_runs[number_of_vertices * _vertex_size]; - number_of_vertices += number_of_vertices_in_run; - - return next_run; -} -*/ \ No newline at end of file diff --git a/Outputs/CRT/Internals/CRTRunBuilder.hpp b/Outputs/CRT/Internals/CRTRunBuilder.hpp index db7020647..137f4ed85 100644 --- a/Outputs/CRT/Internals/CRTRunBuilder.hpp +++ b/Outputs/CRT/Internals/CRTRunBuilder.hpp @@ -15,17 +15,15 @@ namespace Outputs { namespace CRT { struct CRTRunBuilder { - CRTRunBuilder(size_t vertex_size) : _vertex_size(vertex_size), duration(0), start(0), number_of_vertices(0) {} // reset(); + CRTRunBuilder() : start(0) { reset(); } // Resets the run builder. -// void reset(); - - // Getter for new storage plus backing storage; in RGB mode input runs will map directly - // from the input buffer to the screen. In composite mode input runs will map from the - // input buffer to the processing buffer, and output runs will map from the processing - // buffer to the screen. -// uint8_t *get_next_run(size_t number_of_vertices); -// std::vector _runs; + inline void reset() + { + duration = 0; + amount_of_uploaded_data = 0; + amount_of_data = 0; + } // Container for total length in cycles of all contained runs. uint32_t duration; @@ -33,11 +31,8 @@ struct CRTRunBuilder { // Storage for the length of run data uploaded so far; reset to zero by reset but otherwise // entrusted to the CRT to update. -// size_t uploaded_vertices; - size_t number_of_vertices; - - private: - size_t _vertex_size; + size_t amount_of_uploaded_data; + size_t amount_of_data; }; }