mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Introduces buffer alignment when writing to textures.
To avoid cross-boundary writes and hopefully to eke out a little better performance.
This commit is contained in:
parent
edbc60a3fb
commit
ce78d9d12c
@ -207,7 +207,7 @@ class CRTCBusHandler {
|
||||
// collect some more pixels if output is ongoing
|
||||
if(!is_sync && state.display_enable) {
|
||||
if(!pixel_data_) {
|
||||
pixel_pointer_ = pixel_data_ = crt_->allocate_write_area(320);
|
||||
pixel_pointer_ = pixel_data_ = crt_->allocate_write_area(320, 8);
|
||||
}
|
||||
if(pixel_pointer_) {
|
||||
// the CPC shuffles output lines as:
|
||||
|
@ -106,7 +106,7 @@ void VideoOutput::output_pixels(unsigned int number_of_cycles) {
|
||||
if(!initial_output_target_ || divider != current_output_divider_) {
|
||||
if(current_output_target_) crt_->output_data((unsigned int)((current_output_target_ - initial_output_target_) * current_output_divider_), current_output_divider_);
|
||||
current_output_divider_ = divider;
|
||||
initial_output_target_ = current_output_target_ = crt_->allocate_write_area(640 / current_output_divider_);
|
||||
initial_output_target_ = current_output_target_ = crt_->allocate_write_area(640 / current_output_divider_, 4);
|
||||
}
|
||||
|
||||
#define get_pixel() \
|
||||
|
@ -221,9 +221,9 @@ class CRT {
|
||||
@param required_length The number of samples to allocate.
|
||||
@returns A pointer to the allocated area if room is available; @c nullptr otherwise.
|
||||
*/
|
||||
inline uint8_t *allocate_write_area(size_t required_length) {
|
||||
inline uint8_t *allocate_write_area(size_t required_length, size_t required_alignment = 1) {
|
||||
std::unique_lock<std::mutex> output_lock = openGL_output_builder_.get_output_lock();
|
||||
return openGL_output_builder_.texture_builder.allocate_write_area(required_length);
|
||||
return openGL_output_builder_.texture_builder.allocate_write_area(required_length, required_alignment);
|
||||
}
|
||||
|
||||
/*! Causes appropriate OpenGL or OpenGL ES calls to be issued in order to draw the current CRT state.
|
||||
|
@ -60,7 +60,7 @@ inline uint8_t *TextureBuilder::pointer_to_location(uint16_t x, uint16_t y) {
|
||||
return &image_[((y * InputBufferBuilderWidth) + x) * bytes_per_pixel_];
|
||||
}
|
||||
|
||||
uint8_t *TextureBuilder::allocate_write_area(size_t required_length) {
|
||||
uint8_t *TextureBuilder::allocate_write_area(size_t required_length, size_t required_alignment) {
|
||||
// Keep a flag to indicate whether the buffer was full at allocate_write_area; if it was then
|
||||
// don't return anything now, and decline to act upon follow-up methods. is_full_ may be reset
|
||||
// by asynchronous calls to submit. was_full_ will not be touched by it.
|
||||
@ -69,8 +69,10 @@ uint8_t *TextureBuilder::allocate_write_area(size_t required_length) {
|
||||
|
||||
// If there's not enough space on this line, move to the next. If the next is where the current
|
||||
// submission group started, trigger is/was_full_ and return nothing.
|
||||
if(write_areas_start_x_ + required_length + 2 > InputBufferBuilderWidth) {
|
||||
size_t alignment_offset = (required_alignment - ((write_areas_start_x_ + 1) % required_alignment)) % required_alignment;
|
||||
if(write_areas_start_x_ + required_length + 2 + alignment_offset > InputBufferBuilderWidth) {
|
||||
write_areas_start_x_ = 0;
|
||||
alignment_offset = (required_alignment - 1) % required_alignment;
|
||||
write_areas_start_y_ = (write_areas_start_y_ + 1) % InputBufferBuilderHeight;
|
||||
|
||||
if(write_areas_start_y_ == first_unsubmitted_y_) {
|
||||
@ -80,7 +82,7 @@ uint8_t *TextureBuilder::allocate_write_area(size_t required_length) {
|
||||
}
|
||||
|
||||
// Queue up the latest write area.
|
||||
write_area_.x = write_areas_start_x_ + 1;
|
||||
write_area_.x = write_areas_start_x_ + 1 + static_cast<uint16_t>(alignment_offset);
|
||||
write_area_.y = write_areas_start_y_;
|
||||
write_area_.length = (uint16_t)required_length;
|
||||
|
||||
|
@ -66,10 +66,11 @@ class TextureBuilder {
|
||||
TextureBuilder(size_t bytes_per_pixel, GLenum texture_unit);
|
||||
virtual ~TextureBuilder();
|
||||
|
||||
/// Finds the first available space of at least @c required_length pixels in size. Calls must be paired off
|
||||
/// with calls to @c reduce_previous_allocation_to.
|
||||
/// Finds the first available space of at least @c required_length pixels in size which is suitably aligned
|
||||
/// for writing of @c required_alignment number of pixels at a time.
|
||||
/// Calls must be paired off with calls to @c reduce_previous_allocation_to.
|
||||
/// @returns a pointer to the allocated space if any was available; @c nullptr otherwise.
|
||||
uint8_t *allocate_write_area(size_t required_length);
|
||||
uint8_t *allocate_write_area(size_t required_length, size_t required_alignment = 1);
|
||||
|
||||
/// Announces that the owner is finished with the region created by the most recent @c allocate_write_area
|
||||
/// and indicates that its actual final size was @c actual_length.
|
||||
|
Loading…
Reference in New Issue
Block a user