summaryrefslogtreecommitdiff
path: root/src/mbgl/tile/tile.hpp
blob: 651bafe277f105b5527b2f720f7b03afec443ebf (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
#pragma once

#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/feature.hpp>
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/tile/tile_necessity.hpp>
#include <mbgl/renderer/tile_mask.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/style/layer_properties.hpp>

#include <string>
#include <memory>
#include <functional>
#include <unordered_map>

namespace mbgl {

class DebugBucket;
class LayerRenderData;
class TransformState;
class TileObserver;
class RenderLayer;
class RenderedQueryOptions;
class SourceQueryOptions;

class CollisionIndex;

namespace gl {
class Context;
} // namespace gl


class Tile {
public:
    enum class Kind : uint8_t {
        Geometry,
        Raster,
        RasterDEM
    };
    Tile(const Tile&) = delete;
    Tile& operator=(const Tile&) = delete;

    Tile(Kind, OverscaledTileID);
    virtual ~Tile();

    void setObserver(TileObserver* observer);

    virtual void setNecessity(TileNecessity) {}

    // Mark this tile as no longer needed and cancel any pending work.
    virtual void cancel();

    virtual void upload(gfx::Context&) = 0;
    virtual Bucket* getBucket(const style::Layer::Impl&) const = 0;
    virtual const LayerRenderData* getLayerRenderData(const style::Layer::Impl&) const {
        return nullptr;
    }
    // Updates the contained layer render data with the given properties.
    // Returns `true` if the corresponding render layer data is present in this tile (and i.e. it
    // was succesfully updated); returns `false` otherwise.
    virtual bool updateLayerProperties(const Immutable<style::LayerProperties>&) { return true; }

    template <class T>
    T* getBucket(const style::Layer::Impl& layer) const {
        return static_cast<T*>(getBucket(layer));
    }

    virtual void setShowCollisionBoxes(const bool) {}
    virtual void setLayers(const std::vector<Immutable<style::LayerProperties>>&) {}
    virtual void setMask(TileMask&&) {}

    virtual void queryRenderedFeatures(
            std::unordered_map<std::string, std::vector<Feature>>& result,
            const GeometryCoordinates& queryGeometry,
            const TransformState&,
            const std::vector<const RenderLayer*>&,
            const RenderedQueryOptions& options,
            const mat4& projMatrix);

    virtual void querySourceFeatures(
            std::vector<Feature>& result,
            const SourceQueryOptions&);

    virtual float getQueryPadding(const std::vector<const RenderLayer*>&);

    void setTriedCache();

    // Returns true when the tile source has received a first response, regardless of whether a load
    // error occurred or actual data was loaded.
    bool hasTriedCache() const {
        return triedOptional;
    }

    // Tile data considered "Renderable" can be used for rendering. Data in
    // partial state is still waiting for network resources but can also
    // be rendered, although layers will be missing.
    bool isRenderable() const {
        return renderable;
    }

    // A tile is "Loaded" when we have received a response from a FileSource, and have attempted to
    // parse the tile (if applicable). Tile implementations should set this to true when a load
    // error occurred, or after the tile was parsed successfully.
    bool isLoaded() const {
        return loaded;
    }

    // "Completion" of a tile means that we have attempted to load it, and parsed it completely,
    // i.e. no parsing or placement operations are pending for that tile.
    // Completeness doesn't mean that the tile can be rendered, but merely that we have exhausted
    // all options to get this tile to a renderable state. Some tiles may not be renderable, but
    // complete, e.g. when a raster tile couldn't be loaded, or parsing failed.
    bool isComplete() const {
        return loaded && !pending;
    }
    
    // "holdForFade" is used to keep tiles in the render tree after they're no longer
    // ideal tiles in order to allow symbols to fade out
    virtual bool holdForFade() const {
        return false;
    }
    // Set whenever this tile is used as an ideal tile
    virtual void markRenderedIdeal() {}
    // Set when the tile is removed from the ideal render set but may still be held for fading
    virtual void markRenderedPreviously() {}
    // Placement operation performed while this tile is fading
    // We hold onto a tile for two placements: fading starts with the first placement
    // and will have time to finish by the second placement.
    virtual void performedFadePlacement() {}
    
    void dumpDebugLogs() const;

    const Kind kind;
    OverscaledTileID id;
    optional<Timestamp> modified;
    optional<Timestamp> expires;

    // Contains the tile ID string for painting debug information.
    std::unique_ptr<DebugBucket> debugBucket;

protected:
    bool triedOptional = false;
    bool renderable = false;
    bool pending = false;
    bool loaded = false;

    TileObserver* observer = nullptr;
};

} // namespace mbgl