blob: 7362adcb9eb4dbfa349201b90bd2e032bace2776 (
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
90
91
92
93
|
#include <mbgl/gl/headless_backend.hpp>
#include <mbgl/gl/renderable_resource.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/gfx/backend_scope.hpp>
#include <cassert>
#include <stdexcept>
#include <type_traits>
namespace mbgl {
namespace gl {
class HeadlessRenderableResource final : public gl::RenderableResource {
public:
HeadlessRenderableResource(gl::Context& context_, Size size_)
: context(context_),
color(context.createRenderbuffer<gfx::RenderbufferPixelType::RGBA>(size_)),
depthStencil(context.createRenderbuffer<gfx::RenderbufferPixelType::DepthStencil>(size_)),
framebuffer(context.createFramebuffer(color, depthStencil)) {
}
void bind() override {
context.bindFramebuffer = framebuffer.framebuffer;
context.scissorTest = false;
context.viewport = { 0, 0, framebuffer.size };
}
gl::Context& context;
gfx::Renderbuffer<gfx::RenderbufferPixelType::RGBA> color;
gfx::Renderbuffer<gfx::RenderbufferPixelType::DepthStencil> depthStencil;
gl::Framebuffer framebuffer;
};
HeadlessBackend::HeadlessBackend(const Size size_, const gfx::ContextMode contextMode_)
: mbgl::gl::RendererBackend(contextMode_), mbgl::gfx::Renderable(size_, nullptr) {
}
HeadlessBackend::~HeadlessBackend() {
gfx::BackendScope guard { *this };
resource.reset();
// Explicitly reset the context so that it is destructed and cleaned up before we destruct
// the impl object.
context.reset();
}
gl::ProcAddress HeadlessBackend::getExtensionFunctionPointer(const char* name) {
assert(impl);
return impl->getExtensionFunctionPointer(name);
}
void HeadlessBackend::activate() {
active = true;
if (!impl) {
createImpl();
}
assert(impl);
impl->activateContext();
}
void HeadlessBackend::deactivate() {
assert(impl);
impl->deactivateContext();
active = false;
}
gfx::Renderable& HeadlessBackend::getDefaultRenderable() {
if (!resource) {
resource = std::make_unique<HeadlessRenderableResource>(static_cast<gl::Context&>(getContext()), size);
}
return *this;
}
Size HeadlessBackend::getFramebufferSize() const {
return size;
}
void HeadlessBackend::updateAssumedState() {
// no-op
}
void HeadlessBackend::setSize(Size size_) {
size = size_;
resource.reset();
}
PremultipliedImage HeadlessBackend::readStillImage() {
return static_cast<gl::Context&>(getContext()).readFramebuffer<PremultipliedImage>(size);
}
} // namespace gl
} // namespace mbgl
|