| 1 | #pragma once |
| 2 | |
| 3 | #include <mbgl/renderer/backend_scope.hpp> |
| 4 | #include <mbgl/util/image.hpp> |
| 5 | #include <mbgl/util/size.hpp> |
| 6 | #include <mbgl/util/util.hpp> |
| 7 | |
| 8 | #include <memory> |
| 9 | #include <mutex> |
| 10 | |
| 11 | namespace mbgl { |
| 12 | |
| 13 | namespace gl { |
| 14 | class Context; |
| 15 | using ProcAddress = void (*)(); |
| 16 | using FramebufferID = uint32_t; |
| 17 | } // namespace gl |
| 18 | |
| 19 | // The RendererBackend is used by the Renderer to facilitate |
| 20 | // the actual rendering. |
| 21 | class RendererBackend { |
| 22 | public: |
| 23 | RendererBackend(); |
| 24 | virtual ~RendererBackend(); |
| 25 | |
| 26 | // Returns the backend's context which manages OpenGL state. |
| 27 | gl::Context& getContext(); |
| 28 | |
| 29 | // Called prior to rendering to update the internally assumed OpenGL state. |
| 30 | virtual void updateAssumedState() = 0; |
| 31 | |
| 32 | // Called when this backend is used for rendering. Implementations should ensure that a renderable |
| 33 | // object is bound and glClear/glDraw* calls can be done. They should also make sure that |
| 34 | // calling .bind() repeatedly is a no-op and that the appropriate gl::Context values are |
| 35 | // set to the current state. |
| 36 | virtual void bind() = 0; |
| 37 | |
| 38 | virtual Size getFramebufferSize() const = 0; |
| 39 | |
| 40 | protected: |
| 41 | // Called with the name of an OpenGL extension that should be loaded. RendererBackend implementations |
| 42 | // must call the API-specific version that obtains the function pointer for this function, |
| 43 | // or a null pointer if unsupported/unavailable. |
| 44 | virtual gl::ProcAddress getExtensionFunctionPointer(const char*) = 0; |
| 45 | |
| 46 | // Called when the backend's GL context needs to be made active or inactive. These are called, |
| 47 | // as a matched pair, exclusively through BackendScope, in two situations: |
| 48 | // |
| 49 | // 1. When releasing GL resources during Renderer destruction |
| 50 | // (Including calling CustomLayerHost::deinitialize during RenderCustomLayer destruction) |
| 51 | // 2. When renderering through Renderer::render() |
| 52 | // (Including calling CustomLayerHost::initialize for newly added custom layers and |
| 53 | // CustomLayerHost::deinitialize on layer removal) |
| 54 | virtual void activate() = 0; |
| 55 | virtual void deactivate() = 0; |
| 56 | |
| 57 | // Reads the color pixel data from the currently bound framebuffer. |
| 58 | PremultipliedImage readFramebuffer(const Size&) const; |
| 59 | |
| 60 | // A constant to signal that a framebuffer is bound, but with an unknown ID. |
| 61 | static constexpr const gl::FramebufferID ImplicitFramebufferBinding = |
| 62 | std::numeric_limits<gl::FramebufferID>::max(); |
| 63 | |
| 64 | // Tells the renderer that OpenGL state has already been set by the windowing toolkit. |
| 65 | // It sets the internal assumed state to the supplied values. |
| 66 | void assumeFramebufferBinding(gl::FramebufferID fbo); |
| 67 | void assumeViewport(int32_t x, int32_t y, const Size&); |
| 68 | void assumeScissorTest(bool); |
| 69 | |
| 70 | // Returns true when assumed framebuffer binding hasn't changed from the implicit binding. |
| 71 | bool implicitFramebufferBound(); |
| 72 | |
| 73 | // Triggers an OpenGL state update if the internal assumed state doesn't match the |
| 74 | // supplied values. |
| 75 | void setFramebufferBinding(gl::FramebufferID fbo); |
| 76 | void setViewport(int32_t x, int32_t y, const Size&); |
| 77 | void setScissorTest(bool); |
| 78 | |
| 79 | protected: |
| 80 | std::unique_ptr<gl::Context> context; |
| 81 | |
| 82 | private: |
| 83 | std::once_flag initialized; |
| 84 | |
| 85 | friend class BackendScope; |
| 86 | }; |
| 87 | |
| 88 | MBGL_CONSTEXPR bool operator==(const RendererBackend& a, const RendererBackend& b) { |
| 89 | return &a == &b; |
| 90 | } |
| 91 | |
| 92 | } // namespace mbgl |
| 93 | |