mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-23 03:32:32 +00:00
Made attempts (i) to flush buffers before unmapping them; and (ii) to bring texture uploads within the new orthodoxy.
This commit is contained in:
parent
fc1a67c157
commit
2541711061
@ -293,8 +293,8 @@ void CRT::output_level(unsigned int number_of_cycles)
|
|||||||
Scan scan {
|
Scan scan {
|
||||||
.type = Scan::Type::Level,
|
.type = Scan::Type::Level,
|
||||||
.number_of_cycles = number_of_cycles,
|
.number_of_cycles = number_of_cycles,
|
||||||
.tex_x = _openGL_output_builder->get_last_write_x_posiiton(),
|
.tex_x = _openGL_output_builder->get_last_write_x_posititon(),
|
||||||
.tex_y = _openGL_output_builder->get_last_write_y_posiiton()
|
.tex_y = _openGL_output_builder->get_last_write_y_posititon()
|
||||||
};
|
};
|
||||||
output_scan(&scan);
|
output_scan(&scan);
|
||||||
}
|
}
|
||||||
@ -316,8 +316,8 @@ void CRT::output_data(unsigned int number_of_cycles, unsigned int source_divider
|
|||||||
Scan scan {
|
Scan scan {
|
||||||
.type = Scan::Type::Data,
|
.type = Scan::Type::Data,
|
||||||
.number_of_cycles = number_of_cycles,
|
.number_of_cycles = number_of_cycles,
|
||||||
.tex_x = _openGL_output_builder->get_last_write_x_posiiton(),
|
.tex_x = _openGL_output_builder->get_last_write_x_posititon(),
|
||||||
.tex_y = _openGL_output_builder->get_last_write_y_posiiton(),
|
.tex_y = _openGL_output_builder->get_last_write_y_posititon(),
|
||||||
.source_divider = source_divider
|
.source_divider = source_divider
|
||||||
};
|
};
|
||||||
output_scan(&scan);
|
output_scan(&scan);
|
||||||
|
@ -240,18 +240,6 @@ class CRT {
|
|||||||
_openGL_output_builder->set_rgb_sampling_function(shader);
|
_openGL_output_builder->set_rgb_sampling_function(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Optionally sets a function that will map from an input cycle count to a colour carrier phase.
|
|
||||||
|
|
||||||
If this function is not supplied then the colour phase is determined from
|
|
||||||
the input clock rate and the the colour cycle clock rate. Machines whose per-line clock rate
|
|
||||||
is not intended exactly to match the normal line time may prefer to supply a custom function.
|
|
||||||
|
|
||||||
@param A GLSL fragent including a function with the signature
|
|
||||||
`float phase_for_clock_cycle(int cycle)` that returns the colour phase at the beginning of
|
|
||||||
the supplied cycle.
|
|
||||||
*/
|
|
||||||
// void set_phase_function(const char *shader);
|
|
||||||
|
|
||||||
inline void set_output_device(OutputDevice output_device)
|
inline void set_output_device(OutputDevice output_device)
|
||||||
{
|
{
|
||||||
_openGL_output_builder->set_output_device(output_device);
|
_openGL_output_builder->set_output_device(output_device);
|
||||||
|
@ -16,13 +16,11 @@ CRTInputBufferBuilder::CRTInputBufferBuilder(size_t bytes_per_pixel) :
|
|||||||
bytes_per_pixel(bytes_per_pixel),
|
bytes_per_pixel(bytes_per_pixel),
|
||||||
_next_write_x_position(0),
|
_next_write_x_position(0),
|
||||||
_next_write_y_position(0),
|
_next_write_y_position(0),
|
||||||
last_uploaded_line(0),
|
last_uploaded_line(0)
|
||||||
_wraparound_sync(glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0))
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CRTInputBufferBuilder::~CRTInputBufferBuilder()
|
CRTInputBufferBuilder::~CRTInputBufferBuilder()
|
||||||
{
|
{
|
||||||
glDeleteSync(_wraparound_sync);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRTInputBufferBuilder::allocate_write_area(size_t required_length)
|
void CRTInputBufferBuilder::allocate_write_area(size_t required_length)
|
||||||
@ -31,12 +29,13 @@ void CRTInputBufferBuilder::allocate_write_area(size_t required_length)
|
|||||||
|
|
||||||
if(_next_write_x_position + required_length + 2 > InputBufferBuilderWidth)
|
if(_next_write_x_position + required_length + 2 > InputBufferBuilderWidth)
|
||||||
{
|
{
|
||||||
move_to_new_line();
|
_next_write_x_position = 0;
|
||||||
|
_next_write_y_position++;
|
||||||
}
|
}
|
||||||
|
|
||||||
_write_x_position = _next_write_x_position + 1;
|
_write_x_position = _next_write_x_position + 1;
|
||||||
_write_y_position = _next_write_y_position;
|
_write_y_position = _next_write_y_position;
|
||||||
_write_target_pointer = (_write_y_position * InputBufferBuilderWidth) + _write_x_position;
|
_write_target_pointer = ((_write_y_position % InputBufferBuilderHeight) * InputBufferBuilderWidth) + _write_x_position;
|
||||||
_next_write_x_position += required_length + 2;
|
_next_write_x_position += required_length + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,30 +25,52 @@ struct CRTInputBufferBuilder {
|
|||||||
void allocate_write_area(size_t required_length);
|
void allocate_write_area(size_t required_length);
|
||||||
void reduce_previous_allocation_to(size_t actual_length, uint8_t *buffer);
|
void reduce_previous_allocation_to(size_t actual_length, uint8_t *buffer);
|
||||||
|
|
||||||
// a pointer to the section of content buffer currently being
|
inline uint16_t get_and_finalise_current_line()
|
||||||
// returned and to where the next section will begin
|
|
||||||
uint16_t _next_write_x_position, _next_write_y_position;
|
|
||||||
uint16_t _write_x_position, _write_y_position;
|
|
||||||
size_t _write_target_pointer;
|
|
||||||
size_t _last_allocation_amount;
|
|
||||||
size_t bytes_per_pixel;
|
|
||||||
|
|
||||||
// Storage for the amount of buffer uploaded so far; initialised correctly by the buffer
|
|
||||||
// builder but otherwise entrusted to the CRT to update.
|
|
||||||
unsigned int last_uploaded_line;
|
|
||||||
|
|
||||||
GLsync _wraparound_sync;
|
|
||||||
|
|
||||||
inline void move_to_new_line()
|
|
||||||
{
|
{
|
||||||
|
uint16_t result = _write_y_position;
|
||||||
_next_write_x_position = 0;
|
_next_write_x_position = 0;
|
||||||
_next_write_y_position = (_next_write_y_position+1)%InputBufferBuilderHeight;
|
_next_write_y_position++;
|
||||||
|
_next_write_y_position %= InputBufferBuilderHeight;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t *get_write_target(uint8_t *buffer)
|
inline uint8_t *get_write_target(uint8_t *buffer)
|
||||||
{
|
{
|
||||||
return &buffer[_write_target_pointer * bytes_per_pixel];
|
return &buffer[_write_target_pointer * bytes_per_pixel];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline uint16_t get_last_write_x_position()
|
||||||
|
{
|
||||||
|
return _write_x_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint16_t get_last_write_y_position()
|
||||||
|
{
|
||||||
|
return _write_y_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t get_bytes_per_pixel()
|
||||||
|
{
|
||||||
|
return bytes_per_pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// where pixel data will be put to the next time a write is requested
|
||||||
|
uint16_t _next_write_x_position, _next_write_y_position;
|
||||||
|
|
||||||
|
// the most recent position returned for pixel data writing
|
||||||
|
uint16_t _write_x_position, _write_y_position;
|
||||||
|
|
||||||
|
// details of the most recent allocation
|
||||||
|
size_t _write_target_pointer;
|
||||||
|
size_t _last_allocation_amount;
|
||||||
|
|
||||||
|
// the buffer size
|
||||||
|
size_t bytes_per_pixel;
|
||||||
|
|
||||||
|
// Storage for the amount of buffer uploaded so far; initialised correctly by the buffer
|
||||||
|
// builder but otherwise entrusted to the CRT to update.
|
||||||
|
unsigned int last_uploaded_line;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -118,12 +118,12 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int buffer_depth) :
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_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->get_bytes_per_pixel()), InputBufferBuilderWidth, InputBufferBuilderHeight, 0, formatForDepth(_buffer_builder->get_bytes_per_pixel()), GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
|
||||||
// create a pixel unpack buffer
|
// create a pixel unpack buffer
|
||||||
glGenBuffers(1, &_input_texture_array);
|
glGenBuffers(1, &_input_texture_array);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _input_texture_array);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _input_texture_array);
|
||||||
_input_texture_array_size = (GLsizeiptr)(InputBufferBuilderWidth * InputBufferBuilderHeight * _buffer_builder->bytes_per_pixel);
|
_input_texture_array_size = (GLsizeiptr)(InputBufferBuilderWidth * InputBufferBuilderHeight * _buffer_builder->get_bytes_per_pixel());
|
||||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, _input_texture_array_size, NULL, GL_STREAM_DRAW);
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, _input_texture_array_size, NULL, GL_STREAM_DRAW);
|
||||||
|
|
||||||
// map the buffer for clients
|
// map the buffer for clients
|
||||||
@ -205,11 +205,48 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
defaultFramebuffer = 0;
|
defaultFramebuffer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// determine how many lines are newly reclaimed; they'll need to be cleared
|
||||||
|
GLsizei clearing_zones[4], source_drawing_zones[4];
|
||||||
|
GLsizei output_drawing_zones[4], texture_upload_zones[4];
|
||||||
|
int number_of_clearing_zones = getCircularRanges(_cleared_composite_output_y+1, _composite_src_output_y+1, IntermediateBufferHeight, 1, clearing_zones);
|
||||||
|
int number_of_source_drawing_zones = getCircularRanges(_drawn_source_buffer_data_pointer, _source_buffer_data_pointer, SourceVertexBufferDataSize, 2*SourceVertexSize, source_drawing_zones);
|
||||||
|
int number_of_output_drawing_zones = getCircularRanges(_drawn_output_buffer_data_pointer, _output_buffer_data_pointer, OutputVertexBufferDataSize, 6*OutputVertexSize, output_drawing_zones);
|
||||||
|
|
||||||
|
uint16_t completed_texture_y = _buffer_builder->get_and_finalise_current_line();
|
||||||
|
int number_of_texture_upload_zones = getCircularRanges(_uploaded_texture_y, completed_texture_y, InputBufferBuilderHeight, 1, texture_upload_zones);
|
||||||
|
|
||||||
|
_composite_src_output_y %= IntermediateBufferHeight;
|
||||||
|
_source_buffer_data_pointer %= SourceVertexBufferDataSize;
|
||||||
|
_output_buffer_data_pointer %= OutputVertexBufferDataSize;
|
||||||
|
|
||||||
|
_cleared_composite_output_y = _composite_src_output_y;
|
||||||
|
_drawn_source_buffer_data_pointer = _source_buffer_data_pointer;
|
||||||
|
_drawn_output_buffer_data_pointer = _output_buffer_data_pointer;
|
||||||
|
_uploaded_texture_y = completed_texture_y % InputBufferBuilderHeight;
|
||||||
|
|
||||||
// release the mapping, giving up on trying to draw if data has been lost
|
// release the mapping, giving up on trying to draw if data has been lost
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer);
|
||||||
|
for(int c = 0; c < number_of_output_drawing_zones; c++)
|
||||||
|
{
|
||||||
|
glFlushMappedBufferRange(GL_ARRAY_BUFFER, output_drawing_zones[c*2], output_drawing_zones[c*2 + 1]);
|
||||||
|
}
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
// bind and flush the source array buffer
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, source_array_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, source_array_buffer);
|
||||||
|
for(int c = 0; c < number_of_source_drawing_zones; c++)
|
||||||
|
{
|
||||||
|
glFlushMappedBufferRange(GL_ARRAY_BUFFER, source_drawing_zones[c*2], source_drawing_zones[c*2 + 1]);
|
||||||
|
}
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
|
if(number_of_texture_upload_zones)
|
||||||
|
{
|
||||||
|
for(int c = 0; c < number_of_texture_upload_zones; c++)
|
||||||
|
{
|
||||||
|
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, (GLsizeiptr)texture_upload_zones[c*2] * InputBufferBuilderWidth * (GLsizeiptr)_buffer_builder->get_bytes_per_pixel(), (GLsizeiptr)texture_upload_zones[c*2 + 1] * InputBufferBuilderWidth * (GLsizeiptr)_buffer_builder->get_bytes_per_pixel());
|
||||||
|
}
|
||||||
|
}
|
||||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
|
|
||||||
// make sure there's a target to draw to
|
// make sure there's a target to draw to
|
||||||
@ -233,26 +270,14 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _input_texture_array);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _input_texture_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload more source pixel data if any; we'll always resubmit the last line submitted last
|
// upload new source pixels
|
||||||
// time as it may have had extra data appended to it
|
for(int c = 0; c < number_of_texture_upload_zones; c++)
|
||||||
if(_buffer_builder->_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, texture_upload_zones[c*2],
|
||||||
InputBufferBuilderWidth, (GLint)(InputBufferBuilderHeight - _buffer_builder->last_uploaded_line),
|
InputBufferBuilderWidth, texture_upload_zones[c*2 + 1],
|
||||||
formatForDepth(_buffer_builder->bytes_per_pixel), GL_UNSIGNED_BYTE,
|
formatForDepth(_buffer_builder->get_bytes_per_pixel()), GL_UNSIGNED_BYTE,
|
||||||
(void *)(_buffer_builder->last_uploaded_line * InputBufferBuilderWidth * _buffer_builder->bytes_per_pixel));
|
(void *)((size_t)texture_upload_zones[c*2] * InputBufferBuilderWidth * _buffer_builder->get_bytes_per_pixel()));
|
||||||
_buffer_builder->last_uploaded_line = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_buffer_builder->_write_y_position > _buffer_builder->last_uploaded_line)
|
|
||||||
{
|
|
||||||
glTexSubImage2D( GL_TEXTURE_2D, 0,
|
|
||||||
0, (GLint)_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,
|
|
||||||
(void *)(_buffer_builder->last_uploaded_line * InputBufferBuilderWidth * _buffer_builder->bytes_per_pixel));
|
|
||||||
_buffer_builder->last_uploaded_line = _buffer_builder->_next_write_y_position;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RenderStage {
|
struct RenderStage {
|
||||||
@ -280,29 +305,12 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
RenderStage *active_pipeline = (_output_device == Television || !rgb_input_shader_program) ? composite_render_stages : rgb_render_stages;
|
RenderStage *active_pipeline = (_output_device == Television || !rgb_input_shader_program) ? composite_render_stages : rgb_render_stages;
|
||||||
|
|
||||||
// for television, update intermediate buffers and then draw; for a monitor, just draw
|
// for television, update intermediate buffers and then draw; for a monitor, just draw
|
||||||
if(_drawn_source_buffer_data_pointer != _source_buffer_data_pointer)
|
if(number_of_source_drawing_zones)
|
||||||
{
|
{
|
||||||
// determine how many lines are newly reclaimed; they'll need to be cleared
|
|
||||||
GLsizei clearing_zones[4], drawing_zones[4];
|
|
||||||
int number_of_clearing_zones = getCircularRanges(_cleared_composite_output_y+1, _composite_src_output_y+1, IntermediateBufferHeight, 1, clearing_zones);
|
|
||||||
int number_of_drawing_zones = getCircularRanges(_drawn_source_buffer_data_pointer, _source_buffer_data_pointer, SourceVertexBufferDataSize, 2*SourceVertexSize, drawing_zones);
|
|
||||||
|
|
||||||
_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
|
// all drawing will be from the source vertex array and without blending
|
||||||
glBindVertexArray(source_vertex_array);
|
glBindVertexArray(source_vertex_array);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
// flush the source data
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, source_array_buffer);
|
|
||||||
for(int c = 0; c < number_of_drawing_zones; c++)
|
|
||||||
{
|
|
||||||
glFlushMappedBufferRange(GL_ARRAY_BUFFER, drawing_zones[c*2] / SourceVertexSize, drawing_zones[c*2 + 1] / SourceVertexSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
while(active_pipeline->target)
|
while(active_pipeline->target)
|
||||||
{
|
{
|
||||||
// switch to the initial texture
|
// switch to the initial texture
|
||||||
@ -323,9 +331,9 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
}
|
}
|
||||||
|
|
||||||
// draw as desired
|
// draw as desired
|
||||||
for(int c = 0; c < number_of_drawing_zones; c++)
|
for(int c = 0; c < number_of_source_drawing_zones; c++)
|
||||||
{
|
{
|
||||||
glDrawArrays(GL_LINES, drawing_zones[c*2] / SourceVertexSize, drawing_zones[c*2 + 1] / SourceVertexSize);
|
glDrawArrays(GL_LINES, source_drawing_zones[c*2] / SourceVertexSize, source_drawing_zones[c*2 + 1] / SourceVertexSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
active_pipeline++;
|
active_pipeline++;
|
||||||
@ -335,22 +343,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
// transfer to framebuffer
|
// transfer to framebuffer
|
||||||
framebuffer->bind_framebuffer();
|
framebuffer->bind_framebuffer();
|
||||||
|
|
||||||
// draw all pending lines
|
if(number_of_output_drawing_zones)
|
||||||
GLsizei drawing_zones[4];
|
|
||||||
int number_of_drawing_zones = getCircularRanges(_drawn_output_buffer_data_pointer, _output_buffer_data_pointer, OutputVertexBufferDataSize, 6*OutputVertexSize, drawing_zones);
|
|
||||||
|
|
||||||
// flush the buffer data
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, output_array_buffer);
|
|
||||||
for(int c = 0; c < number_of_drawing_zones; c++)
|
|
||||||
{
|
|
||||||
glFlushMappedBufferRange(GL_ARRAY_BUFFER, drawing_zones[c*2] / OutputVertexSize, drawing_zones[c*2 + 1] / OutputVertexSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
_output_buffer_data_pointer %= SourceVertexBufferDataSize;
|
|
||||||
_output_buffer_data_pointer -= (_output_buffer_data_pointer%(6*OutputVertexSize));
|
|
||||||
_drawn_output_buffer_data_pointer = _output_buffer_data_pointer;
|
|
||||||
|
|
||||||
if(number_of_drawing_zones > 0)
|
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
@ -367,9 +360,9 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
output_shader_program->bind();
|
output_shader_program->bind();
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
for(int c = 0; c < number_of_drawing_zones; c++)
|
for(int c = 0; c < number_of_output_drawing_zones; c++)
|
||||||
{
|
{
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, drawing_zones[c*2] / OutputVertexSize, drawing_zones[c*2 + 1] / OutputVertexSize);
|
glDrawArrays(GL_TRIANGLE_STRIP, output_drawing_zones[c*2] / OutputVertexSize, output_drawing_zones[c*2 + 1] / OutputVertexSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +380,7 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, source_array_buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, source_array_buffer);
|
||||||
_source_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, SourceVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
|
_source_buffer_data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, SourceVertexBufferDataSize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
|
||||||
|
|
||||||
_input_texture_data = (uint8_t *)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _input_texture_array_size, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_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();
|
||||||
}
|
}
|
||||||
|
@ -157,14 +157,14 @@ class OpenGLOutputBuilder {
|
|||||||
_buffer_builder->reduce_previous_allocation_to(actual_length, _input_texture_data);
|
_buffer_builder->reduce_previous_allocation_to(actual_length, _input_texture_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t get_last_write_x_posiiton()
|
inline uint16_t get_last_write_x_posititon()
|
||||||
{
|
{
|
||||||
return _buffer_builder->_write_x_position;
|
return _buffer_builder->get_last_write_x_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t get_last_write_y_posiiton()
|
inline uint16_t get_last_write_y_posititon()
|
||||||
{
|
{
|
||||||
return _buffer_builder->_write_y_position;
|
return _buffer_builder->get_last_write_y_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty);
|
void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty);
|
||||||
@ -186,6 +186,8 @@ class OpenGLOutputBuilder {
|
|||||||
uint8_t *_output_buffer_data;
|
uint8_t *_output_buffer_data;
|
||||||
GLsizei _output_buffer_data_pointer;
|
GLsizei _output_buffer_data_pointer;
|
||||||
GLsizei _drawn_output_buffer_data_pointer;
|
GLsizei _drawn_output_buffer_data_pointer;
|
||||||
|
|
||||||
|
uint16_t _uploaded_texture_y;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ TextureTarget::TextureTarget(GLsizei width, GLsizei height, GLenum texture_unit)
|
|||||||
|
|
||||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
throw ErrorFramebufferIncomplete;
|
throw ErrorFramebufferIncomplete;
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureTarget::~TextureTarget()
|
TextureTarget::~TextureTarget()
|
||||||
|
Loading…
Reference in New Issue
Block a user