mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-23 20:29:42 +00:00
Factored out wraparound buffer addressing where it's otherwise going to get really repetitive; need to look at using the same approach for the glTexSubImage2D step at least but that probably means properly encapsulating the buffer builder's state.
This commit is contained in:
parent
8232ed765e
commit
d9a9dffe63
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user