1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Simplified interface by baking in last-minute-only updates.

This commit is contained in:
Thomas Harte 2016-12-03 18:19:12 -05:00
parent ca50606e1d
commit cb3c837e30
3 changed files with 22 additions and 40 deletions

View File

@ -140,7 +140,6 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
source_input_position_y() = tex_y;
source_output_position_x1() = (uint16_t)horizontal_flywheel_->get_current_output_position();
// Don't write output_y now, write it later; we won't necessarily know what it is outside of the locked region
// source_output_position_y() = openGL_output_builder_->get_composite_output_y();
source_phase() = colour_burst_phase_;
source_amplitude() = colour_burst_amplitude_;
source_phase_time() = (uint8_t)colour_burst_time_; // assumption: burst was within the first 1/16 of the line
@ -193,13 +192,7 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
openGL_output_builder_.lock_output();
// Get and write all those previously unwritten output ys
uint16_t output_y = openGL_output_builder_.get_composite_output_y();
size_t size;
uint8_t *buffered_lines = openGL_output_builder_.array_builder.get_unflushed_input(size);
for(size_t position = 0; position < size; position += SourceVertexSize)
{
(*(uint16_t *)&buffered_lines[position + SourceVertexOffsetOfOutputStart + 2]) = output_y;
}
const uint16_t output_y = openGL_output_builder_.get_composite_output_y();
// Construct the output run
uint8_t *next_run = openGL_output_builder_.array_builder.get_output_storage(OutputVertexSize);
@ -210,7 +203,14 @@ void CRT::advance_cycles(unsigned int number_of_cycles, unsigned int source_divi
output_tex_y() = output_y;
output_x2() = (uint16_t)horizontal_flywheel_->get_current_output_position();
}
openGL_output_builder_.array_builder.flush();
openGL_output_builder_.array_builder.flush(
[output_y] (uint8_t *input_buffer, size_t input_size, uint8_t *output_buffer, size_t output_size)
{
for(size_t position = 0; position < input_size; position += SourceVertexSize)
{
(*(uint16_t *)&input_buffer[position + SourceVertexOffsetOfOutputStart + 2]) = output_y;
}
});
openGL_output_builder_.unlock_output();
}

View File

@ -23,9 +23,8 @@ ArrayBuilder::ArrayBuilder(size_t input_size, size_t output_size, std::function<
bool ArrayBuilder::is_full()
{
bool was_full;
buffer_mutex_.lock();
std::lock_guard<std::mutex> guard(buffer_mutex_);
was_full = is_full_;
buffer_mutex_.unlock();
return was_full;
}
@ -34,30 +33,24 @@ uint8_t *ArrayBuilder::get_input_storage(size_t size)
return get_storage(size, input_);
}
uint8_t *ArrayBuilder::get_unflushed_input(size_t &size)
{
return input_.get_unflushed(size);
}
uint8_t *ArrayBuilder::get_output_storage(size_t size)
{
return get_storage(size, output_);
}
uint8_t *ArrayBuilder::get_unflushed_output(size_t &size)
void ArrayBuilder::flush(const std::function<void(uint8_t *input, size_t input_size, uint8_t *output, size_t output_size)> &function)
{
return output_.get_unflushed(size);
}
void ArrayBuilder::flush()
{
buffer_mutex_.lock();
std::lock_guard<std::mutex> guard(buffer_mutex_);
if(!is_full_)
{
size_t input_size, output_size;
uint8_t *input = input_.get_unflushed(input_size);
uint8_t *output = output_.get_unflushed(output_size);
function(input, input_size, output, output_size);
input_.flush();
output_.flush();
}
buffer_mutex_.unlock();
}
void ArrayBuilder::bind_input()
@ -74,7 +67,7 @@ ArrayBuilder::Submission ArrayBuilder::submit()
{
ArrayBuilder::Submission submission;
buffer_mutex_.lock();
std::lock_guard<std::mutex> guard(buffer_mutex_);
submission.input_size = input_.submit(true);
submission.output_size = output_.submit(false);
if(is_full_)
@ -83,7 +76,6 @@ ArrayBuilder::Submission ArrayBuilder::submit()
input_.reset();
output_.reset();
}
buffer_mutex_.unlock();
return submission;
}
@ -110,10 +102,9 @@ ArrayBuilder::Buffer::~Buffer()
uint8_t *ArrayBuilder::get_storage(size_t size, Buffer &buffer)
{
buffer_mutex_.lock();
std::lock_guard<std::mutex> guard(buffer_mutex_);
uint8_t *pointer = buffer.get_storage(size);
if(!pointer) is_full_ = true;
buffer_mutex_.unlock();
return pointer;
}

View File

@ -41,26 +41,17 @@ class ArrayBuilder {
/// @returns a pointer to the allocated area if allocation was possible; @c nullptr otherwise.
uint8_t *get_input_storage(size_t size);
/// Gets the size of and a pointer to all data so far added to the input set but not yet flushed.
/// @returns a pointer from which it is safe to access @c size elements, which contains all regions returned via
/// @c get_input_storage in FIFO order.
uint8_t *get_unflushed_input(size_t &size);
/// Attempts to add @c size bytes to the output set.
/// @returns a pointer to the allocated area if allocation was possible; @c nullptr otherwise.
uint8_t *get_output_storage(size_t size);
/// Gets the size of and a pointer to all data so far added to the output set but not yet flushed.
/// @returns a pointer from which it is safe to access @c size elements, which contains all regions returned via
/// @c get_input_storage in FIFO order.
uint8_t *get_unflushed_output(size_t &size);
/// @returns @c true if either of the input or output storage areas is currently exhausted; @c false otherwise.
bool is_full();
/// If neither input nor output was exhausted since the last flush, atomically commits both input and output
/// up to the currently allocated size for use upon the next @c submit. Otherwise acts as a no-op.
void flush();
/// up to the currently allocated size for use upon the next @c submit, giving the supplied function a
/// chance to perform last-minute processing. Otherwise acts as a no-op.
void flush(const std::function<void(uint8_t *input, size_t input_size, uint8_t *output, size_t output_size)> &);
/// Binds the input array to GL_ARRAY_BUFFER.
void bind_input();