1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-13 07:30:21 +00:00

Renamed the 'input buffer builder' to the 'input texture builder' to be explicit about what sort of buffer, and killed the prefix since it's namespaced. Also switched to std::vector.

This commit is contained in:
Thomas Harte 2016-11-16 12:31:32 +08:00
parent 4ee4400801
commit 4d0d5eb919
6 changed files with 118 additions and 99 deletions

View File

@ -352,7 +352,7 @@
4BB73EB71B587A5100552FC2 /* AllSuiteATests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EB61B587A5100552FC2 /* AllSuiteATests.swift */; };
4BB73EC21B587A5100552FC2 /* Clock_SignalUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB73EC11B587A5100552FC2 /* Clock_SignalUITests.swift */; };
4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBB142F1CD2CECE00BDB55C /* IntermediateShader.cpp */; };
4BBF99141C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99081C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp */; };
4BBF99141C8FBA6F0075DAFB /* InputTextureBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99081C8FBA6F0075DAFB /* InputTextureBuilder.cpp */; };
4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */; };
4BBF99181C8FBA6F0075DAFB /* TextureTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF99121C8FBA6F0075DAFB /* TextureTarget.cpp */; };
4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B74D1CD194CC00F86E85 /* Shader.cpp */; };
@ -828,8 +828,8 @@
4BBB142F1CD2CECE00BDB55C /* IntermediateShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntermediateShader.cpp; sourceTree = "<group>"; };
4BBB14301CD2CECE00BDB55C /* IntermediateShader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IntermediateShader.hpp; sourceTree = "<group>"; };
4BBC34241D2208B100FFC9DF /* CSFastLoading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSFastLoading.h; sourceTree = "<group>"; };
4BBF99081C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CRTInputBufferBuilder.cpp; sourceTree = "<group>"; };
4BBF99091C8FBA6F0075DAFB /* CRTInputBufferBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTInputBufferBuilder.hpp; sourceTree = "<group>"; };
4BBF99081C8FBA6F0075DAFB /* InputTextureBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputTextureBuilder.cpp; sourceTree = "<group>"; };
4BBF99091C8FBA6F0075DAFB /* InputTextureBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = InputTextureBuilder.hpp; sourceTree = "<group>"; };
4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CRTOpenGL.cpp; sourceTree = "<group>"; };
4BBF990B1C8FBA6F0075DAFB /* CRTOpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTOpenGL.hpp; sourceTree = "<group>"; };
4BBF990E1C8FBA6F0075DAFB /* Flywheel.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Flywheel.hpp; sourceTree = "<group>"; };
@ -1688,8 +1688,8 @@
isa = PBXGroup;
children = (
4BC3B74C1CD194CC00F86E85 /* Shaders */,
4BBF99081C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp */,
4BBF99091C8FBA6F0075DAFB /* CRTInputBufferBuilder.hpp */,
4BBF99081C8FBA6F0075DAFB /* InputTextureBuilder.cpp */,
4BBF99091C8FBA6F0075DAFB /* InputTextureBuilder.hpp */,
4BBF990A1C8FBA6F0075DAFB /* CRTOpenGL.cpp */,
4BBF990B1C8FBA6F0075DAFB /* CRTOpenGL.hpp */,
4BBF990E1C8FBA6F0075DAFB /* Flywheel.hpp */,
@ -2320,7 +2320,7 @@
4BE77A2E1D84ADFB00BC3827 /* File.cpp in Sources */,
4BAB62B51D327F7E00DF5BA0 /* G64.cpp in Sources */,
4BD468F71D8DF41D0084958B /* 1770.cpp in Sources */,
4BBF99141C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp in Sources */,
4BBF99141C8FBA6F0075DAFB /* InputTextureBuilder.cpp in Sources */,
4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */,
4BCF1FA81DADC5250039D2E7 /* CSOric.mm in Sources */,
4B6C73BD1D387AE500AFCFCA /* DiskController.cpp in Sources */,

View File

@ -1,62 +0,0 @@
//
// CRTInputBufferBuilder.hpp
// Clock Signal
//
// Created by Thomas Harte on 08/03/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#ifndef CRTInputBufferBuilder_hpp
#define CRTInputBufferBuilder_hpp
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include "CRTConstants.hpp"
#include "OpenGL.hpp"
#include <memory>
namespace Outputs {
namespace CRT {
struct CRTInputBufferBuilder {
CRTInputBufferBuilder(size_t bytes_per_pixel);
void allocate_write_area(size_t required_length);
void reduce_previous_allocation_to(size_t actual_length);
uint16_t get_and_finalise_current_line();
uint8_t *get_image_pointer();
uint8_t *get_write_target();
uint16_t get_last_write_x_position();
uint16_t get_last_write_y_position();
size_t get_bytes_per_pixel();
bool is_full();
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;
// the buffer
std::unique_ptr<uint8_t> _image;
};
}
}
#endif /* CRTInputBufferBuilder_hpp */

View File

@ -45,6 +45,8 @@ static GLsizei submitArrayData(GLuint buffer, uint8_t *source, size_t *length_po
{
GLsizei length = (GLsizei)*length_pointer;
// The development machine is a Mac; Apple seemingly having given up on OpenGL (?), GL_MAP_PERSISTENT_BIT is not
// available. Which possibly means I'm doing no better here than a traditional buffer submit, but there it is.
glBindBuffer(GL_ARRAY_BUFFER, buffer);
uint8_t *data = (uint8_t *)glMapBufferRange(GL_ARRAY_BUFFER, 0, length, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
memcpy(data, source, (size_t)length);
@ -78,7 +80,7 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int buffer_depth) :
_last_output_height(0),
_fence(nullptr)
{
_buffer_builder.reset(new CRTInputBufferBuilder(buffer_depth));
_texture_builder.reset(new InputTextureBuilder(buffer_depth));
_output_buffer.data.resize(OutputVertexBufferDataSize);
_source_buffer.data.resize(SourceVertexBufferDataSize);
@ -100,7 +102,7 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(unsigned int buffer_depth) :
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_MIN_FILTER, GL_NEAREST);
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);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormatForDepth(_texture_builder->get_bytes_per_pixel()), InputBufferBuilderWidth, InputBufferBuilderHeight, 0, formatForDepth(_texture_builder->get_bytes_per_pixel()), GL_UNSIGNED_BYTE, nullptr);
// create the output vertex array
glGenVertexArrays(1, &output_vertex_array);
@ -189,15 +191,15 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
GLsizei submitted_source_data = submitArrayData(source_array_buffer, _source_buffer.data.data(), &_source_buffer.pointer);
// upload new source pixels, if any
uint16_t completed_texture_y = _buffer_builder->get_and_finalise_current_line();
uint16_t completed_texture_y = _texture_builder->get_and_finalise_current_line();
if(completed_texture_y)
{
glActiveTexture(source_data_texture_unit);
glTexSubImage2D( GL_TEXTURE_2D, 0,
0, 0,
InputBufferBuilderWidth, completed_texture_y,
formatForDepth(_buffer_builder->get_bytes_per_pixel()), GL_UNSIGNED_BYTE,
_buffer_builder->get_image_pointer());
formatForDepth(_texture_builder->get_bytes_per_pixel()), GL_UNSIGNED_BYTE,
_texture_builder->get_image_pointer());
}
// buffer usage restart from 0 for the next time around

View File

@ -14,7 +14,7 @@
#include "OpenGL.hpp"
#include "TextureTarget.hpp"
#include "Shader.hpp"
#include "CRTInputBufferBuilder.hpp"
#include "InputTextureBuilder.hpp"
#include "Shaders/OutputShader.hpp"
#include "Shaders/IntermediateShader.hpp"
@ -57,7 +57,7 @@ class OpenGLOutputBuilder {
void prepare_source_vertex_array();
// the run and input data buffers
std::unique_ptr<CRTInputBufferBuilder> _buffer_builder;
std::unique_ptr<InputTextureBuilder> _texture_builder;
std::unique_ptr<std::mutex> _output_mutex;
std::unique_ptr<std::mutex> _draw_mutex;
@ -183,28 +183,28 @@ class OpenGLOutputBuilder {
inline uint8_t *allocate_write_area(size_t required_length)
{
_buffer_builder->allocate_write_area(required_length);
return _buffer_builder->get_write_target();
_texture_builder->allocate_write_area(required_length);
return _texture_builder->get_write_target();
}
inline void reduce_previous_allocation_to(size_t actual_length)
{
_buffer_builder->reduce_previous_allocation_to(actual_length);
_texture_builder->reduce_previous_allocation_to(actual_length);
}
inline bool input_buffer_is_full()
{
return _buffer_builder->is_full();
return _texture_builder->is_full();
}
inline uint16_t get_last_write_x_posititon()
{
return _buffer_builder->get_last_write_x_position();
return _texture_builder->get_last_write_x_position();
}
inline uint16_t get_last_write_y_posititon()
{
return _buffer_builder->get_last_write_y_position();
return _texture_builder->get_last_write_y_position();
}
void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty);

View File

@ -1,25 +1,26 @@
//
// CRTInputBufferBuilder.cpp
// InputTextureBuilder.cpp
// Clock Signal
//
// Created by Thomas Harte on 08/03/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#include "CRTInputBufferBuilder.hpp"
#include "InputTextureBuilder.hpp"
#include "CRTOpenGL.hpp"
#include <string.h>
using namespace Outputs::CRT;
CRTInputBufferBuilder::CRTInputBufferBuilder(size_t bytes_per_pixel) :
InputTextureBuilder::InputTextureBuilder(size_t bytes_per_pixel) :
_bytes_per_pixel(bytes_per_pixel),
_next_write_x_position(0),
_next_write_y_position(0),
_image(new uint8_t[bytes_per_pixel * InputBufferBuilderWidth * InputBufferBuilderHeight])
{}
_next_write_y_position(0)
{
_image.resize(bytes_per_pixel * InputBufferBuilderWidth * InputBufferBuilderHeight);
}
void CRTInputBufferBuilder::allocate_write_area(size_t required_length)
void InputTextureBuilder::allocate_write_area(size_t required_length)
{
if(_next_write_y_position != InputBufferBuilderHeight)
{
@ -41,16 +42,16 @@ void CRTInputBufferBuilder::allocate_write_area(size_t required_length)
}
}
bool CRTInputBufferBuilder::is_full()
bool InputTextureBuilder::is_full()
{
return (_next_write_y_position == InputBufferBuilderHeight);
}
void CRTInputBufferBuilder::reduce_previous_allocation_to(size_t actual_length)
void InputTextureBuilder::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.data();
// correct if the writing cursor was reset while a client was writing
if(_next_write_x_position == 0 && _next_write_y_position == 0)
@ -77,34 +78,34 @@ void CRTInputBufferBuilder::reduce_previous_allocation_to(size_t actual_length)
_next_write_x_position -= (_last_allocation_amount - actual_length);
}
uint8_t *CRTInputBufferBuilder::get_image_pointer()
uint8_t *InputTextureBuilder::get_image_pointer()
{
return _image.get();
return _image.data();
}
uint16_t CRTInputBufferBuilder::get_and_finalise_current_line()
uint16_t InputTextureBuilder::get_and_finalise_current_line()
{
uint16_t result = _write_y_position + (_next_write_x_position ? 1 : 0);
_next_write_x_position = _next_write_y_position = 0;
return result;
}
uint8_t *CRTInputBufferBuilder::get_write_target()
uint8_t *InputTextureBuilder::get_write_target()
{
return (_next_write_y_position == InputBufferBuilderHeight) ? nullptr : &_image.get()[_write_target_pointer * _bytes_per_pixel];
return (_next_write_y_position == InputBufferBuilderHeight) ? nullptr : &_image[_write_target_pointer * _bytes_per_pixel];
}
uint16_t CRTInputBufferBuilder::get_last_write_x_position()
uint16_t InputTextureBuilder::get_last_write_x_position()
{
return _write_x_position;
}
uint16_t CRTInputBufferBuilder::get_last_write_y_position()
uint16_t InputTextureBuilder::get_last_write_y_position()
{
return _write_y_position;
}
size_t CRTInputBufferBuilder::get_bytes_per_pixel()
size_t InputTextureBuilder::get_bytes_per_pixel()
{
return _bytes_per_pixel;
}

View File

@ -0,0 +1,78 @@
//
// InputTextureBuilder.hpp
// Clock Signal
//
// Created by Thomas Harte on 08/03/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
#ifndef Outputs_CRT_Internals_InputBufferBuilder_hpp
#define Outputs_CRT_Internals_InputBufferBuilder_hpp
#include <cstdint>
#include <memory>
#include <vector>
#include "OpenGL.hpp"
#include "CRTConstants.hpp"
namespace Outputs {
namespace CRT {
/*!
Owns an OpenGL texture resource and provides mechanisms to fill it from top left to bottom right
with runs of data, ensuring each run is neighboured immediately to the left and right by copies of its
first and last pixels.
*/
class InputTextureBuilder {
public:
/// Constructs an instance of InputTextureBuilder that contains a texture of colour depth @c bytes_per_pixel.
InputTextureBuilder(size_t bytes_per_pixel);
/// 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.
void allocate_write_area(size_t required_length);
/// 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.
void reduce_previous_allocation_to(size_t actual_length);
/// @returns the row that was the final one to receive data; also resets the builder to restart filling of
/// the texture from row 0.
uint16_t get_and_finalise_current_line();
/// @returns a pointer to the image data for this texture.
uint8_t *get_image_pointer();
uint8_t *get_write_target();
uint16_t get_last_write_x_position();
uint16_t get_last_write_y_position();
size_t get_bytes_per_pixel();
bool is_full();
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;
// the buffer
std::vector<uint8_t> _image;
};
}
}
#endif /* CRTInputBufferBuilder_hpp */