1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-11 04:28:58 +00:00

Switched to a more rational interface, ensured output_level will work when eventually needed, and that neither it nor output_data attempts a recursive lock.

This commit is contained in:
Thomas Harte 2016-05-09 07:02:12 -04:00
parent a82fa31370
commit cec9ad0dc6
4 changed files with 42 additions and 16 deletions

View File

@ -302,13 +302,24 @@ void CRT::output_blank(unsigned int number_of_cycles)
void CRT::output_level(unsigned int number_of_cycles) void CRT::output_level(unsigned int number_of_cycles)
{ {
_openGL_output_builder->lock_output(); _openGL_output_builder->lock_output();
Scan scan { if(!_openGL_output_builder->input_buffer_is_full())
.type = Scan::Type::Level, {
.number_of_cycles = number_of_cycles, Scan scan {
.tex_x = _openGL_output_builder->get_last_write_x_posititon(), .type = Scan::Type::Level,
.tex_y = _openGL_output_builder->get_last_write_y_posititon() .number_of_cycles = number_of_cycles,
}; .tex_x = _openGL_output_builder->get_last_write_x_posititon(),
output_scan(&scan); .tex_y = _openGL_output_builder->get_last_write_y_posititon()
};
output_scan(&scan);
}
else
{
Scan scan {
.type = Scan::Type::Blank,
.number_of_cycles = number_of_cycles
};
output_scan(&scan);
}
_openGL_output_builder->unlock_output(); _openGL_output_builder->unlock_output();
} }
@ -328,8 +339,9 @@ void CRT::output_colour_burst(unsigned int number_of_cycles, uint8_t phase, uint
void CRT::output_data(unsigned int number_of_cycles, unsigned int source_divider) void CRT::output_data(unsigned int number_of_cycles, unsigned int source_divider)
{ {
_openGL_output_builder->lock_output(); _openGL_output_builder->lock_output();
if(_openGL_output_builder->reduce_previous_allocation_to(number_of_cycles / source_divider)) if(!_openGL_output_builder->input_buffer_is_full())
{ {
_openGL_output_builder->reduce_previous_allocation_to(number_of_cycles / 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,
@ -341,7 +353,11 @@ void CRT::output_data(unsigned int number_of_cycles, unsigned int source_divider
} }
else else
{ {
output_blank(number_of_cycles); Scan scan {
.type = Scan::Type::Blank,
.number_of_cycles = number_of_cycles
};
output_scan(&scan);
} }
_openGL_output_builder->unlock_output(); _openGL_output_builder->unlock_output();
} }

View File

@ -41,9 +41,14 @@ void CRTInputBufferBuilder::allocate_write_area(size_t required_length)
} }
} }
bool CRTInputBufferBuilder::reduce_previous_allocation_to(size_t actual_length) bool CRTInputBufferBuilder::is_full()
{ {
if(_next_write_y_position == InputBufferBuilderHeight) return false; return (_next_write_y_position == InputBufferBuilderHeight);
}
void CRTInputBufferBuilder::reduce_previous_allocation_to(size_t actual_length)
{
if(_next_write_y_position == InputBufferBuilderHeight) return;
uint8_t *const image_pointer = _image.get(); uint8_t *const image_pointer = _image.get();
@ -68,8 +73,6 @@ bool CRTInputBufferBuilder::reduce_previous_allocation_to(size_t actual_length)
// return any allocated length that wasn't actually used to the available pool // return any allocated length that wasn't actually used to the available pool
_next_write_x_position -= (_last_allocation_amount - actual_length); _next_write_x_position -= (_last_allocation_amount - actual_length);
return true;
} }
uint8_t *CRTInputBufferBuilder::get_image_pointer() uint8_t *CRTInputBufferBuilder::get_image_pointer()

View File

@ -23,7 +23,7 @@ struct CRTInputBufferBuilder {
CRTInputBufferBuilder(size_t bytes_per_pixel); CRTInputBufferBuilder(size_t bytes_per_pixel);
void allocate_write_area(size_t required_length); void allocate_write_area(size_t required_length);
bool reduce_previous_allocation_to(size_t actual_length); void reduce_previous_allocation_to(size_t actual_length);
uint16_t get_and_finalise_current_line(); uint16_t get_and_finalise_current_line();
uint8_t *get_image_pointer(); uint8_t *get_image_pointer();
@ -36,6 +36,8 @@ struct CRTInputBufferBuilder {
size_t get_bytes_per_pixel(); size_t get_bytes_per_pixel();
bool is_full();
private: private:
// where pixel data will be put to the next time a write is requested // where pixel data will be put to the next time a write is requested
uint16_t _next_write_x_position, _next_write_y_position; uint16_t _next_write_x_position, _next_write_y_position;

View File

@ -173,9 +173,14 @@ class OpenGLOutputBuilder {
return _buffer_builder->get_write_target(); return _buffer_builder->get_write_target();
} }
inline bool reduce_previous_allocation_to(size_t actual_length) inline void reduce_previous_allocation_to(size_t actual_length)
{ {
return _buffer_builder->reduce_previous_allocation_to(actual_length); _buffer_builder->reduce_previous_allocation_to(actual_length);
}
inline bool input_buffer_is_full()
{
return _buffer_builder->is_full();
} }
inline uint16_t get_last_write_x_posititon() inline uint16_t get_last_write_x_posititon()