blob: f6168a4b8037978ad40c884ae9a3ce751a001334 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#import "MGLMapView+OpenGL.h"
#import "MGLOpenGLLayer.h"
#include <mbgl/gl/renderable_resource.hpp>
#import <OpenGL/gl.h>
class MGLMapViewOpenGLRenderableResource final : public mbgl::gl::RenderableResource {
public:
MGLMapViewOpenGLRenderableResource(MGLMapViewOpenGLImpl& backend_) : backend(backend_) {
}
void bind() override {
backend.restoreFramebufferBinding();
}
private:
MGLMapViewOpenGLImpl& backend;
public:
// The current framebuffer of the NSOpenGLLayer we are painting to.
GLint fbo = 0;
// The reference counted count of activation calls
NSUInteger activationCount = 0;
};
MGLMapViewOpenGLImpl::MGLMapViewOpenGLImpl(MGLMapView* nativeView_)
: MGLMapViewImpl(nativeView_),
mbgl::gl::RendererBackend(mbgl::gfx::ContextMode::Unique),
mbgl::gfx::Renderable(mapView.framebufferSize,
std::make_unique<MGLMapViewOpenGLRenderableResource>(*this)) {
// Install the OpenGL layer. Interface Builder’s synchronous drawing means
// we can’t display a map, so don’t even bother to have a map layer.
mapView.layer =
mapView.isTargetingInterfaceBuilder ? [CALayer layer] : [MGLOpenGLLayer layer];
}
mbgl::gl::ProcAddress MGLMapViewOpenGLImpl::getExtensionFunctionPointer(const char* name) {
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (!framework) {
throw std::runtime_error("Failed to load OpenGL framework.");
}
return reinterpret_cast<mbgl::gl::ProcAddress>(CFBundleGetFunctionPointerForName(
framework, (__bridge CFStringRef)[NSString stringWithUTF8String:name]));
}
void MGLMapViewOpenGLImpl::activate() {
auto& resource = getResource<MGLMapViewOpenGLRenderableResource>();
if (resource.activationCount++) {
return;
}
MGLOpenGLLayer* layer = (MGLOpenGLLayer*)mapView.layer;
[layer.openGLContext makeCurrentContext];
}
void MGLMapViewOpenGLImpl::deactivate() {
auto& resource = getResource<MGLMapViewOpenGLRenderableResource>();
if (--resource.activationCount) {
return;
}
[NSOpenGLContext clearCurrentContext];
}
void MGLMapViewOpenGLImpl::updateAssumedState() {
auto& resource = getResource<MGLMapViewOpenGLRenderableResource>();
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &resource.fbo);
assumeFramebufferBinding(resource.fbo);
assumeViewport(0, 0, mapView.framebufferSize);
}
void MGLMapViewOpenGLImpl::restoreFramebufferBinding() {
auto& resource = getResource<MGLMapViewOpenGLRenderableResource>();
setFramebufferBinding(resource.fbo);
setViewport(0, 0, mapView.framebufferSize);
}
mbgl::PremultipliedImage MGLMapViewOpenGLImpl::readStillImage() {
return readFramebuffer(mapView.framebufferSize);
}
CGLContextObj MGLMapViewOpenGLImpl::getCGLContextObj() {
MGLOpenGLLayer* layer = (MGLOpenGLLayer*)mapView.layer;
return layer.openGLContext.CGLContextObj;
}
|