move headless to their own files
[skip ci]
This commit is contained in:
117
common/headless_view.cpp
Normal file
117
common/headless_view.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "headless_view.hpp"
|
||||
#include <llmr/util/timer.hpp>
|
||||
#include <llmr/platform/platform.hpp>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
namespace platform {
|
||||
|
||||
void notify_map_change(MapChange change) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HeadlessView::HeadlessView() {
|
||||
// TODO: test if OpenGL 4.1 with GL_ARB_ES2_compatibility is supported
|
||||
// If it is, use kCGLOGLPVersion_3_2_Core and enable that extension.
|
||||
CGLPixelFormatAttribute attributes[] = {
|
||||
kCGLPFAOpenGLProfile,
|
||||
(CGLPixelFormatAttribute) kCGLOGLPVersion_Legacy,
|
||||
kCGLPFAAccelerated,
|
||||
(CGLPixelFormatAttribute) 0
|
||||
};
|
||||
|
||||
CGLPixelFormatObj pixelFormat;
|
||||
GLint num;
|
||||
CGLError error = CGLChoosePixelFormat(attributes, &pixelFormat, &num);
|
||||
if (error) {
|
||||
fprintf(stderr, "Error pixel format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
error = CGLCreateContext(pixelFormat, NULL, &gl_context);
|
||||
CGLDestroyPixelFormat(pixelFormat);
|
||||
if (error) {
|
||||
fprintf(stderr, "Error creating GL context object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
make_active();
|
||||
}
|
||||
|
||||
|
||||
void HeadlessView::resize(int width, int height) {
|
||||
clear_buffers();
|
||||
|
||||
// Create depth/stencil buffer
|
||||
glGenRenderbuffersEXT(1, &fbo_depth_stencil);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo_depth_stencil);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, width, height);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
glGenRenderbuffersEXT(1, &fbo_color);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo_color);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, width, height);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
glGenFramebuffersEXT(1, &fbo);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
|
||||
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, fbo_color);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, fbo_depth_stencil);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
fprintf(stderr, "Couldn't create framebuffer: ");
|
||||
switch (status) {
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: fprintf(stderr, "incomplete attachment\n"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: fprintf(stderr, "incomplete missing attachment\n"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: fprintf(stderr, "incomplete draw buffer\n"); break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED: fprintf(stderr, "unsupported\n"); break;
|
||||
default: fprintf(stderr, "other\n"); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void HeadlessView::clear_buffers() {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
if (fbo) {
|
||||
glDeleteFramebuffersEXT(1, &fbo);
|
||||
fbo = 0;
|
||||
}
|
||||
|
||||
if (fbo_color) {
|
||||
glDeleteTextures(1, &fbo_color);
|
||||
fbo_color = 0;
|
||||
}
|
||||
|
||||
if (fbo_depth_stencil) {
|
||||
glDeleteRenderbuffersEXT(1, &fbo_depth_stencil);
|
||||
fbo_depth_stencil = 0;
|
||||
}
|
||||
}
|
||||
|
||||
HeadlessView::~HeadlessView() {
|
||||
clear_buffers();
|
||||
CGLDestroyContext(gl_context);
|
||||
}
|
||||
|
||||
void HeadlessView::make_active() {
|
||||
CGLError error = CGLSetCurrentContext(gl_context);
|
||||
if (error) {
|
||||
fprintf(stderr, "Switching OpenGL context failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void HeadlessView::swap() {}
|
||||
|
||||
unsigned int HeadlessView::root_fbo() {
|
||||
return fbo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
33
common/headless_view.hpp
Normal file
33
common/headless_view.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef LLMR_COMMON_HEADLESS_CGL
|
||||
#define LLMR_COMMON_HEADLESS_CGL
|
||||
|
||||
#include <llmr/map/view.hpp>
|
||||
#include <llmr/platform/gl.hpp>
|
||||
|
||||
namespace llmr {
|
||||
|
||||
class HeadlessView : public View {
|
||||
public:
|
||||
HeadlessView();
|
||||
~HeadlessView();
|
||||
|
||||
void resize(int width, int height);
|
||||
|
||||
void make_active();
|
||||
void swap();
|
||||
unsigned int root_fbo();
|
||||
|
||||
private:
|
||||
void clear_buffers();
|
||||
|
||||
|
||||
private:
|
||||
CGLContextObj gl_context;
|
||||
GLuint fbo = 0;
|
||||
GLuint fbo_depth_stencil = 0;
|
||||
GLuint fbo_color = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,131 +1,30 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <llmr/llmr.hpp>
|
||||
#include <llmr/map/map.hpp>
|
||||
#include <llmr/util/image.hpp>
|
||||
#include <llmr/util/io.hpp>
|
||||
#include <llmr/util/timer.hpp>
|
||||
|
||||
#include <uv.h>
|
||||
#include "../common/headless_view.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace llmr {
|
||||
namespace platform {
|
||||
|
||||
void notify_map_change(MapChange change) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
class View : public llmr::View {
|
||||
public:
|
||||
View(int width, int height) {
|
||||
// TODO: test if OpenGL 4.1 with GL_ARB_ES2_compatibility is supported
|
||||
// If it is, use kCGLOGLPVersion_3_2_Core and enable that extension.
|
||||
CGLPixelFormatAttribute attributes[] = {
|
||||
kCGLPFAOpenGLProfile,
|
||||
(CGLPixelFormatAttribute) kCGLOGLPVersion_Legacy,
|
||||
kCGLPFAAccelerated,
|
||||
(CGLPixelFormatAttribute) 0
|
||||
};
|
||||
|
||||
CGLPixelFormatObj pixelFormat;
|
||||
GLint num;
|
||||
CGLError error = CGLChoosePixelFormat(attributes, &pixelFormat, &num);
|
||||
if (error) {
|
||||
fprintf(stderr, "Error pixel format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
error = CGLCreateContext(pixelFormat, NULL, &gl_context);
|
||||
CGLDestroyPixelFormat(pixelFormat);
|
||||
if (error) {
|
||||
fprintf(stderr, "Error creating GL context object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
make_active();
|
||||
|
||||
// Create depth/stencil buffer
|
||||
glGenRenderbuffersEXT(1, &fbo_depth_stencil);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo_depth_stencil);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, width, height);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
glGenRenderbuffersEXT(1, &fbo_color);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo_color);
|
||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, width, height);
|
||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
glGenFramebuffersEXT(1, &fbo);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
|
||||
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, fbo_color);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, fbo_depth_stencil);
|
||||
|
||||
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
|
||||
fprintf(stderr, "Couldn't create framebuffer: ");
|
||||
switch (status) {
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: fprintf(stderr, "incomplete attachment\n"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: fprintf(stderr, "incomplete missing attachment\n"); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: fprintf(stderr, "incomplete draw buffer\n"); break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED: fprintf(stderr, "unsupported\n"); break;
|
||||
default: fprintf(stderr, "other\n"); break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
~View() {
|
||||
glDeleteFramebuffersEXT(1, &fbo);
|
||||
glDeleteTextures(1, &fbo_color);
|
||||
glDeleteRenderbuffersEXT(1, &fbo_depth_stencil);
|
||||
|
||||
CGLDestroyContext(gl_context);
|
||||
}
|
||||
|
||||
void make_active() {
|
||||
CGLError error = CGLSetCurrentContext(gl_context);
|
||||
if (error) {
|
||||
fprintf(stderr, "Switching OpenGL context failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void swap() {}
|
||||
|
||||
unsigned int root_fbo() {
|
||||
return fbo;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
CGLContextObj gl_context;
|
||||
GLuint fbo = 0;
|
||||
GLuint fbo_depth_stencil = 0;
|
||||
GLuint fbo_color = 0;
|
||||
};
|
||||
|
||||
TEST(Headless, initialize) {
|
||||
const int width = 1024;
|
||||
const int height = 768;
|
||||
|
||||
llmr::util::timer timer;
|
||||
|
||||
int width = 1024;
|
||||
int height = 768;
|
||||
|
||||
// Setup OpenGL
|
||||
View view(width, height);
|
||||
|
||||
timer.report("gl setup");
|
||||
|
||||
llmr::HeadlessView view;
|
||||
llmr::Map map(view);
|
||||
|
||||
view.resize(width, height);
|
||||
map.resize(width, height);
|
||||
|
||||
timer.report("map setup");
|
||||
|
||||
std::ifstream stylefile("./style.min.js");
|
||||
ASSERT_TRUE(stylefile.good());
|
||||
std::stringstream stylejson;
|
||||
@@ -137,7 +36,7 @@ TEST(Headless, initialize) {
|
||||
map.setAngle(0);
|
||||
map.setDebug(false);
|
||||
|
||||
timer.report("map resize");
|
||||
timer.report("map style");
|
||||
|
||||
// Run the loop. It will terminate when we don't have any further listeners.
|
||||
map.run();
|
||||
@@ -146,8 +45,6 @@ TEST(Headless, initialize) {
|
||||
|
||||
uint32_t *pixels = new uint32_t[width * height];
|
||||
|
||||
view.make_active();
|
||||
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
timer.report("gl readpixels");
|
||||
@@ -160,9 +57,7 @@ TEST(Headless, initialize) {
|
||||
|
||||
timer.report("save file");
|
||||
|
||||
|
||||
delete[] pixels;
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
timer.report("destruct");
|
||||
}
|
||||
|
||||
@@ -138,6 +138,8 @@
|
||||
"sources": [
|
||||
"./main.cpp",
|
||||
"./headless.cpp",
|
||||
"../common/headless_view.hpp",
|
||||
"../common/headless_view.cpp",
|
||||
"../common/curl_request.hpp",
|
||||
"../common/curl_request.cpp",
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user