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

Switched to passing around std::strings rather than char *s, because they should be easier to capture.

This commit is contained in:
Thomas Harte 2017-02-20 10:35:33 -05:00
parent d979a822ac
commit 6cb95b4fc5
7 changed files with 41 additions and 43 deletions

View File

@ -243,7 +243,7 @@ class CRT {
that evaluates to the composite signal level as a function of a source buffer, sampling location, colour that evaluates to the composite signal level as a function of a source buffer, sampling location, colour
carrier phase and amplitude. carrier phase and amplitude.
*/ */
inline void set_composite_sampling_function(const char *shader) inline void set_composite_sampling_function(const std::string &shader)
{ {
openGL_output_builder_.set_composite_sampling_function(shader); openGL_output_builder_.set_composite_sampling_function(shader);
} }
@ -261,7 +261,7 @@ class CRT {
* `vec2 coordinate` representing the source buffer location to sample from in the range [0, 1); and * `vec2 coordinate` representing the source buffer location to sample from in the range [0, 1); and
* `vec2 icoordinate` representing the source buffer location to sample from as a pixel count, for easier multiple-pixels-per-byte unpacking. * `vec2 icoordinate` representing the source buffer location to sample from as a pixel count, for easier multiple-pixels-per-byte unpacking.
*/ */
inline void set_rgb_sampling_function(const char *shader) inline void set_rgb_sampling_function(const std::string &shader)
{ {
openGL_output_builder_.set_rgb_sampling_function(shader); openGL_output_builder_.set_rgb_sampling_function(shader);
} }

View File

@ -8,7 +8,6 @@
#include "CRT.hpp" #include "CRT.hpp"
#include <cstdlib> #include <cstdlib>
#include <cstring>
#include <cmath> #include <cmath>
#include "CRTOpenGL.hpp" #include "CRTOpenGL.hpp"
@ -17,7 +16,8 @@
using namespace Outputs::CRT; using namespace Outputs::CRT;
namespace { namespace
{
static const GLenum source_data_texture_unit = GL_TEXTURE0; static const GLenum source_data_texture_unit = GL_TEXTURE0;
static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE1; static const GLenum pixel_accumulation_texture_unit = GL_TEXTURE1;
@ -31,8 +31,6 @@ namespace {
OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) : OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
visible_area_(Rect(0, 0, 1, 1)), visible_area_(Rect(0, 0, 1, 1)),
composite_src_output_y_(0), composite_src_output_y_(0),
composite_shader_(nullptr),
rgb_shader_(nullptr),
last_output_width_(0), last_output_width_(0),
last_output_height_(0), last_output_height_(0),
fence_(nullptr), fence_(nullptr),
@ -78,9 +76,6 @@ OpenGLOutputBuilder::OpenGLOutputBuilder(size_t bytes_per_pixel) :
OpenGLOutputBuilder::~OpenGLOutputBuilder() OpenGLOutputBuilder::~OpenGLOutputBuilder()
{ {
glDeleteVertexArrays(1, &output_vertex_array_); glDeleteVertexArrays(1, &output_vertex_array_);
free(composite_shader_);
free(rgb_shader_);
} }
bool OpenGLOutputBuilder::get_is_television_output() bool OpenGLOutputBuilder::get_is_television_output()
@ -275,17 +270,17 @@ void OpenGLOutputBuilder::set_openGL_context_will_change(bool should_delete_reso
output_mutex_.unlock(); output_mutex_.unlock();
} }
void OpenGLOutputBuilder::set_composite_sampling_function(const char *shader) void OpenGLOutputBuilder::set_composite_sampling_function(const std::string &shader)
{ {
std::lock_guard<std::mutex> lock_guard(output_mutex_); std::lock_guard<std::mutex> lock_guard(output_mutex_);
composite_shader_ = strdup(shader); composite_shader_ = shader;
reset_all_OpenGL_state(); reset_all_OpenGL_state();
} }
void OpenGLOutputBuilder::set_rgb_sampling_function(const char *shader) void OpenGLOutputBuilder::set_rgb_sampling_function(const std::string &shader)
{ {
std::lock_guard<std::mutex> lock_guard(output_mutex_); std::lock_guard<std::mutex> lock_guard(output_mutex_);
rgb_shader_ = strdup(shader); rgb_shader_ = shader;
reset_all_OpenGL_state(); reset_all_OpenGL_state();
} }
@ -321,7 +316,7 @@ void OpenGLOutputBuilder::prepare_composite_input_shaders()
void OpenGLOutputBuilder::prepare_rgb_input_shaders() void OpenGLOutputBuilder::prepare_rgb_input_shaders()
{ {
if(rgb_shader_) if(rgb_shader_.size())
{ {
rgb_input_shader_program_ = OpenGL::IntermediateShader::make_rgb_source_shader(rgb_shader_); rgb_input_shader_program_ = OpenGL::IntermediateShader::make_rgb_source_shader(rgb_shader_);
rgb_input_shader_program_->set_source_texture_unit(source_data_texture_unit); rgb_input_shader_program_->set_source_texture_unit(source_data_texture_unit);

View File

@ -47,8 +47,8 @@ class OpenGLOutputBuilder {
Rect visible_area_; Rect visible_area_;
// Other things the caller may have provided. // Other things the caller may have provided.
char *composite_shader_; std::string composite_shader_;
char *rgb_shader_; std::string rgb_shader_;
// Methods used by the OpenGL code // Methods used by the OpenGL code
void prepare_output_shader(); void prepare_output_shader();
@ -148,8 +148,8 @@ class OpenGLOutputBuilder {
void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty); void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty);
void set_openGL_context_will_change(bool should_delete_resources); void set_openGL_context_will_change(bool should_delete_resources);
void set_composite_sampling_function(const char *shader); void set_composite_sampling_function(const std::string &shader);
void set_rgb_sampling_function(const char *shader); void set_rgb_sampling_function(const std::string &shader);
void set_output_device(OutputDevice output_device); void set_output_device(OutputDevice output_device);
void set_timing(unsigned int input_frequency, unsigned int cycles_per_line, unsigned int height_of_display, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider); void set_timing(unsigned int input_frequency, unsigned int cycles_per_line, unsigned int height_of_display, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider);
}; };

View File

@ -26,7 +26,7 @@ namespace {
}; };
} }
std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *fragment_shader, bool use_usampler, bool input_is_inputPosition) std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const std::string &fragment_shader, bool use_usampler, bool input_is_inputPosition)
{ {
const char *sampler_type = use_usampler ? "usampler2D" : "sampler2D"; const char *sampler_type = use_usampler ? "usampler2D" : "sampler2D";
const char *input_variable = input_is_inputPosition ? "inputPosition" : "outputPosition"; const char *input_variable = input_is_inputPosition ? "inputPosition" : "outputPosition";
@ -111,12 +111,13 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_shader(const char *
return shader; return shader;
} }
std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_shader(const char *composite_shader, const char *rgb_shader) std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_shader(const std::string &composite_shader, const std::string &rgb_shader)
{ {
char *composite_sample = (char *)composite_shader; char *derived_composite_sample = nullptr;
if(!composite_sample) const char *composite_sample = composite_shader.c_str();
if(!composite_shader.size())
{ {
asprintf(&composite_sample, asprintf(&derived_composite_sample,
"%s\n" "%s\n"
"uniform mat3 rgbToLumaChroma;" "uniform mat3 rgbToLumaChroma;"
"float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)" "float composite_sample(usampler2D texID, vec2 coordinate, vec2 iCoordinate, float phase, float amplitude)"
@ -126,7 +127,8 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_s
"vec2 quadrature = vec2(cos(phase), -sin(phase)) * amplitude;" "vec2 quadrature = vec2(cos(phase), -sin(phase)) * amplitude;"
"return dot(lumaChromaColour, vec3(1.0 - amplitude, quadrature));" "return dot(lumaChromaColour, vec3(1.0 - amplitude, quadrature));"
"}", "}",
rgb_shader); rgb_shader.c_str());
composite_sample = derived_composite_sample;
} }
char *fragment_shader; char *fragment_shader;
@ -148,7 +150,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_s
"fragColour = vec4(composite_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x, phaseAndAmplitudeVarying.y));" "fragColour = vec4(composite_sample(texID, inputPositionsVarying[5], iInputPositionVarying, phaseAndAmplitudeVarying.x, phaseAndAmplitudeVarying.y));"
"}" "}"
, composite_sample); , composite_sample);
if(!composite_shader) free(composite_sample); free(derived_composite_sample);
std::unique_ptr<IntermediateShader> shader = make_shader(fragment_shader, true, true); std::unique_ptr<IntermediateShader> shader = make_shader(fragment_shader, true, true);
free(fragment_shader); free(fragment_shader);
@ -156,7 +158,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_source_conversion_s
return shader; return shader;
} }
std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_source_shader(const char *rgb_shader) std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_source_shader(const std::string &rgb_shader)
{ {
char *fragment_shader; char *fragment_shader;
asprintf(&fragment_shader, asprintf(&fragment_shader,
@ -176,7 +178,7 @@ std::unique_ptr<IntermediateShader> IntermediateShader::make_rgb_source_shader(c
"{" "{"
"fragColour = rgb_sample(texID, inputPositionsVarying[5], iInputPositionVarying);" "fragColour = rgb_sample(texID, inputPositionsVarying[5], iInputPositionVarying);"
"}" "}"
, rgb_shader); , rgb_shader.c_str());
std::unique_ptr<IntermediateShader> shader = make_shader(fragment_shader, true, true); std::unique_ptr<IntermediateShader> shader = make_shader(fragment_shader, true, true);
free(fragment_shader); free(fragment_shader);

View File

@ -25,13 +25,13 @@ public:
converting them to single-channel composite values using @c composite_shader if supplied converting them to single-channel composite values using @c composite_shader if supplied
or @c rgb_shader and a reference composite conversion if @c composite_shader is @c nullptr. or @c rgb_shader and a reference composite conversion if @c composite_shader is @c nullptr.
*/ */
static std::unique_ptr<IntermediateShader> make_source_conversion_shader(const char *composite_shader, const char *rgb_shader); static std::unique_ptr<IntermediateShader> make_source_conversion_shader(const std::string &composite_shader, const std::string &rgb_shader);
/*! /*!
Constructs and returns an intermediate shader that will take runs from the inputPositions, Constructs and returns an intermediate shader that will take runs from the inputPositions,
converting them to RGB values using @c rgb_shader. converting them to RGB values using @c rgb_shader.
*/ */
static std::unique_ptr<IntermediateShader> make_rgb_source_shader(const char *rgb_shader); static std::unique_ptr<IntermediateShader> make_rgb_source_shader(const std::string &rgb_shader);
/*! /*!
Constructs and returns an intermediate shader that will read composite samples from the R channel, Constructs and returns an intermediate shader that will read composite samples from the R channel,
@ -95,7 +95,7 @@ public:
void set_is_double_height(bool is_double_height, float input_offset = 0.0f, float output_offset = 0.0f); void set_is_double_height(bool is_double_height, float input_offset = 0.0f, float output_offset = 0.0f);
private: private:
static std::unique_ptr<IntermediateShader> make_shader(const char *fragment_shader, bool use_usampler, bool input_is_inputPosition); static std::unique_ptr<IntermediateShader> make_shader(const std::string &fragment_shader, bool use_usampler, bool input_is_inputPosition);
}; };
} }

View File

@ -8,22 +8,23 @@
#include "Shader.hpp" #include "Shader.hpp"
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
using namespace OpenGL; using namespace OpenGL;
namespace { namespace
{
Shader *bound_shader = nullptr; Shader *bound_shader = nullptr;
} }
GLuint Shader::compile_shader(const char *source, GLenum type) GLuint Shader::compile_shader(const std::string &source, GLenum type)
{ {
GLuint shader = glCreateShader(type); GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, NULL); const char *c_str = source.c_str();
glShaderSource(shader, 1, &c_str, NULL);
glCompileShader(shader); glCompileShader(shader);
#if defined(DEBUG) #ifdef DEBUG
GLint isCompiled = 0; GLint isCompiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE) if(isCompiled == GL_FALSE)
@ -31,10 +32,10 @@ GLuint Shader::compile_shader(const char *source, GLenum type)
GLint logLength; GLint logLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
if(logLength > 0) { if(logLength > 0) {
GLchar *log = (GLchar *)malloc((size_t)logLength); GLchar *log = new GLchar[logLength];
glGetShaderInfoLog(shader, logLength, &logLength, log); glGetShaderInfoLog(shader, logLength, &logLength, log);
printf("Compile log:\n%s\n", log); printf("Compile log:\n%s\n", log);
free(log); delete[] log;
} }
throw (type == GL_VERTEX_SHADER) ? VertexShaderCompilationError : FragmentShaderCompilationError; throw (type == GL_VERTEX_SHADER) ? VertexShaderCompilationError : FragmentShaderCompilationError;
@ -44,7 +45,7 @@ GLuint Shader::compile_shader(const char *source, GLenum type)
return shader; return shader;
} }
Shader::Shader(const char *vertex_shader, const char *fragment_shader, const AttributeBinding *attribute_bindings) Shader::Shader(const std::string &vertex_shader, const std::string &fragment_shader, const AttributeBinding *attribute_bindings)
{ {
shader_program_ = glCreateProgram(); shader_program_ = glCreateProgram();
GLuint vertex = compile_shader(vertex_shader, GL_VERTEX_SHADER); GLuint vertex = compile_shader(vertex_shader, GL_VERTEX_SHADER);
@ -64,7 +65,7 @@ Shader::Shader(const char *vertex_shader, const char *fragment_shader, const Att
glLinkProgram(shader_program_); glLinkProgram(shader_program_);
#if defined(DEBUG) #ifdef DEBUG
GLint didLink = 0; GLint didLink = 0;
glGetProgramiv(shader_program_, GL_LINK_STATUS, &didLink); glGetProgramiv(shader_program_, GL_LINK_STATUS, &didLink);
if(didLink == GL_FALSE) if(didLink == GL_FALSE)
@ -72,10 +73,10 @@ Shader::Shader(const char *vertex_shader, const char *fragment_shader, const Att
GLint logLength; GLint logLength;
glGetProgramiv(shader_program_, GL_INFO_LOG_LENGTH, &logLength); glGetProgramiv(shader_program_, GL_INFO_LOG_LENGTH, &logLength);
if(logLength > 0) { if(logLength > 0) {
GLchar *log = (GLchar *)malloc((size_t)logLength); GLchar *log = new GLchar[logLength];
glGetProgramInfoLog(shader_program_, logLength, &logLength, log); glGetProgramInfoLog(shader_program_, logLength, &logLength, log);
printf("Link log:\n%s\n", log); printf("Link log:\n%s\n", log);
free(log); delete[] log;
} }
throw ProgramLinkageError; throw ProgramLinkageError;
} }

View File

@ -41,7 +41,7 @@ public:
@param fragment_shader The fragment shader source code. @param fragment_shader The fragment shader source code.
@param attribute_bindings Either @c nullptr or an array terminated by an entry with a @c nullptr-name of attribute bindings. @param attribute_bindings Either @c nullptr or an array terminated by an entry with a @c nullptr-name of attribute bindings.
*/ */
Shader(const char *vertex_shader, const char *fragment_shader, const AttributeBinding *attribute_bindings); Shader(const std::string &vertex_shader, const std::string &fragment_shader, const AttributeBinding *attribute_bindings);
~Shader(); ~Shader();
/*! /*!
@ -106,7 +106,7 @@ public:
void set_uniform_matrix(const std::string &name, GLint size, GLsizei count, bool transpose, const GLfloat *values); void set_uniform_matrix(const std::string &name, GLint size, GLsizei count, bool transpose, const GLfloat *values);
private: private:
GLuint compile_shader(const char *source, GLenum type); GLuint compile_shader(const std::string &source, GLenum type);
GLuint shader_program_; GLuint shader_program_;
void flush_functions(); void flush_functions();