1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-15 20:24:07 +00:00
CLK/Outputs/OpenGL/ScanTarget.hpp
Thomas Harte dce52d740d Finally gets some pixels back on screen.
For now, just the raw scans, direct to the framebuffer, with no intermediate processing. But it seems to prove that at least some of the proper data is reaching the GPU.
2018-11-11 23:23:42 -05:00

132 lines
3.4 KiB
C++

//
// ScanTarget.hpp
// Clock Signal
//
// Created by Thomas Harte on 05/11/2018.
// Copyright © 2018 Thomas Harte. All rights reserved.
//
#ifndef ScanTarget_hpp
#define ScanTarget_hpp
#include "../ScanTarget.hpp"
#include "OpenGL.hpp"
#include "Primitives/TextureTarget.hpp"
#include <array>
#include <atomic>
#include <cstdint>
#include <string>
#include <vector>
namespace Outputs {
namespace Display {
namespace OpenGL {
class ScanTarget: public Outputs::Display::ScanTarget {
public:
ScanTarget();
~ScanTarget();
void draw();
private:
// Outputs::Display::ScanTarget overrides.
void set_modals(Modals) override;
Scan *begin_scan() override;
void end_scan() override;
uint8_t *begin_data(size_t required_length, size_t required_alignment) override;
void end_data(size_t actual_length) override;
void submit() override;
void announce(Event event, uint16_t x, uint16_t y) override;
// Extends the definition of a Scan to include two extra fields,
// relevant to the way that this scan target processes video.
struct Scan {
Outputs::Display::ScanTarget::Scan scan;
/// Stores the y coordinate that this scan's data is at, within the write area texture.
uint16_t data_y;
/// Stores the y coordinate of this scan within the line buffer.
uint16_t line;
};
struct PointerSet {
// The sizes below might be less hassle as something more natural like ints,
// but squeezing this struct into 64 bits makes the std::atomics more likely
// to be lock free; they are under LLVM x86-64.
int write_area = 0;
uint16_t scan_buffer = 0;
uint16_t line = 0;
};
/// A pointer to the next thing that should be provided to the caller for data.
PointerSet write_pointers_;
/// A pointer to the final thing currently cleared for submission.
std::atomic<PointerSet> submit_pointers_;
/// A pointer to the first thing not yet submitted for display.
std::atomic<PointerSet> read_pointers_;
// Maintains a buffer of the most recent 3072 scans.
std::array<Scan, 3072> scan_buffer_;
GLuint scan_buffer_name_ = 0;
GLuint scan_vertex_array_ = 0;
// Maintains a list of composite scan buffer coordinates.
struct Line {
struct EndPoint {
uint16_t x, y;
} end_points[2];
uint16_t line;
};
std::array<Line, 2048> line_buffer_;
TextureTarget unprocessed_line_texture_;
GLuint line_vertex_array_ = 0;
Line *active_line_ = nullptr;
// Uses a texture to vend write areas.
std::vector<uint8_t> write_area_texture_;
size_t data_type_size_ = 0;
GLuint write_area_texture_name_ = 0;
bool texture_exists_ = false;
// Ephemeral information for the begin/end functions.
Scan *vended_scan_ = nullptr;
int vended_write_area_pointer_ = 0;
// Track allocation failures.
bool allocation_has_failed_ = false;
// Receives scan target modals.
Modals modals_;
enum class ShaderType {
Scan,
Line
};
/*!
@returns A string containing GLSL code describing the standard set of
@c in and @c uniform variables to bind to the relevant struct
from [...]OpenGL::ScanTarget and a vertex function to provide
the standard varyings.
*/
std::string globals(ShaderType type);
/*!
Calls @c taret.enable_vertex_attribute_with_pointer to attach all
globals for shaders of @c type to @c target.
*/
void enable_vertex_attributes(ShaderType type, Shader &target);
std::unique_ptr<Shader> test_shader_;
};
}
}
}
#endif /* ScanTarget_hpp */