summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/headless_view.cpp117
-rw-r--r--common/headless_view.hpp33
-rw-r--r--test/headless.cpp125
-rw-r--r--test/test.gyp2
4 files changed, 162 insertions, 115 deletions
diff --git a/common/headless_view.cpp b/common/headless_view.cpp
new file mode 100644
index 0000000000..7fa5b83946
--- /dev/null
+++ b/common/headless_view.cpp
@@ -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;
+}
+
+}
+
diff --git a/common/headless_view.hpp b/common/headless_view.hpp
new file mode 100644
index 0000000000..b79b0c9746
--- /dev/null
+++ b/common/headless_view.hpp
@@ -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
diff --git a/test/headless.cpp b/test/headless.cpp
index 297b3f28ec..3851702097 100644
--- a/test/headless.cpp
+++ b/test/headless.cpp
@@ -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) {
- llmr::util::timer timer;
+ const int width = 1024;
+ const int height = 768;
- int width = 1024;
- int height = 768;
+ llmr::util::timer timer;
// 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");
}
diff --git a/test/test.gyp b/test/test.gyp
index 4c8ea9499a..98effdfa9e 100644
--- a/test/test.gyp
+++ b/test/test.gyp
@@ -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",
],