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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include <mbgl/gl/headless_frontend.hpp>
#include <mbgl/renderer/renderer.hpp>
#include <mbgl/renderer/renderer_state.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/util/run_loop.hpp>
namespace mbgl {
HeadlessFrontend::HeadlessFrontend(float pixelRatio_, FileSource& fileSource, Scheduler& scheduler, const optional<std::string> programCacheDir, GLContextMode mode, const optional<std::string> localFontFamily)
: HeadlessFrontend({ 256, 256 }, pixelRatio_, fileSource, scheduler, programCacheDir, mode, localFontFamily) {
}
HeadlessFrontend::HeadlessFrontend(Size size_, float pixelRatio_, FileSource& fileSource, Scheduler& scheduler, const optional<std::string> programCacheDir, GLContextMode mode, const optional<std::string> localFontFamily)
: size(size_),
pixelRatio(pixelRatio_),
backend({ static_cast<uint32_t>(size.width * pixelRatio),
static_cast<uint32_t>(size.height * pixelRatio) }),
asyncInvalidate([this] {
if (renderer && updateParameters) {
mbgl::BackendScope guard { backend };
renderer->render(*updateParameters);
}
}),
renderer(std::make_unique<Renderer>(backend, pixelRatio, fileSource, scheduler, mode, programCacheDir, localFontFamily)) {
}
HeadlessFrontend::~HeadlessFrontend() = default;
void HeadlessFrontend::reset() {
assert(renderer);
renderer.reset();
}
void HeadlessFrontend::update(std::shared_ptr<UpdateParameters> updateParameters_) {
updateParameters = updateParameters_;
asyncInvalidate.send();
}
void HeadlessFrontend::setObserver(RendererObserver& observer_) {
assert(renderer);
renderer->setObserver(&observer_);
}
Size HeadlessFrontend::getSize() const {
return size;
}
Renderer* HeadlessFrontend::getRenderer() {
assert(renderer);
return renderer.get();
}
RendererBackend* HeadlessFrontend::getBackend() {
return &backend;
}
CameraOptions HeadlessFrontend::getCameraOptions() {
if (updateParameters)
return RendererState::getCameraOptions(*updateParameters);
static CameraOptions nullCamera;
return nullCamera;
}
bool HeadlessFrontend::hasImage(const std::string& id) {
if (updateParameters) {
return RendererState::hasImage(*updateParameters, id);
}
return false;
}
bool HeadlessFrontend::hasLayer(const std::string& id) {
if (updateParameters) {
return RendererState::hasLayer(*updateParameters, id);
}
return false;
}
bool HeadlessFrontend::hasSource(const std::string& id) {
if (updateParameters) {
return RendererState::hasSource(*updateParameters, id);
}
return false;
}
void HeadlessFrontend::setSize(Size size_) {
if (size != size_) {
size = size_;
backend.setSize({ static_cast<uint32_t>(size_.width * pixelRatio),
static_cast<uint32_t>(size_.height * pixelRatio) });
}
}
PremultipliedImage HeadlessFrontend::readStillImage() {
return backend.readStillImage();
}
PremultipliedImage HeadlessFrontend::render(Map& map) {
PremultipliedImage result;
map.renderStill([&](std::exception_ptr error) {
if (error) {
std::rethrow_exception(error);
} else {
result = backend.readStillImage();
}
});
while (!result.valid()) {
util::RunLoop::Get()->runOnce();
}
return result;
}
optional<TransformState> HeadlessFrontend::getTransformState() const {
if (updateParameters) {
return updateParameters->transformState;
} else {
return {};
}
}
} // namespace mbgl
|