58 lines
2.1 KiB
C++
58 lines
2.1 KiB
C++
#pragma once
|
|
#include <plot/core/status.hpp>
|
|
#include <plot/core/types.hpp>
|
|
#include <plot/gl/handle.hpp>
|
|
|
|
#include <cstdint>
|
|
|
|
namespace plottest {
|
|
|
|
using plot::u32;
|
|
|
|
/// A surfaceless EGL context plus an off-screen RGBA framebuffer, so renderer
|
|
/// output can be asserted pixel by pixel without a window or a display server.
|
|
///
|
|
/// Test-only: `plot_core` neither links nor includes EGL.
|
|
class HeadlessContext {
|
|
public:
|
|
explicit HeadlessContext(u32 w = 256, u32 h = 256) noexcept;
|
|
~HeadlessContext();
|
|
|
|
HeadlessContext(const HeadlessContext&) = delete;
|
|
HeadlessContext& operator=(const HeadlessContext&) = delete;
|
|
|
|
/// Makes an OpenGL 3.3 core context current on this thread, resolves the GL
|
|
/// entry points against it (`plot::gl::load(eglGetProcAddress)`) and
|
|
/// allocates the colour attachment. Idempotent. On failure `st` (when
|
|
/// non-null) carries the reason, every resource already created is released,
|
|
/// and the error is also printed to stderr so a failing CTest run is
|
|
/// diagnosable.
|
|
bool create(plot::Status* st = nullptr) noexcept;
|
|
|
|
/// Releases the framebuffer, the GL context and the EGL display. Safe to call
|
|
/// more than once, and to call after a failed create().
|
|
void destroy() noexcept;
|
|
|
|
/// Binds the off-screen target and reads one RGBA8 pixel, in GL's
|
|
/// origin-at-the-bottom-left convention. False when it cannot be read.
|
|
bool read_pixel(u32 x, u32 y, std::uint8_t rgba[4]) const noexcept;
|
|
|
|
u32 width = 0;
|
|
u32 height = 0;
|
|
/// The headless path create() selected ("egl surfaceless" or "egl pbuffer");
|
|
/// empty before a successful create() and after destroy(). Setting
|
|
/// PLOT_HEADLESS_FORCE_PBUFFER in the environment skips the surfaceless
|
|
/// attempt, so the pbuffer fallback can be exercised on a driver that does
|
|
/// support surfaceless contexts.
|
|
const char* egl_path = "";
|
|
|
|
private:
|
|
plot::gl::Texture color_;
|
|
plot::gl::Framebuffer framebuffer_;
|
|
void* display_ = nullptr; // EGLDisplay
|
|
void* context_ = nullptr; // EGLContext
|
|
void* surface_ = nullptr; // EGLSurface, null on the surfaceless path
|
|
};
|
|
|
|
} // namespace plottest
|