Files
ORB_SLAM3_Win/Thirdparty/Pangolin/src/display/device/display_headless.cpp
PodmogilnyjIvan ff4acf84be raw
2021-12-03 03:34:31 -08:00

167 lines
4.2 KiB
C++

#include <pangolin/display/display_internal.h>
#include <pangolin/factory/factory_registry.h>
#include <EGL/egl.h>
namespace pangolin {
extern __thread PangolinGl* context;
namespace headless {
class EGLDisplayHL {
public:
EGLDisplayHL(const int width, const int height);
~EGLDisplayHL();
void swap();
void makeCurrent();
void removeCurrent();
private:
EGLSurface egl_surface;
EGLContext egl_context;
EGLDisplay egl_display;
static constexpr EGLint attribs[] = {
EGL_SURFACE_TYPE , EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE , EGL_OPENGL_BIT,
EGL_RED_SIZE , 8,
EGL_GREEN_SIZE , 8,
EGL_BLUE_SIZE , 8,
EGL_ALPHA_SIZE , 8,
EGL_DEPTH_SIZE , 24,
EGL_STENCIL_SIZE , 8,
EGL_NONE
};
};
constexpr EGLint EGLDisplayHL::attribs[];
struct HeadlessWindow : public PangolinGl {
HeadlessWindow(const int width, const int height);
~HeadlessWindow() override;
void ToggleFullscreen() override;
void Move(const int x, const int y) override;
void Resize(const unsigned int w, const unsigned int h) override;
void MakeCurrent() override;
void RemoveCurrent() override;
void SwapBuffers() override;
void ProcessEvents() override;
EGLDisplayHL display;
};
EGLDisplayHL::EGLDisplayHL(const int width, const int height) {
egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if(!egl_display) {
std::cerr << "Failed to open EGL display" << std::endl;
}
EGLint major, minor;
if(eglInitialize(egl_display, &major, &minor)==EGL_FALSE) {
std::cerr << "EGL init failed" << std::endl;
}
if(eglBindAPI(EGL_OPENGL_API)==EGL_FALSE) {
std::cerr << "EGL bind failed" << std::endl;
}
EGLint count;
eglGetConfigs(egl_display, nullptr, 0, &count);
std::vector<EGLConfig> egl_configs(count);
EGLint numConfigs;
eglChooseConfig(egl_display, attribs, egl_configs.data(), count, &numConfigs);
egl_context = eglCreateContext(egl_display, egl_configs[0], EGL_NO_CONTEXT, nullptr);
const EGLint pbufferAttribs[] = {
EGL_WIDTH, width,
EGL_HEIGHT, height,
EGL_NONE,
};
egl_surface = eglCreatePbufferSurface(egl_display, egl_configs[0], pbufferAttribs);
if (egl_surface == EGL_NO_SURFACE) {
std::cerr << "Cannot create EGL surface" << std::endl;
}
}
EGLDisplayHL::~EGLDisplayHL() {
if(egl_context) eglDestroyContext(egl_display, egl_context);
if(egl_surface) eglDestroySurface(egl_display, egl_surface);
if(egl_display) eglTerminate(egl_display);
}
void EGLDisplayHL::swap() {
eglSwapBuffers(egl_display, egl_surface);
}
void EGLDisplayHL::makeCurrent() {
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
}
void EGLDisplayHL::removeCurrent() {
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
HeadlessWindow::HeadlessWindow(const int w, const int h) : display(w, h) {
windowed_size[0] = w;
windowed_size[1] = h;
}
HeadlessWindow::~HeadlessWindow() { }
void HeadlessWindow::MakeCurrent() {
display.makeCurrent();
context = this;
}
void HeadlessWindow::RemoveCurrent() {
display.removeCurrent();
}
void HeadlessWindow::ToggleFullscreen() { }
void HeadlessWindow::Move(const int /*x*/, const int /*y*/) { }
void HeadlessWindow::Resize(const unsigned int /*w*/, const unsigned int /*h*/) { }
void HeadlessWindow::ProcessEvents() { }
void HeadlessWindow::SwapBuffers() {
display.swap();
MakeCurrent();
}
} // namespace headless
PANGOLIN_REGISTER_FACTORY(NoneWindow) {
struct HeadlessWindowFactory : public FactoryInterface<WindowInterface> {
std::unique_ptr<WindowInterface> Open(const Uri& uri) override {
return std::unique_ptr<WindowInterface>(new headless::HeadlessWindow(uri.Get<int>("w", 640), uri.Get<int>("h", 480)));
}
virtual ~HeadlessWindowFactory() { }
};
auto factory = std::make_shared<HeadlessWindowFactory>();
FactoryRegistry<WindowInterface>::I().RegisterFactory(factory, 1, "none");
FactoryRegistry<WindowInterface>::I().RegisterFactory(factory, 1, "nogui");
FactoryRegistry<WindowInterface>::I().RegisterFactory(factory, 1, "headless");
}
} // namespace pangolin