diff --git a/Outputs/CRT/Internals/CRTConstants.hpp b/Outputs/CRT/Internals/CRTConstants.hpp index 27b45cb1a..6151ecc79 100644 --- a/Outputs/CRT/Internals/CRTConstants.hpp +++ b/Outputs/CRT/Internals/CRTConstants.hpp @@ -17,30 +17,30 @@ namespace CRT { // Output vertices are those used to copy from an input buffer — whether it describes data that maps directly to RGB // or is one of the intermediate buffers that we've used to convert from composite towards RGB. -const size_t OutputVertexOffsetOfPosition = 0; -const size_t OutputVertexOffsetOfTexCoord = 4; -const size_t OutputVertexOffsetOfTimestamp = 8; -const size_t OutputVertexOffsetOfLateral = 12; -const size_t OutputVertexOffsetOfFrameID = 13; +const GLsizei OutputVertexOffsetOfPosition = 0; +const GLsizei OutputVertexOffsetOfTexCoord = 4; +const GLsizei OutputVertexOffsetOfTimestamp = 8; +const GLsizei OutputVertexOffsetOfLateral = 12; +const GLsizei OutputVertexOffsetOfFrameID = 13; -const size_t OutputVertexSize = 16; +const GLsizei OutputVertexSize = 16; // Input vertices, used only in composite mode, map from the input buffer to temporary buffer locations; such // remapping occurs to ensure a continous stream of data for each scan, giving correct out-of-bounds behaviour -const size_t SourceVertexOffsetOfInputPosition = 0; -const size_t SourceVertexOffsetOfOutputPosition = 4; -const size_t SourceVertexOffsetOfPhaseAmplitudeAndAlpha = 8; -const size_t SourceVertexOffsetOfPhaseTime = 12; +const GLsizei SourceVertexOffsetOfInputPosition = 0; +const GLsizei SourceVertexOffsetOfOutputPosition = 4; +const GLsizei SourceVertexOffsetOfPhaseAmplitudeAndAlpha = 8; +const GLsizei SourceVertexOffsetOfPhaseTime = 12; -const size_t SourceVertexSize = 16; +const GLsizei SourceVertexSize = 16; // These constants hold the size of the rolling buffer to which the CPU writes -const int InputBufferBuilderWidth = 2048; -const int InputBufferBuilderHeight = 1024; +const GLsizei InputBufferBuilderWidth = 2048; +const GLsizei InputBufferBuilderHeight = 1024; // This is the size of the intermediate buffers used during composite to RGB conversion -const int IntermediateBufferWidth = 2048; -const int IntermediateBufferHeight = 2048; +const GLsizei IntermediateBufferWidth = 2048; +const GLsizei IntermediateBufferHeight = 2048; // Some internal buffer sizes const GLsizeiptr OutputVertexBufferDataSize = 262080; // a multiple of 6 * OutputVertexSize diff --git a/Outputs/CRT/Internals/CRTInputBufferBuilder.hpp b/Outputs/CRT/Internals/CRTInputBufferBuilder.hpp index d6eab1ab1..4e074f2bc 100644 --- a/Outputs/CRT/Internals/CRTInputBufferBuilder.hpp +++ b/Outputs/CRT/Internals/CRTInputBufferBuilder.hpp @@ -43,12 +43,6 @@ struct CRTInputBufferBuilder { { _next_write_x_position = 0; _next_write_y_position = (_next_write_y_position+1)%InputBufferBuilderHeight; -// if(!_next_write_y_position) -// { -// glClientWaitSync(_wraparound_sync, 0, ~(GLuint64)0); -// glDeleteSync(_wraparound_sync); -// _wraparound_sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -// } } inline uint8_t *get_write_target(uint8_t *buffer) diff --git a/Outputs/CRT/Internals/CRTOpenGL.cpp b/Outputs/CRT/Internals/CRTOpenGL.cpp index a9ea0d8b0..706368e6f 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.cpp +++ b/Outputs/CRT/Internals/CRTOpenGL.cpp @@ -36,6 +36,34 @@ static const GLenum formatForDepth(size_t depth) } } +static int getCircularRanges(GLsizei start, GLsizei end, GLsizei buffer_length, GLsizei *ranges) +{ + GLsizei length = end - start; + if(!length) return 0; + if(length > buffer_length) + { + ranges[0] = 0; + ranges[1] = buffer_length; + return 1; + } + else + { + ranges[0] = start % buffer_length; + if(ranges[0]+length < buffer_length) + { + ranges[1] = length; + return 1; + } + else + { + ranges[1] = buffer_length - ranges[0]; + ranges[2] = 0; + ranges[3] = length - ranges[1]; + return 2; + } + } +} + using namespace Outputs::CRT; namespace { @@ -207,38 +235,14 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out if(_drawn_source_buffer_data_pointer != _source_buffer_data_pointer) { // determine how many lines are newly reclaimed; they'll need to be cleared - uint16_t clearing_zones[4]; - int number_of_clearing_zones = 0; + GLsizei clearing_zones[4], drawing_zones[4]; + int number_of_clearing_zones = getCircularRanges(_cleared_composite_output_y+1, _composite_src_output_y+1, IntermediateBufferHeight, clearing_zones); + int number_of_drawing_zones = getCircularRanges(_drawn_source_buffer_data_pointer, _source_buffer_data_pointer, SourceVertexBufferDataSize, drawing_zones); - if(_composite_src_output_y != _cleared_composite_output_y) - { - uint16_t lines_to_clear = _composite_src_output_y - _cleared_composite_output_y; - if(lines_to_clear > IntermediateBufferHeight) - { - number_of_clearing_zones = 1; - clearing_zones[0] = 0; - clearing_zones[1] = IntermediateBufferHeight; - } - else - { - clearing_zones[0] = (_cleared_composite_output_y+1)%IntermediateBufferHeight; - if(clearing_zones[0]+lines_to_clear < IntermediateBufferHeight) - { - clearing_zones[1] = lines_to_clear; - number_of_clearing_zones = 1; - } - else - { - clearing_zones[1] = IntermediateBufferHeight - clearing_zones[0]; - clearing_zones[2] = 0; - clearing_zones[3] = lines_to_clear - clearing_zones[1]; - number_of_clearing_zones = 2; - } - } - - _composite_src_output_y %= IntermediateBufferHeight; - _cleared_composite_output_y = _composite_src_output_y; - } + _composite_src_output_y %= IntermediateBufferHeight; + _cleared_composite_output_y = _composite_src_output_y; + _source_buffer_data_pointer %= SourceVertexBufferDataSize; + _drawn_source_buffer_data_pointer = _source_buffer_data_pointer; // all drawing will be from the source vertex array and without blending glBindVertexArray(source_vertex_array); @@ -260,22 +264,10 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out glDisable(GL_SCISSOR_TEST); } - size_t new_data_size = _source_buffer_data_pointer - _drawn_source_buffer_data_pointer; - size_t new_data_start = _drawn_source_buffer_data_pointer; - _source_buffer_data_pointer %= SourceVertexBufferDataSize; - _drawn_source_buffer_data_pointer = _source_buffer_data_pointer; - - if(new_data_size >= SourceVertexBufferDataSize) + // draw as desired + for(int c = 0; c < number_of_drawing_zones; c++) { - new_data_size = SourceVertexBufferDataSize; - new_data_start = 0; - } - - size_t first_data_length = std::min(SourceVertexBufferDataSize - new_data_start, new_data_size); - glDrawArrays(GL_LINES, (GLint)(new_data_start / SourceVertexSize), (GLsizei)(first_data_length / SourceVertexSize)); - if(new_data_size > first_data_length) - { - glDrawArrays(GL_LINES, 0, (GLsizei)((new_data_size - first_data_length) / SourceVertexSize)); + glDrawArrays(GL_LINES, drawing_zones[c*2] / SourceVertexSize, drawing_zones[c*2 + 1] / SourceVertexSize); } // switch back to screen output diff --git a/Outputs/CRT/Internals/CRTOpenGL.hpp b/Outputs/CRT/Internals/CRTOpenGL.hpp index 6da878397..ced737db9 100644 --- a/Outputs/CRT/Internals/CRTOpenGL.hpp +++ b/Outputs/CRT/Internals/CRTOpenGL.hpp @@ -126,9 +126,9 @@ class OpenGLOutputBuilder { return &_output_buffer_data[_output_buffer_data_pointer]; } - inline void complete_output_run(size_t vertices_written) + inline void complete_output_run(GLsizei vertices_written) { - _run_builders[_run_write_pointer]->amount_of_data += vertices_written * OutputVertexSize; + _run_builders[_run_write_pointer]->amount_of_data += (size_t)(vertices_written * OutputVertexSize); _output_buffer_data_pointer = (_output_buffer_data_pointer + vertices_written * OutputVertexSize) % OutputVertexBufferDataSize; _output_mutex->unlock(); } @@ -162,7 +162,7 @@ class OpenGLOutputBuilder { { _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]->start = (size_t)_output_buffer_data_pointer; _run_builders[_run_write_pointer]->reset(); _output_mutex->unlock(); } @@ -218,11 +218,11 @@ class OpenGLOutputBuilder { GLsizeiptr _input_texture_array_size; uint8_t *_output_buffer_data; - size_t _output_buffer_data_pointer; + GLsizei _output_buffer_data_pointer; uint8_t *_source_buffer_data; - size_t _source_buffer_data_pointer; - size_t _drawn_source_buffer_data_pointer; + GLsizei _source_buffer_data_pointer; + GLsizei _drawn_source_buffer_data_pointer; }; }