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:
parent
4ee4400801
commit
4d0d5eb919
@ -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 */,
|
||||
|
@ -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 */
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
78
Outputs/CRT/Internals/InputTextureBuilder.hpp
Normal file
78
Outputs/CRT/Internals/InputTextureBuilder.hpp
Normal 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 */
|
Loading…
x
Reference in New Issue
Block a user