diff options
Diffstat (limited to 'platform/default')
-rw-r--r-- | platform/default/glfw_view.cpp | 31 | ||||
-rw-r--r-- | platform/default/headless_view.cpp | 70 | ||||
-rw-r--r-- | platform/default/headless_view_glx.cpp | 74 | ||||
-rw-r--r-- | platform/default/offscreen_view.cpp | 47 |
4 files changed, 69 insertions, 153 deletions
diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp index 044181e8c8..47551d786f 100644 --- a/platform/default/glfw_view.cpp +++ b/platform/default/glfw_view.cpp @@ -4,6 +4,7 @@ #include <mbgl/style/transition_options.hpp> #include <mbgl/gl/gl.hpp> #include <mbgl/gl/extension.hpp> +#include <mbgl/gl/context.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/platform/platform.hpp> #include <mbgl/util/string.hpp> @@ -124,13 +125,21 @@ GLFWView::~GLFWView() { glfwTerminate(); } -void GLFWView::initialize(mbgl::Map *map_) { - View::initialize(map_); +void GLFWView::setMap(mbgl::Map *map_) { + map = map_; map->addAnnotationIcon("default_marker", makeSpriteImage(22, 22, 1)); } +void GLFWView::updateViewBinding() { + getContext().bindFramebuffer.setCurrentValue(0); + getContext().viewport.setCurrentValue( + { 0, 0, static_cast<uint16_t>(fbWidth), static_cast<uint16_t>(fbHeight) }); +} + void GLFWView::bind() { - MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0)); + getContext().bindFramebuffer = 0; + getContext().viewport = { 0, 0, static_cast<uint16_t>(fbWidth), + static_cast<uint16_t>(fbHeight) }; } void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) { @@ -365,8 +374,8 @@ void GLFWView::onWindowResize(GLFWwindow *window, int width, int height) { GLFWView *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window)); view->width = width; view->height = height; - - view->map->update(mbgl::Update::Dimensions); + view->map->setSize({{ static_cast<uint16_t>(view->width), + static_cast<uint16_t>(view->height) }}); } void GLFWView::onFramebufferResize(GLFWwindow *window, int width, int height) { @@ -374,7 +383,11 @@ void GLFWView::onFramebufferResize(GLFWwindow *window, int width, int height) { view->fbWidth = width; view->fbHeight = height; - view->map->update(mbgl::Update::Repaint); + // This is only triggered when the framebuffer is resized, but not the window. It can + // happen when you move the window between screens with a different pixel ratio. + // We are forcing a repaint my invalidating the view, which triggers a rerender with the + // new framebuffer dimensions. + view->invalidate(); } void GLFWView::onMouseClick(GLFWwindow *window, int button, int action, int modifiers) { @@ -440,15 +453,15 @@ void GLFWView::run() { const double started = glfwGetTime(); glfwMakeContextCurrent(window); - glViewport(0, 0, fbWidth, fbHeight); - map->render(); + updateViewBinding(); + map->render(*this); glfwSwapBuffers(window); report(1000 * (glfwGetTime() - started)); if (benchmark) { - map->update(mbgl::Update::Repaint); + invalidate(); } dirty = false; diff --git a/platform/default/headless_view.cpp b/platform/default/headless_view.cpp deleted file mode 100644 index f96b0a7f6d..0000000000 --- a/platform/default/headless_view.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include <mbgl/platform/default/headless_view.hpp> - -#include <mbgl/gl/gl.hpp> - -#include <cstring> - -namespace mbgl { - -HeadlessView::HeadlessView(float pixelRatio_, uint16_t width, uint16_t height) - : pixelRatio(pixelRatio_), dimensions({ { width, height } }), needsResize(true) { -} - -HeadlessView::~HeadlessView() { - clearBuffers(); -} - -void HeadlessView::bind() { - if (needsResize) { - clearBuffers(); - resizeFramebuffer(); - needsResize = false; - } else { - bindFramebuffer(); - } -} - -void HeadlessView::resize(const uint16_t width, const uint16_t height) { - if(dimensions[0] == width && - dimensions[1] == height) { - return; - } - dimensions = {{ width, height }}; - needsResize = true; -} - -PremultipliedImage HeadlessView::readStillImage(std::array<uint16_t, 2> size) { - if (!size[0] || !size[1]) { - size[0] = dimensions[0] * pixelRatio; - size[1] = dimensions[1] * pixelRatio; - } - - PremultipliedImage image { size[0], size[1] }; - MBGL_CHECK_ERROR(glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, image.data.get())); - - const auto stride = image.stride(); - auto tmp = std::make_unique<uint8_t[]>(stride); - uint8_t* rgba = image.data.get(); - for (int i = 0, j = size[1] - 1; i < j; i++, j--) { - std::memcpy(tmp.get(), rgba + i * stride, stride); - std::memcpy(rgba + i * stride, rgba + j * stride, stride); - std::memcpy(rgba + j * stride, tmp.get(), stride); - } - - return image; -} - -float HeadlessView::getPixelRatio() const { - return pixelRatio; -} - -std::array<uint16_t, 2> HeadlessView::getSize() const { - return dimensions; -} - -std::array<uint16_t, 2> HeadlessView::getFramebufferSize() const { - return {{ static_cast<uint16_t>(dimensions[0] * pixelRatio), - static_cast<uint16_t>(dimensions[1] * pixelRatio) }}; -} - -} // namespace mbgl diff --git a/platform/default/headless_view_glx.cpp b/platform/default/headless_view_glx.cpp deleted file mode 100644 index 08f0da8751..0000000000 --- a/platform/default/headless_view_glx.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include <mbgl/platform/default/headless_view.hpp> - -#include <mbgl/gl/gl.hpp> - -#include <cassert> - -namespace mbgl { - -void HeadlessView::bindFramebuffer() { - assert(fbo); - MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo)); -} - -void HeadlessView::resizeFramebuffer() { - const unsigned int w = dimensions[0] * pixelRatio; - const unsigned int h = dimensions[1] * pixelRatio; - - // Create depth/stencil buffer - MBGL_CHECK_ERROR(glGenRenderbuffersEXT(1, &fboDepthStencil)); - MBGL_CHECK_ERROR(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthStencil)); - MBGL_CHECK_ERROR(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, w, h)); - MBGL_CHECK_ERROR(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0)); - - MBGL_CHECK_ERROR(glGenRenderbuffersEXT(1, &fboColor)); - MBGL_CHECK_ERROR(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboColor)); - MBGL_CHECK_ERROR(glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, w, h)); - MBGL_CHECK_ERROR(glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0)); - - MBGL_CHECK_ERROR(glGenFramebuffersEXT(1, &fbo)); - MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo)); - - MBGL_CHECK_ERROR(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, fboColor)); - MBGL_CHECK_ERROR(glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, fboDepthStencil)); - - GLenum status = MBGL_CHECK_ERROR(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)); - - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - std::string error("Couldn't create framebuffer: "); - switch (status) { - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: (error += "incomplete attachment"); break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: error += "incomplete missing attachment"; break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: error += "incomplete dimensions"; break; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: error += "incomplete formats"; break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: error += "incomplete draw buffer"; break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: error += "incomplete read buffer"; break; - case GL_FRAMEBUFFER_UNSUPPORTED: error += "unsupported"; break; - default: error += "other"; break; - } - throw std::runtime_error(error); - } - - MBGL_CHECK_ERROR(glViewport(0, 0, w, h)); -} - -void HeadlessView::clearBuffers() { - MBGL_CHECK_ERROR(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)); - - if (fbo) { - MBGL_CHECK_ERROR(glDeleteFramebuffersEXT(1, &fbo)); - fbo = 0; - } - - if (fboColor) { - MBGL_CHECK_ERROR(glDeleteRenderbuffersEXT(1, &fboColor)); - fboColor = 0; - } - - if (fboDepthStencil) { - MBGL_CHECK_ERROR(glDeleteRenderbuffersEXT(1, &fboDepthStencil)); - fboDepthStencil = 0; - } -} - -} // namespace mbgl diff --git a/platform/default/offscreen_view.cpp b/platform/default/offscreen_view.cpp new file mode 100644 index 0000000000..eaf87d0f87 --- /dev/null +++ b/platform/default/offscreen_view.cpp @@ -0,0 +1,47 @@ +#include <mbgl/platform/default/offscreen_view.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/gl.hpp> + +#include <cstring> +#include <cassert> + +namespace mbgl { + +OffscreenView::OffscreenView(gl::Context& context_, std::array<uint16_t, 2> size_) + : context(context_), size(std::move(size_)) { + assert(size[0] > 0 && size[1] > 0); +} + +void OffscreenView::bind() { + if (!framebuffer) { + color = context.createRenderbuffer<gl::RenderbufferType::RGBA>(size); + depthStencil = context.createRenderbuffer<gl::RenderbufferType::DepthStencil>(size); + framebuffer = context.createFramebuffer(*color, *depthStencil); + } else { + context.bindFramebuffer = framebuffer->framebuffer; + } + + context.viewport = { 0, 0, size[0], size[1] }; +} + +PremultipliedImage OffscreenView::readStillImage() { + PremultipliedImage image { size[0], size[1] }; + MBGL_CHECK_ERROR(glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, image.data.get())); + + const auto stride = image.stride(); + auto tmp = std::make_unique<uint8_t[]>(stride); + uint8_t* rgba = image.data.get(); + for (int i = 0, j = size[1] - 1; i < j; i++, j--) { + std::memcpy(tmp.get(), rgba + i * stride, stride); + std::memcpy(rgba + i * stride, rgba + j * stride, stride); + std::memcpy(rgba + j * stride, tmp.get(), stride); + } + + return image; +} + +std::array<uint16_t, 2> OffscreenView::getSize() const { + return size; +} + +} // namespace mbgl |