summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/render_layer.cpp
blob: 3813e9f6b617fd757eb6991b1b646beb2b16c668 (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
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/style/layer.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/util/logging.hpp>

namespace mbgl {

using namespace style;

LayerRenderItem::LayerRenderItem(RenderTiles renderTiles_, LayerRenderer renderer_, LayerUploader uploader_, Immutable<style::LayerProperties> evaluatedProperties_, RenderPass renderPass_)
    : renderTiles(std::move(renderTiles_))
    , renderer(std::move(renderer_))
    , uploader(std::move(uploader_))
    , evaluatedProperties(std::move(evaluatedProperties_))
    , renderPass(renderPass_) {}

LayerRenderItem::~LayerRenderItem() = default;

LayerRenderItem RenderLayer::createRenderItem() {
    return {
        renderTiles,
        createRenderer(),
        createUploader(),
        evaluatedProperties,
        passes
    };
}

void LayerRenderItem::checkRenderability(const PaintParameters& parameters,
                                         const uint32_t activeBindingCount) const {
    // Only warn once for every layer.
    if (hasRenderFailures) {
        return;
    }
    std::string layerId = evaluatedProperties->baseImpl->id;
    if (activeBindingCount > parameters.context.maximumVertexBindingCount) {
        Log::Info(Event::OpenGL,
                "The layer '%s' uses more data-driven properties than the current device "
                "supports, and will have rendering errors. To ensure compatibility with this "
                "device, use %d fewer data driven properties in this layer.",
                layerId.c_str(),
                activeBindingCount - parameters.context.minimumRequiredVertexBindingCount);
        hasRenderFailures = true;
    } else if (activeBindingCount > parameters.context.minimumRequiredVertexBindingCount) {
        Log::Info(Event::OpenGL,
                "The layer '%s' uses more data-driven properties than some devices may support. "
                "Though it will render correctly on this device, it may have rendering errors "
                "on other devices. To ensure compatibility with all devices, use %d fewer "
                "data-driven properties in this layer.",
                layerId.c_str(),
                activeBindingCount - parameters.context.minimumRequiredVertexBindingCount);
        hasRenderFailures = true;
    }
}

LayerRenderer RenderLayer::createRenderer() {
    return [this](PaintParameters& pass, const LayerRenderItem&){ render(pass); };
}

LayerUploader RenderLayer::createUploader() {
    return {};
}

RenderLayer::RenderLayer(Immutable<style::LayerProperties> properties)
    : evaluatedProperties(std::move(properties)),
      baseImpl(evaluatedProperties->baseImpl) {
}

void RenderLayer::transition(const TransitionParameters& parameters, Immutable<style::Layer::Impl> newImpl) {
    baseImpl = std::move(newImpl);
    transition(parameters);
}

bool RenderLayer::needsPlacement() const {
    return baseImpl->getTypeInfo()->crossTileIndex == style::LayerTypeInfo::CrossTileIndex::Required
           && !placementData.empty();
}

const std::string& RenderLayer::getID() const {
    return baseImpl->id;
}

bool RenderLayer::hasRenderPass(RenderPass pass) const {
    return bool(passes & pass);
}

bool RenderLayer::needsRendering() const {
    return passes != RenderPass::None
           && baseImpl->visibility != style::VisibilityType::None;
}

bool RenderLayer::supportsZoom(float zoom) const {
    // TODO: shall we use rounding or epsilon comparisons?
    return baseImpl->minZoom <= zoom && baseImpl->maxZoom >= zoom;
}

void RenderLayer::prepare(const LayerPrepareParameters& params) {
    assert(params.source);
    renderTiles = filterRenderTiles(params.source->getRenderTiles());
}

optional<Color> RenderLayer::getSolidBackground() const {
    return nullopt;
}

RenderTiles RenderLayer::filterRenderTiles(RenderTiles tiles) const {
    RenderTiles filtered;

    for (const RenderTile& tile : tiles) {
        if (tile.holdForFade()) {
            continue;
        }
        filtered.emplace_back(tile);
    }
    return filtered;
}

void RenderLayer::markContextDestroyed() {
    // no-op
}

void RenderLayer::checkRenderability(const PaintParameters& parameters,
                                     const uint32_t activeBindingCount) {
    // Only warn once for every layer.
    if (hasRenderFailures) {
        return;
    }

    if (activeBindingCount > parameters.context.maximumVertexBindingCount) {
        Log::Info(Event::OpenGL,
                "The layer '%s' uses more data-driven properties than the current device "
                "supports, and will have rendering errors. To ensure compatibility with this "
                "device, use %d fewer data driven properties in this layer.",
                getID().c_str(),
                activeBindingCount - parameters.context.minimumRequiredVertexBindingCount);
        hasRenderFailures = true;
    } else if (activeBindingCount > parameters.context.minimumRequiredVertexBindingCount) {
        Log::Info(Event::OpenGL,
                "The layer '%s' uses more data-driven properties than some devices may support. "
                "Though it will render correctly on this device, it may have rendering errors "
                "on other devices. To ensure compatibility with all devices, use %d fewer "
                "data-driven properties in this layer.",
                getID().c_str(),
                activeBindingCount - parameters.context.minimumRequiredVertexBindingCount);
        hasRenderFailures = true;
    }
}

} //namespace mbgl