summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mbgl/map/backend.hpp11
-rwxr-xr-xplatform/android/src/native_map_view.cpp9
-rwxr-xr-xplatform/android/src/native_map_view.hpp1
-rw-r--r--platform/darwin/src/headless_backend_cgl.cpp4
-rw-r--r--platform/darwin/src/headless_backend_eagl.mm6
-rw-r--r--platform/default/headless_backend_osmesa.cpp2
-rw-r--r--platform/default/mbgl/gl/headless_backend.cpp5
-rw-r--r--platform/default/mbgl/gl/headless_backend.hpp5
-rw-r--r--platform/glfw/glfw_view.cpp7
-rw-r--r--platform/glfw/glfw_view.hpp6
-rw-r--r--platform/ios/src/MGLMapView.mm30
-rw-r--r--platform/linux/src/headless_backend_egl.cpp2
-rw-r--r--platform/linux/src/headless_backend_glx.cpp2
-rw-r--r--platform/macos/src/MGLMapView.mm27
-rw-r--r--platform/qt/app/mapwindow.cpp2
-rw-r--r--platform/qt/include/qmapbox.hpp2
-rw-r--r--platform/qt/src/qmapbox.cpp23
-rw-r--r--platform/qt/src/qmapboxgl.cpp14
-rw-r--r--platform/qt/src/qmapboxgl_p.hpp3
-rw-r--r--platform/qt/test/headless_backend_qt.cpp4
-rw-r--r--platform/qt/test/qmapboxgl.cpp2
-rw-r--r--src/mbgl/gl/extension.cpp25
-rw-r--r--src/mbgl/gl/extension.hpp7
-rw-r--r--src/mbgl/map/backend.cpp11
-rw-r--r--src/mbgl/renderer/painter.cpp2
25 files changed, 102 insertions, 110 deletions
diff --git a/include/mbgl/map/backend.hpp b/include/mbgl/map/backend.hpp
index cd756abe43..876c19261b 100644
--- a/include/mbgl/map/backend.hpp
+++ b/include/mbgl/map/backend.hpp
@@ -3,11 +3,13 @@
#include <mbgl/map/map_observer.hpp>
#include <memory>
+#include <mutex>
namespace mbgl {
namespace gl {
class Context;
+using ProcAddress = void (*)();
} // namespace gl
class BackendScope;
@@ -25,6 +27,11 @@ public:
virtual void invalidate() = 0;
protected:
+ // Called with the name of an OpenGL extension that should be loaded. Backend implementations
+ // must call the API-specific version that obtains the function pointer for this function,
+ // or a null pointer if unsupported/unavailable.
+ virtual gl::ProcAddress initializeExtension(const char*) = 0;
+
// Called when the backend's GL context needs to be made active or inactive. These are called,
// as a matched pair, in four situations:
//
@@ -38,8 +45,12 @@ protected:
virtual void activate() = 0;
virtual void deactivate() = 0;
+protected:
std::unique_ptr<gl::Context> context;
+private:
+ std::once_flag initialized;
+
friend class BackendScope;
};
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index c65c241458..eeb4620c2e 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -15,7 +15,6 @@
#include <jni/jni.hpp>
#include <mbgl/gl/context.hpp>
-#include <mbgl/gl/extension.hpp>
#include <mbgl/map/backend_scope.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/event.hpp>
@@ -108,6 +107,10 @@ void NativeMapView::bind() {
/**
* From mbgl::Backend.
*/
+gl::ProcAddress NativeMapView::initializeExtension(const char* name) {
+ return eglGetProcAddress(name);
+}
+
void NativeMapView::activate() {
if (active++) {
return;
@@ -1394,10 +1397,6 @@ void NativeMapView::_createSurface(ANativeWindow *window_) {
eglGetError());
throw std::runtime_error("eglMakeCurrent() failed");
}
-
- mbgl::gl::InitializeExtensions([] (const char * name) {
- return reinterpret_cast<mbgl::gl::glProc>(eglGetProcAddress(name));
- });
}
}
diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp
index 9a490ddbae..af8c7dd660 100755
--- a/platform/android/src/native_map_view.hpp
+++ b/platform/android/src/native_map_view.hpp
@@ -262,6 +262,7 @@ public:
protected:
// mbgl::Backend //
+ gl::ProcAddress initializeExtension(const char*) override;
void activate() override;
void deactivate() override;
diff --git a/platform/darwin/src/headless_backend_cgl.cpp b/platform/darwin/src/headless_backend_cgl.cpp
index 7069738fb1..6ad98f4326 100644
--- a/platform/darwin/src/headless_backend_cgl.cpp
+++ b/platform/darwin/src/headless_backend_cgl.cpp
@@ -36,7 +36,7 @@ struct CGLImpl : public HeadlessBackend::Impl {
CGLContextObj glContext = nullptr;
};
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+gl::ProcAddress HeadlessBackend::initializeExtension(const char* name) {
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (!framework) {
throw std::runtime_error("Failed to load OpenGL framework.");
@@ -46,7 +46,7 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) {
void* symbol = CFBundleGetFunctionPointerForName(framework, str);
CFRelease(str);
- return reinterpret_cast<gl::glProc>(symbol);
+ return reinterpret_cast<gl::ProcAddress>(symbol);
}
bool HeadlessBackend::hasDisplay() {
diff --git a/platform/darwin/src/headless_backend_eagl.mm b/platform/darwin/src/headless_backend_eagl.mm
index bd4a202ec5..1daaeaf54c 100644
--- a/platform/darwin/src/headless_backend_eagl.mm
+++ b/platform/darwin/src/headless_backend_eagl.mm
@@ -1,7 +1,5 @@
#include <mbgl/gl/headless_backend.hpp>
-#include <mbgl/gl/extension.hpp>
-
#include <OpenGLES/EAGL.h>
#include <stdexcept>
@@ -29,7 +27,7 @@ struct EAGLImpl : public HeadlessBackend::Impl {
EAGLContext* glContext = nullptr;
};
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+gl::ProcAddress HeadlessBackend::initializeExtension(const char* name) {
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
if (!framework) {
throw std::runtime_error("Failed to load OpenGL framework.");
@@ -39,7 +37,7 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) {
void* symbol = CFBundleGetFunctionPointerForName(framework, str);
CFRelease(str);
- return reinterpret_cast<gl::glProc>(symbol);
+ return reinterpret_cast<gl::ProcAddress>(symbol);
}
bool HeadlessBackend::hasDisplay() {
diff --git a/platform/default/headless_backend_osmesa.cpp b/platform/default/headless_backend_osmesa.cpp
index 8ec6079bd0..5042f5ed10 100644
--- a/platform/default/headless_backend_osmesa.cpp
+++ b/platform/default/headless_backend_osmesa.cpp
@@ -25,7 +25,7 @@ struct OSMesaImpl : public HeadlessBackend::Impl {
GLubyte fakeBuffer = 0;
};
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+gl::ProcAddress HeadlessBackend::initializeExtension(const char* name) {
return OSMesaGetProcAddress(name);
}
diff --git a/platform/default/mbgl/gl/headless_backend.cpp b/platform/default/mbgl/gl/headless_backend.cpp
index 6ae19356fb..798c8fe680 100644
--- a/platform/default/mbgl/gl/headless_backend.cpp
+++ b/platform/default/mbgl/gl/headless_backend.cpp
@@ -33,11 +33,6 @@ void HeadlessBackend::activate() {
assert(hasContext());
impl->activateContext();
-
- if (!extensionsLoaded) {
- gl::InitializeExtensions(initializeExtension);
- extensionsLoaded = true;
- }
}
void HeadlessBackend::deactivate() {
diff --git a/platform/default/mbgl/gl/headless_backend.hpp b/platform/default/mbgl/gl/headless_backend.hpp
index 63e3cec9ee..7e1749a253 100644
--- a/platform/default/mbgl/gl/headless_backend.hpp
+++ b/platform/default/mbgl/gl/headless_backend.hpp
@@ -1,7 +1,5 @@
#pragma once
-#include <mbgl/gl/extension.hpp>
-
#include <mbgl/map/backend.hpp>
#include <memory>
@@ -27,7 +25,7 @@ public:
private:
// Implementation specific functions
- static gl::glProc initializeExtension(const char*);
+ gl::ProcAddress initializeExtension(const char*) override;
void activate() override;
void deactivate() override;
@@ -40,7 +38,6 @@ private:
std::unique_ptr<Impl> impl;
std::shared_ptr<HeadlessDisplay> display;
- bool extensionsLoaded = false;
bool active = false;
};
diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp
index d73b147deb..812b0e32af 100644
--- a/platform/glfw/glfw_view.cpp
+++ b/platform/glfw/glfw_view.cpp
@@ -4,7 +4,6 @@
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/gl/gl.hpp>
-#include <mbgl/gl/extension.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/platform.hpp>
@@ -86,8 +85,6 @@ GLFWView::GLFWView(bool fullscreen_, bool benchmark_)
glfwSetScrollCallback(window, onScroll);
glfwSetKeyCallback(window, onKey);
- mbgl::gl::InitializeExtensions(glfwGetProcAddress);
-
glfwGetWindowSize(window, &width, &height);
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
pixelRatio = static_cast<float>(fbWidth) / width;
@@ -499,6 +496,10 @@ mbgl::Size GLFWView::getFramebufferSize() const {
return { static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) };
}
+mbgl::gl::ProcAddress GLFWView::initializeExtension(const char* name) {
+ return glfwGetProcAddress(name);
+}
+
void GLFWView::activate() {
glfwMakeContextCurrent(window);
}
diff --git a/platform/glfw/glfw_view.hpp b/platform/glfw/glfw_view.hpp
index bfabf6cc68..55f795cd34 100644
--- a/platform/glfw/glfw_view.hpp
+++ b/platform/glfw/glfw_view.hpp
@@ -44,9 +44,13 @@ public:
mbgl::Size getFramebufferSize() const;
// mbgl::Backend implementation
+ void invalidate() override;
+
+protected:
+ // mbgl::Backend implementation
+ mbgl::gl::ProcAddress initializeExtension(const char*) override;
void activate() override;
void deactivate() override;
- void invalidate() override;
private:
// Window callbacks
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 6bd3092445..e8bc1b4b2a 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -1,7 +1,6 @@
#import "MGLMapView_Private.h"
#include <mbgl/util/logging.hpp>
-#include <mbgl/gl/extension.hpp>
#include <mbgl/gl/context.hpp>
#import <GLKit/GLKit.h>
@@ -610,21 +609,6 @@ public:
[_glView bindDrawable];
[self insertSubview:_glView atIndex:0];
_glView.contentMode = UIViewContentModeCenter;
-
- // load extensions
- //
- mbgl::gl::InitializeExtensions([](const char * name) {
- static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
- if (!framework) {
- throw std::runtime_error("Failed to load OpenGL framework.");
- }
-
- CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
- void* symbol = CFBundleGetFunctionPointerForName(framework, str);
- CFRelease(str);
-
- return reinterpret_cast<mbgl::gl::glProc>(symbol);
- });
}
- (UIImage *)compassImage
@@ -5436,6 +5420,20 @@ public:
[nativeView didFinishLoadingStyle];
}
+ mbgl::gl::ProcAddress initializeExtension(const char* name) override {
+ static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
+ if (!framework) {
+ throw std::runtime_error("Failed to load OpenGL framework.");
+ }
+
+ CFStringRef str =
+ CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
+ void* symbol = CFBundleGetFunctionPointerForName(framework, str);
+ CFRelease(str);
+
+ return reinterpret_cast<mbgl::gl::ProcAddress>(symbol);
+ }
+
void invalidate() override
{
[nativeView setNeedsGLDisplay];
diff --git a/platform/linux/src/headless_backend_egl.cpp b/platform/linux/src/headless_backend_egl.cpp
index df0ecc8dff..696fa3065c 100644
--- a/platform/linux/src/headless_backend_egl.cpp
+++ b/platform/linux/src/headless_backend_egl.cpp
@@ -60,7 +60,7 @@ struct EGLImpl : public HeadlessBackend::Impl {
EGLSurface glSurface = EGL_NO_SURFACE;
};
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+gl::ProcAddress HeadlessBackend::initializeExtension(const char* name) {
return eglGetProcAddress(name);
}
diff --git a/platform/linux/src/headless_backend_glx.cpp b/platform/linux/src/headless_backend_glx.cpp
index 5791f1892f..36a60ec06b 100644
--- a/platform/linux/src/headless_backend_glx.cpp
+++ b/platform/linux/src/headless_backend_glx.cpp
@@ -44,7 +44,7 @@ struct GLXImpl : public HeadlessBackend::Impl {
GLXFBConfig* fbConfigs = nullptr;
};
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+gl::ProcAddress HeadlessBackend::initializeExtension(const char* name) {
return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
}
diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm
index ef1c0f3bc1..45ac7c5357 100644
--- a/platform/macos/src/MGLMapView.mm
+++ b/platform/macos/src/MGLMapView.mm
@@ -26,7 +26,6 @@
#import <mbgl/map/camera.hpp>
#import <mbgl/storage/reachability.h>
#import <mbgl/util/default_thread_pool.hpp>
-#import <mbgl/gl/extension.hpp>
#import <mbgl/gl/context.hpp>
#import <mbgl/map/backend.hpp>
#import <mbgl/map/backend_scope.hpp>
@@ -768,19 +767,6 @@ public:
- (void)renderSync {
if (!self.dormant) {
- // Enable vertex buffer objects.
- mbgl::gl::InitializeExtensions([](const char *name) {
- static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
- if (!framework) {
- throw std::runtime_error("Failed to load OpenGL framework.");
- }
-
- CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
- void *symbol = CFBundleGetFunctionPointerForName(framework, str);
- CFRelease(str);
-
- return reinterpret_cast<mbgl::gl::glProc>(symbol);
- });
// The OpenGL implementation automatically enables the OpenGL context for us.
mbgl::BackendScope scope { *_mbglView, mbgl::BackendScope::ScopeType::Implicit };
@@ -2846,6 +2832,19 @@ public:
[nativeView sourceDidChange];
}
+ mbgl::gl::ProcAddress initializeExtension(const char* name) override {
+ static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
+ if (!framework) {
+ throw std::runtime_error("Failed to load OpenGL framework.");
+ }
+
+ CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
+ void *symbol = CFBundleGetFunctionPointerForName(framework, str);
+ CFRelease(str);
+
+ return reinterpret_cast<mbgl::gl::ProcAddress>(symbol);
+ }
+
void invalidate() override {
[nativeView setNeedsGLDisplay];
}
diff --git a/platform/qt/app/mapwindow.cpp b/platform/qt/app/mapwindow.cpp
index 926d504904..345c5196ba 100644
--- a/platform/qt/app/mapwindow.cpp
+++ b/platform/qt/app/mapwindow.cpp
@@ -372,8 +372,6 @@ void MapWindow::wheelEvent(QWheelEvent *ev)
void MapWindow::initializeGL()
{
- QMapbox::initializeGLExtensions();
-
m_map.reset(new QMapboxGL(nullptr, m_settings, size(), pixelRatio()));
connect(m_map.data(), SIGNAL(needsRendering()), this, SLOT(update()));
diff --git a/platform/qt/include/qmapbox.hpp b/platform/qt/include/qmapbox.hpp
index f2d96412a9..e69b37108d 100644
--- a/platform/qt/include/qmapbox.hpp
+++ b/platform/qt/include/qmapbox.hpp
@@ -97,8 +97,6 @@ typedef void (*CustomLayerInitializeFunction)(void* context) ;
typedef void (*CustomLayerRenderFunction)(void* context, const CustomLayerRenderParameters&);
typedef void (*CustomLayerDeinitializeFunction)(void* context);
-Q_DECL_EXPORT void initializeGLExtensions();
-
} // namespace QMapbox
Q_DECLARE_METATYPE(QMapbox::Coordinate);
diff --git a/platform/qt/src/qmapbox.cpp b/platform/qt/src/qmapbox.cpp
index 126ece1efa..410e114690 100644
--- a/platform/qt/src/qmapbox.cpp
+++ b/platform/qt/src/qmapbox.cpp
@@ -1,6 +1,5 @@
#include "qmapbox.hpp"
-#include <mbgl/gl/extension.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/default_styles.hpp>
#include <mbgl/util/geometry.hpp>
@@ -255,26 +254,4 @@ Q_DECL_EXPORT QList<QPair<QString, QString> >& defaultStyles()
return styles;
}
-/*!
- \fn void QMapbox::initializeGLExtensions()
-
- Initializes the OpenGL extensions such as Vertex Array Objects (VAOs),
- required by Mapbox GL Native engine.
-
- Should be called only once, after an OpenGL context is available.
- Consecutive calls are ignored.
-*/
-Q_DECL_EXPORT void initializeGLExtensions()
-{
- mbgl::gl::InitializeExtensions([](const char* name) {
-#if QT_VERSION >= 0x050000
- QOpenGLContext* thisContext = QOpenGLContext::currentContext();
- return thisContext->getProcAddress(name);
-#else
- const QGLContext* thisContext = QGLContext::currentContext();
- return reinterpret_cast<mbgl::gl::glProc>(thisContext->getProcAddress(name));
-#endif
- });
-}
-
} // namespace QMapbox
diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp
index 384bdc8ebf..5776502a5b 100644
--- a/platform/qt/src/qmapboxgl.cpp
+++ b/platform/qt/src/qmapboxgl.cpp
@@ -1678,6 +1678,20 @@ void QMapboxGLPrivate::onSourceChanged(mbgl::style::Source&)
emit mapChanged(QMapboxGL::MapChangeSourceDidChange);
}
+/*!
+ Initializes an OpenGL extension function such as Vertex Array Objects (VAOs),
+ required by Mapbox GL Native engine.
+*/
+mbgl::gl::ProcAddress QMapboxGLPrivate::initializeExtension(const char* name) {
+#if QT_VERSION >= 0x050000
+ QOpenGLContext* thisContext = QOpenGLContext::currentContext();
+ return thisContext->getProcAddress(name);
+#else
+ const QGLContext* thisContext = QGLContext::currentContext();
+ return reinterpret_cast<mbgl::gl::ProcAddress>(thisContext->getProcAddress(name));
+#endif
+}
+
void QMapboxGLPrivate::connectionEstablished()
{
mbgl::NetworkStatus::Reachable();
diff --git a/platform/qt/src/qmapboxgl_p.hpp b/platform/qt/src/qmapboxgl_p.hpp
index 4112542431..464b66bd73 100644
--- a/platform/qt/src/qmapboxgl_p.hpp
+++ b/platform/qt/src/qmapboxgl_p.hpp
@@ -58,6 +58,9 @@ public:
bool dirty { false };
+private:
+ mbgl::gl::ProcAddress initializeExtension(const char*) override;
+
public slots:
void connectionEstablished();
diff --git a/platform/qt/test/headless_backend_qt.cpp b/platform/qt/test/headless_backend_qt.cpp
index 401ce55a7f..5f95b2f96a 100644
--- a/platform/qt/test/headless_backend_qt.cpp
+++ b/platform/qt/test/headless_backend_qt.cpp
@@ -24,13 +24,13 @@ struct QtImpl : public HeadlessBackend::Impl {
QGLWidget widget;
};
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+gl::ProcAddress HeadlessBackend::initializeExtension(const char* name) {
#if QT_VERSION >= 0x050000
QOpenGLContext* thisContext = QOpenGLContext::currentContext();
return thisContext->getProcAddress(name);
#else
const QGLContext* thisContext = QGLContext::currentContext();
- return reinterpret_cast<mbgl::gl::glProc>(thisContext->getProcAddress(name));
+ return reinterpret_cast<gl::ProcAddress>(thisContext->getProcAddress(name));
#endif
}
diff --git a/platform/qt/test/qmapboxgl.cpp b/platform/qt/test/qmapboxgl.cpp
index 650c635b99..453604076e 100644
--- a/platform/qt/test/qmapboxgl.cpp
+++ b/platform/qt/test/qmapboxgl.cpp
@@ -20,8 +20,6 @@ public:
this, SLOT(onMapChanged(QMapboxGL::MapChange)));
connect(&map, SIGNAL(needsRendering()),
this, SLOT(onNeedsRendering()));
- QMapbox::initializeGLExtensions();
-
map.resize(fbo.size(), fbo.size());
map.setFramebufferObject(fbo.handle());
map.setCoordinateZoom(QMapbox::Coordinate(60.170448, 24.942046), 14);
diff --git a/src/mbgl/gl/extension.cpp b/src/mbgl/gl/extension.cpp
index e6b4d9156e..41a5ea175e 100644
--- a/src/mbgl/gl/extension.cpp
+++ b/src/mbgl/gl/extension.cpp
@@ -1,7 +1,6 @@
#include <mbgl/gl/extension.hpp>
#include <mbgl/gl/gl.hpp>
-#include <mutex>
#include <string>
#include <vector>
#include <cstring>
@@ -11,7 +10,7 @@ namespace gl {
namespace detail {
using Probes = std::vector<ExtensionFunctionBase::Probe>;
-using ExtensionFunctions = std::vector<std::pair<glProc*, Probes>>;
+using ExtensionFunctions = std::vector<std::pair<ProcAddress*, Probes>>;
ExtensionFunctions& extensionFunctions() {
static ExtensionFunctions functions;
return functions;
@@ -23,22 +22,18 @@ ExtensionFunctionBase::ExtensionFunctionBase(std::initializer_list<Probe> probes
} // namespace detail
-static std::once_flag initializeExtensionsOnce;
-
-void InitializeExtensions(glProc (*getProcAddress)(const char*)) {
- std::call_once(initializeExtensionsOnce, [getProcAddress] {
- if (const char* extensions =
- reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS)))) {
- for (auto fn : detail::extensionFunctions()) {
- for (auto probe : fn.second) {
- if (strstr(extensions, probe.first) != nullptr) {
- *fn.first = getProcAddress(probe.second);
- break;
- }
+void initializeExtensions(const std::function<ProcAddress(const char*)>& getProcAddress) {
+ if (const char* extensions =
+ reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS)))) {
+ for (auto fn : detail::extensionFunctions()) {
+ for (auto probe : fn.second) {
+ if (strstr(extensions, probe.first) != nullptr) {
+ *fn.first = getProcAddress(probe.second);
+ break;
}
}
}
- });
+ }
}
} // namespace gl
diff --git a/src/mbgl/gl/extension.hpp b/src/mbgl/gl/extension.hpp
index ea5a1ae5f5..7d1d9a4d7d 100644
--- a/src/mbgl/gl/extension.hpp
+++ b/src/mbgl/gl/extension.hpp
@@ -2,12 +2,13 @@
#include <initializer_list>
#include <utility>
+#include <functional>
namespace mbgl {
namespace gl {
-using glProc = void (*)();
-void InitializeExtensions(glProc (*getProcAddress)(const char*));
+using ProcAddress = void (*)();
+void initializeExtensions(const std::function<ProcAddress(const char*)>&);
namespace detail {
@@ -15,7 +16,7 @@ class ExtensionFunctionBase {
public:
using Probe = std::pair<const char*, const char*>;
ExtensionFunctionBase(std::initializer_list<Probe>);
- glProc ptr;
+ ProcAddress ptr;
};
} // namespace detail
diff --git a/src/mbgl/map/backend.cpp b/src/mbgl/map/backend.cpp
index a1a2f8f3a8..29f7522e4f 100644
--- a/src/mbgl/map/backend.cpp
+++ b/src/mbgl/map/backend.cpp
@@ -1,16 +1,23 @@
#include <mbgl/map/backend.hpp>
#include <mbgl/map/backend_scope.hpp>
#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/extension.hpp>
+#include <mbgl/gl/debugging.hpp>
#include <cassert>
namespace mbgl {
-Backend::Backend() : context(std::make_unique<gl::Context>()) {
-}
+Backend::Backend() = default;
gl::Context& Backend::getContext() {
assert(BackendScope::exists());
+ std::call_once(initialized, [this] {
+ context = std::make_unique<gl::Context>();
+ gl::debugging::enable();
+ gl::initializeExtensions(
+ std::bind(&Backend::initializeExtension, this, std::placeholders::_1));
+ });
return *context;
}
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 754959438b..73a084c8c6 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -94,8 +94,6 @@ Painter::Painter(gl::Context& context_,
tileBorderSegments.emplace_back(0, 0, 4, 5);
rasterSegments.emplace_back(0, 0, 4, 6);
- gl::debugging::enable();
-
programs = std::make_unique<Programs>(context,
ProgramParameters{ pixelRatio, false, programCacheDir });
#ifndef NDEBUG