2016-02-13 20:52:23 -05:00
//
// CRTOpenGL.hpp
// Clock Signal
//
// Created by Thomas Harte on 13/02/2016.
// Copyright © 2016 Thomas Harte. All rights reserved.
//
# ifndef CRTOpenGL_h
# define CRTOpenGL_h
2016-03-08 22:40:23 -05:00
# include "../CRTTypes.hpp"
2016-03-19 17:07:05 -04:00
# include "CRTConstants.hpp"
2016-03-08 22:40:23 -05:00
# include "OpenGL.hpp"
# include "TextureTarget.hpp"
# include "Shader.hpp"
2016-11-17 12:26:04 +08:00
# include "ArrayBuilder.hpp"
2016-11-16 22:57:17 +08:00
# include "TextureBuilder.hpp"
2016-03-08 22:40:23 -05:00
2016-04-27 22:29:54 -04:00
# include "Shaders/OutputShader.hpp"
2016-04-28 21:45:44 -04:00
# include "Shaders/IntermediateShader.hpp"
2016-04-27 22:29:54 -04:00
2016-03-08 22:40:23 -05:00
# include <mutex>
2016-11-16 10:34:54 +08:00
# include <vector>
2016-03-08 22:40:23 -05:00
2016-03-08 20:49:07 -05:00
namespace Outputs {
namespace CRT {
2016-03-08 22:40:23 -05:00
class OpenGLOutputBuilder {
private :
// colour information
ColourSpace _colour_space ;
unsigned int _colour_cycle_numerator ;
unsigned int _colour_cycle_denominator ;
OutputDevice _output_device ;
// timing information to allow reasoning about input information
2016-05-02 21:05:58 -04:00
unsigned int _input_frequency ;
2016-03-08 22:40:23 -05:00
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 ;
// The user-supplied visible area
Rect _visible_area ;
// Other things the caller may have provided.
char * _composite_shader ;
char * _rgb_shader ;
// Methods used by the OpenGL code
2016-05-02 21:05:58 -04:00
void prepare_output_shader ( ) ;
void prepare_rgb_input_shaders ( ) ;
void prepare_composite_input_shaders ( ) ;
2016-04-21 20:21:34 -04:00
2016-03-08 22:40:23 -05:00
void prepare_output_vertex_array ( ) ;
2016-04-17 16:17:23 -04:00
void prepare_source_vertex_array ( ) ;
2016-03-08 22:40:23 -05:00
// the run and input data buffers
2016-05-08 16:07:36 -04:00
std : : unique_ptr < std : : mutex > _output_mutex ;
2016-06-02 22:29:09 -04:00
std : : unique_ptr < std : : mutex > _draw_mutex ;
2016-03-08 22:40:23 -05:00
// transient buffers indicating composite data not yet decoded
2016-11-16 11:10:34 +08:00
GLsizei _composite_src_output_y ;
2016-03-08 22:40:23 -05:00
2016-05-02 21:05:58 -04:00
std : : unique_ptr < OpenGL : : OutputShader > output_shader_program ;
2016-05-03 07:46:40 -04:00
std : : unique_ptr < OpenGL : : IntermediateShader > composite_input_shader_program , composite_separation_filter_program , composite_y_filter_shader_program , composite_chrominance_filter_shader_program ;
2016-05-02 21:05:58 -04:00
std : : unique_ptr < OpenGL : : IntermediateShader > rgb_input_shader_program , rgb_filter_shader_program ;
2016-03-08 22:40:23 -05:00
2016-05-03 07:46:40 -04:00
std : : unique_ptr < OpenGL : : TextureTarget > compositeTexture ; // receives raw composite levels
std : : unique_ptr < OpenGL : : TextureTarget > separatedTexture ; // receives unfiltered Y in the R channel plus unfiltered but demodulated chrominance in G and B
std : : unique_ptr < OpenGL : : TextureTarget > filteredYTexture ; // receives filtered Y in the R channel plus unfiltered chrominance in G and B
std : : unique_ptr < OpenGL : : TextureTarget > filteredTexture ; // receives filtered YIQ or YUV
std : : unique_ptr < OpenGL : : TextureTarget > framebuffer ; // the current pixel output
2016-11-17 12:26:04 +08:00
GLuint output_vertex_array ;
GLuint source_vertex_array ;
2016-03-08 22:40:23 -05:00
2016-04-28 22:04:47 -04:00
unsigned int _last_output_width , _last_output_height ;
2016-11-16 23:13:06 +08:00
GLuint shadowMaskTextureName ;
2016-03-08 22:40:23 -05:00
GLuint defaultFramebuffer ;
2016-04-24 18:58:31 -04:00
void set_timing_uniforms ( ) ;
2016-04-24 19:16:23 -04:00
void set_colour_space_uniforms ( ) ;
2016-04-17 18:08:05 -04:00
2016-05-11 22:11:01 -04:00
void establish_OpenGL_state ( ) ;
void reset_all_OpenGL_state ( ) ;
2016-03-08 22:40:23 -05:00
public :
2016-11-17 12:26:04 +08:00
TextureBuilder texture_builder ;
ArrayBuilder array_builder ;
2016-03-08 22:40:23 -05:00
2016-11-17 12:26:04 +08:00
OpenGLOutputBuilder ( size_t bytes_per_pixel ) ;
~ OpenGLOutputBuilder ( ) ;
2016-03-08 22:40:23 -05:00
2016-11-16 10:34:54 +08:00
inline void set_colour_format ( ColourSpace colour_space , unsigned int colour_cycle_numerator , unsigned int colour_cycle_denominator )
2016-05-07 18:37:18 -04:00
{
2016-11-16 10:34:54 +08:00
_output_mutex - > lock ( ) ;
_colour_space = colour_space ;
_colour_cycle_numerator = colour_cycle_numerator ;
_colour_cycle_denominator = colour_cycle_denominator ;
set_colour_space_uniforms ( ) ;
_output_mutex - > unlock ( ) ;
2016-05-07 18:37:18 -04:00
}
2016-11-16 10:34:54 +08:00
inline void set_visible_area ( Rect visible_area )
2016-03-08 22:40:23 -05:00
{
2016-11-16 10:34:54 +08:00
_visible_area = visible_area ;
2016-03-08 22:40:23 -05:00
}
2016-05-09 06:58:26 -04:00
inline void lock_output ( )
{
_output_mutex - > lock ( ) ;
}
inline void unlock_output ( )
{
2016-04-10 15:58:43 -04:00
_output_mutex - > unlock ( ) ;
2016-03-08 22:40:23 -05:00
}
inline OutputDevice get_output_device ( )
{
return _output_device ;
}
inline uint16_t get_composite_output_y ( )
{
2016-11-16 11:34:05 +08:00
return ( uint16_t ) _composite_src_output_y ;
2016-03-08 22:40:23 -05:00
}
2016-05-07 18:37:18 -04:00
inline bool composite_output_buffer_is_full ( )
{
2016-11-16 11:10:34 +08:00
return _composite_src_output_y = = IntermediateBufferHeight ;
2016-05-07 18:37:18 -04:00
}
2016-03-08 22:40:23 -05:00
inline void increment_composite_output_y ( )
{
2016-05-07 18:37:18 -04:00
if ( ! composite_output_buffer_is_full ( ) )
_composite_src_output_y + + ;
2016-03-08 22:40:23 -05:00
}
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_composite_sampling_function ( const char * shader ) ;
void set_rgb_sampling_function ( const char * shader ) ;
void set_output_device ( OutputDevice output_device ) ;
2016-05-02 21:05:58 -04:00
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 ) ;
2016-03-16 22:29:22 -04:00
2016-05-08 19:42:33 -04:00
GLsync _fence ;
2016-03-08 22:40:23 -05:00
} ;
2016-03-08 20:49:07 -05:00
}
}
2016-02-13 23:50:18 -05:00
2016-02-13 20:52:23 -05:00
# endif /* CRTOpenGL_h */