Ensure call-once semantics inside InitializeExtensions

This commit is contained in:
John Firebaugh
2015-05-12 16:11:15 -07:00
parent a2344c36c3
commit 7d4f12434e
5 changed files with 44 additions and 62 deletions

View File

@@ -17,10 +17,6 @@
#include <mbgl/platform/gl.hpp>
#include <mbgl/util/std.hpp>
#include <pthread.h>
pthread_once_t loadGLExtensions = PTHREAD_ONCE_INIT;
namespace mbgl {
namespace android {
@@ -308,8 +304,6 @@ void NativeMapView::terminateContext() {
context = EGL_NO_CONTEXT;
}
void loadExtensions();
void NativeMapView::createSurface(ANativeWindow *window_) {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::createSurface");
@@ -349,9 +343,11 @@ void NativeMapView::createSurface(ANativeWindow *window_) {
"SL Version"); // In the emulator this returns NULL with error code 0?
// https://code.google.com/p/android/issues/detail?id=78977
}
log_gl_string(GL_EXTENSIONS, "Extensions");
pthread_once(&loadGLExtensions, loadExtensions);
log_gl_string(GL_EXTENSIONS, "Extensions");
mbgl::gl::InitializeExtensions([] (const char * name) {
return reinterpret_cast<mbgl::gl::glProc>(eglGetProcAddress(name));
});
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
mbgl::Log::Error(mbgl::Event::OpenGL,
@@ -584,12 +580,6 @@ EGLConfig NativeMapView::chooseConfig(const EGLConfig configs[], EGLint numConfi
return configId;
}
void loadExtensions() {
mbgl::gl::InitializeExtensions([] (const char * name) {
return reinterpret_cast<mbgl::gl::glProc>(eglGetProcAddress(name));
});
}
void NativeMapView::pause() {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::pause");

View File

@@ -4,9 +4,6 @@
#include <mbgl/util/gl_helper.hpp>
#include <cassert>
#include <pthread.h>
pthread_once_t loadGLExtensions = PTHREAD_ONCE_INIT;
void glfwError(int error, const char *description) {
mbgl::Log::Error(mbgl::Event::OpenGL, "GLFW error (%i): %s", error, description);
@@ -61,9 +58,7 @@ GLFWView::GLFWView(bool fullscreen_) : fullscreen(fullscreen_) {
glfwSetScrollCallback(window, onScroll);
glfwSetKeyCallback(window, onKey);
pthread_once(&loadGLExtensions, [] {
mbgl::gl::InitializeExtensions(glfwGetProcAddress);
});
mbgl::gl::InitializeExtensions(glfwGetProcAddress);
glfwMakeContextCurrent(nullptr);
}

View File

@@ -13,8 +13,6 @@
#include <cstring>
#include <cassert>
pthread_once_t loadGLExtensions = PTHREAD_ONCE_INIT;
#ifdef MBGL_USE_CGL
#include <CoreFoundation/CoreFoundation.h>
#elif MBGL_USE_GLX
@@ -45,28 +43,26 @@ void HeadlessView::loadExtensions() {
return;
}
pthread_once(&loadGLExtensions, [] {
#ifdef MBGL_USE_CGL
gl::InitializeExtensions([](const char * name) {
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (!framework) {
throw std::runtime_error("Failed to load OpenGL framework.");
}
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);
CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
void* symbol = CFBundleGetFunctionPointerForName(framework, str);
CFRelease(str);
return reinterpret_cast<gl::glProc>(symbol);
});
return reinterpret_cast<gl::glProc>(symbol);
});
#endif
#ifdef MBGL_USE_GLX
gl::InitializeExtensions([](const char * name) {
return glXGetProcAddress(reinterpret_cast<const GLubyte *>(name));
});
#endif
gl::InitializeExtensions([](const char * name) {
return glXGetProcAddress(reinterpret_cast<const GLubyte *>(name));
});
#endif
extensionsLoaded = true;
}

View File

@@ -35,8 +35,6 @@
class MBGLView;
static dispatch_once_t loadGLExtensions;
NSString *const MGLDefaultStyleName = @"mapbox-streets";
NSString *const MGLStyleVersion = @"7";
NSString *const MGLDefaultStyleMarkerSymbolName = @"default_marker";
@@ -233,20 +231,17 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
// load extensions
//
dispatch_once(&loadGLExtensions, ^
{
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.");
}
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);
CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, name, kCFStringEncodingASCII);
void* symbol = CFBundleGetFunctionPointerForName(framework, str);
CFRelease(str);
return reinterpret_cast<mbgl::gl::glProc>(symbol);
});
return reinterpret_cast<mbgl::gl::glProc>(symbol);
});
// setup mbgl map

View File

@@ -1,5 +1,7 @@
#include <mbgl/platform/gl.hpp>
#include <mutex>
namespace mbgl {
namespace gl {
@@ -8,22 +10,26 @@ std::vector<ExtensionFunctionBase*>& ExtensionFunctionBase::functions() {
return functions;
}
static std::once_flag initializeExtensionsOnce;
void InitializeExtensions(glProc (*getProcAddress)(const char *)) {
const char * extensionsPtr = reinterpret_cast<const char *>(
MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS)));
std::call_once(initializeExtensionsOnce, [getProcAddress] {
const char * extensionsPtr = reinterpret_cast<const char *>(
MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS)));
if (!extensionsPtr)
return;
if (!extensionsPtr)
return;
const std::string extensions = extensionsPtr;
for (auto fn : ExtensionFunctionBase::functions()) {
for (auto probe : fn->probes) {
if (extensions.find(probe.first) != std::string::npos) {
fn->ptr = getProcAddress(probe.second);
break;
const std::string extensions = extensionsPtr;
for (auto fn : ExtensionFunctionBase::functions()) {
for (auto probe : fn->probes) {
if (extensions.find(probe.first) != std::string::npos) {
fn->ptr = getProcAddress(probe.second);
break;
}
}
}
}
});
}
void checkError(const char *cmd, const char *file, int line) {