summaryrefslogtreecommitdiff
path: root/platform/android/src/map_renderer.hpp
blob: 5fb5ef1a618d25604a2efcfe0d1247da1ede5298 (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
#pragma once

#include <mbgl/actor/scheduler.hpp>
#include <mbgl/util/image.hpp>

#include <memory>
#include <utility>

#include <jni/jni.hpp>
#include <mbgl/storage/default_file_source.hpp>

#include "jni/generic_global_ref_deleter.hpp"

namespace mbgl {

template <class>
class ActorRef;
class Mailbox;
class Renderer;
class RendererBackend;
class RendererObserver;
class ThreadPool;
class UpdateParameters;

namespace android {

class AndroidRendererBackend;
class FileSource;

/**
 * The MapRenderer is a peer class that encapsulates the actions
 * performed on the GL Thread.
 *
 * The public methods are safe to call from the main thread, others are not.
 */
class MapRenderer : public Scheduler {
public:

    static constexpr auto Name() { return "com/mapbox/mapboxsdk/maps/renderer/MapRenderer"; };

    static jni::Class<MapRenderer> javaClass;

    static void registerNative(jni::JNIEnv&);

    static MapRenderer& getNativePeer(JNIEnv&, jni::Object<MapRenderer>);

    MapRenderer(jni::JNIEnv& _env,
                jni::Object<MapRenderer>,
                jni::Object<FileSource>,
                jni::jfloat pixelRatio,
                jni::String programCacheDir,
                jni::String localIdeographFontFamily);

    ~MapRenderer() override;

    // Resets the renderer to clean up on the calling thread
    void reset();

    // Takes the RendererObserver by shared_ptr so we
    // don't have to make the header public. Use
    // this instead of Renderer#setObserver directly
    void setObserver(std::shared_ptr<RendererObserver>);

    // Sets the new update parameters to use on subsequent
    // renders. Be sure to trigger a render with
    // requestRender().
    void update(std::shared_ptr<UpdateParameters>);

    // Gives a handle to the Renderer to enable actions on
    // any thread.
    ActorRef<Renderer> actor() const;

    // From Scheduler. Schedules by using callbacks to the
    // JVM to process the mailbox on the right thread.
    void schedule(std::weak_ptr<Mailbox> scheduled) override;

    void requestRender();

    // Snapshot - requires a RunLoop on the calling thread
    using SnapshotCallback = std::function<void (PremultipliedImage)>;
    void requestSnapshot(SnapshotCallback);

protected:
    // Called from the GL Thread //

    void scheduleSnapshot(std::unique_ptr<SnapshotCallback>);

private:
    // Called from the GL Thread //

    // Resets the renderer
    void resetRenderer();

    // Renders a frame.
    void render(JNIEnv&);

    void onSurfaceCreated(JNIEnv&);

    void onSurfaceChanged(JNIEnv&, jint width, jint height);

    void onResume(JNIEnv&);

    void onPause(JNIEnv&);

private:
    GenericUniqueWeakObject<MapRenderer> javaPeer;

    float pixelRatio;
    DefaultFileSource& fileSource;
    std::string programCacheDir;
    optional<std::string> localIdeographFontFamily;

    std::shared_ptr<ThreadPool> threadPool;
    std::shared_ptr<Mailbox> mailbox;

    std::mutex initialisationMutex;
    std::shared_ptr<RendererObserver> rendererObserver;

    std::unique_ptr<AndroidRendererBackend> backend;
    std::unique_ptr<Renderer> renderer;
    std::unique_ptr<ActorRef<Renderer>> rendererRef;

    std::shared_ptr<UpdateParameters> updateParameters;
    std::mutex updateMutex;

    bool framebufferSizeChanged = false;
    std::atomic<bool> paused {false};

    std::unique_ptr<SnapshotCallback> snapshotCallback;
};

} // namespace android
} // namespace mbgl