diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2019-04-01 13:48:20 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2019-04-05 11:49:17 +0200 |
commit | 865f8a6c03540e329ed6caef354799fb58b7ab6e (patch) | |
tree | 8c748a0ef16dc88ed0ceeadea71f20bfd99cdf96 | |
parent | ebd850803278a6ffbca0bc8a5b96d415b239aeb8 (diff) | |
download | qtlocation-mapboxgl-865f8a6c03540e329ed6caef354799fb58b7ab6e.tar.gz |
[core] add gfx::Renderable and gfx::OffscreenTexture
-rw-r--r-- | include/mbgl/gfx/renderable.hpp | 44 | ||||
-rw-r--r-- | include/mbgl/gl/renderable_resource.hpp | 17 | ||||
-rw-r--r-- | src/core-files.json | 7 | ||||
-rw-r--r-- | src/mbgl/gfx/context.hpp | 10 | ||||
-rw-r--r-- | src/mbgl/gfx/offscreen_texture.hpp | 25 | ||||
-rw-r--r-- | src/mbgl/gl/context.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 7 | ||||
-rw-r--r-- | src/mbgl/gl/offscreen_texture.cpp | 87 | ||||
-rw-r--r-- | src/mbgl/gl/offscreen_texture.hpp | 26 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_heatmap_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_heatmap_layer.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_hillshade_layer.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/util/offscreen_texture.cpp | 100 | ||||
-rw-r--r-- | src/mbgl/util/offscreen_texture.hpp | 39 | ||||
-rw-r--r-- | test/util/offscreen_texture.test.cpp | 7 |
17 files changed, 260 insertions, 164 deletions
diff --git a/include/mbgl/gfx/renderable.hpp b/include/mbgl/gfx/renderable.hpp new file mode 100644 index 0000000000..3a973e6693 --- /dev/null +++ b/include/mbgl/gfx/renderable.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include <mbgl/util/size.hpp> + +#include <memory> +#include <cassert> + +namespace mbgl { +namespace gfx { + +class RenderableResource { +protected: + explicit RenderableResource() = default; + +public: + virtual ~RenderableResource() = default; + RenderableResource(const RenderableResource&) = delete; + RenderableResource& operator=(const RenderableResource&) = delete; +}; + +class Renderable { +protected: + Renderable(const Size size_, std::unique_ptr<RenderableResource> resource_) + : size(size_), resource(std::move(resource_)) { + } + +public: + Size getSize() const { + return size; + } + + template <typename T> + T& getResource() const { + assert(resource); + return static_cast<T&>(*resource); + } + +protected: + Size size; + std::unique_ptr<RenderableResource> resource; +}; + +} // namespace gfx +} // namespace mbgl diff --git a/include/mbgl/gl/renderable_resource.hpp b/include/mbgl/gl/renderable_resource.hpp new file mode 100644 index 0000000000..0be0ae9c67 --- /dev/null +++ b/include/mbgl/gl/renderable_resource.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include <mbgl/gfx/renderable.hpp> + +namespace mbgl { +namespace gl { + +class RenderableResource : public gfx::RenderableResource { +protected: + explicit RenderableResource() = default; + +public: + virtual void bind() = 0; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/core-files.json b/src/core-files.json index f95d43e743..98d1de3765 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -24,6 +24,7 @@ "src/mbgl/gl/debugging_extension.cpp", "src/mbgl/gl/enum.cpp", "src/mbgl/gl/object.cpp", + "src/mbgl/gl/offscreen_texture.cpp", "src/mbgl/gl/texture.cpp", "src/mbgl/gl/uniform.cpp", "src/mbgl/gl/value.cpp", @@ -299,7 +300,6 @@ "src/mbgl/util/mat2.cpp", "src/mbgl/util/mat3.cpp", "src/mbgl/util/mat4.cpp", - "src/mbgl/util/offscreen_texture.cpp", "src/mbgl/util/premultiply.cpp", "src/mbgl/util/rapidjson.cpp", "src/mbgl/util/stopwatch.cpp", @@ -321,6 +321,8 @@ "mbgl/actor/message.hpp": "include/mbgl/actor/message.hpp", "mbgl/actor/scheduler.hpp": "include/mbgl/actor/scheduler.hpp", "mbgl/annotation/annotation.hpp": "include/mbgl/annotation/annotation.hpp", + "mbgl/gfx/renderable.hpp": "include/mbgl/gfx/renderable.hpp", + "mbgl/gl/renderable_resource.hpp": "include/mbgl/gl/renderable_resource.hpp", "mbgl/layermanager/background_layer_factory.hpp": "include/mbgl/layermanager/background_layer_factory.hpp", "mbgl/layermanager/circle_layer_factory.hpp": "include/mbgl/layermanager/circle_layer_factory.hpp", "mbgl/layermanager/custom_layer_factory.hpp": "include/mbgl/layermanager/custom_layer_factory.hpp", @@ -520,6 +522,7 @@ "mbgl/gfx/draw_scope.hpp": "src/mbgl/gfx/draw_scope.hpp", "mbgl/gfx/index_buffer.hpp": "src/mbgl/gfx/index_buffer.hpp", "mbgl/gfx/index_vector.hpp": "src/mbgl/gfx/index_vector.hpp", + "mbgl/gfx/offscreen_texture.hpp": "src/mbgl/gfx/offscreen_texture.hpp", "mbgl/gfx/program.hpp": "src/mbgl/gfx/program.hpp", "mbgl/gfx/renderbuffer.hpp": "src/mbgl/gfx/renderbuffer.hpp", "mbgl/gfx/stencil_mode.hpp": "src/mbgl/gfx/stencil_mode.hpp", @@ -541,6 +544,7 @@ "mbgl/gl/framebuffer.hpp": "src/mbgl/gl/framebuffer.hpp", "mbgl/gl/index_buffer_resource.hpp": "src/mbgl/gl/index_buffer_resource.hpp", "mbgl/gl/object.hpp": "src/mbgl/gl/object.hpp", + "mbgl/gl/offscreen_texture.hpp": "src/mbgl/gl/offscreen_texture.hpp", "mbgl/gl/program.hpp": "src/mbgl/gl/program.hpp", "mbgl/gl/program_binary_extension.hpp": "src/mbgl/gl/program_binary_extension.hpp", "mbgl/gl/renderbuffer_resource.hpp": "src/mbgl/gl/renderbuffer_resource.hpp", @@ -757,7 +761,6 @@ "mbgl/util/mat3.hpp": "src/mbgl/util/mat3.hpp", "mbgl/util/mat4.hpp": "src/mbgl/util/mat4.hpp", "mbgl/util/math.hpp": "src/mbgl/util/math.hpp", - "mbgl/util/offscreen_texture.hpp": "src/mbgl/util/offscreen_texture.hpp", "mbgl/util/rapidjson.hpp": "src/mbgl/util/rapidjson.hpp", "mbgl/util/rect.hpp": "src/mbgl/util/rect.hpp", "mbgl/util/std.hpp": "src/mbgl/util/std.hpp", diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp index 1ce00f04d1..c956debcb0 100644 --- a/src/mbgl/gfx/context.hpp +++ b/src/mbgl/gfx/context.hpp @@ -17,6 +17,8 @@ class ProgramParameters; namespace gfx { +class OffscreenTexture; + class Context { protected: Context(ContextType type_, uint32_t maximumVertexBindingCount_) @@ -124,6 +126,14 @@ protected: TexturePixelType, TextureChannelDataType) = 0; public: + virtual std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture( + Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) = 0; + virtual std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture( + Size, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&, + gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) = 0; + +public: template <RenderbufferPixelType pixelType> Renderbuffer<pixelType> createRenderbuffer(const Size size) { diff --git a/src/mbgl/gfx/offscreen_texture.hpp b/src/mbgl/gfx/offscreen_texture.hpp new file mode 100644 index 0000000000..1eaf4557c6 --- /dev/null +++ b/src/mbgl/gfx/offscreen_texture.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include <mbgl/gfx/renderable.hpp> +#include <mbgl/util/image.hpp> + +namespace mbgl { +namespace gfx { + +class Texture; + +class OffscreenTexture : public gfx::Renderable { +protected: + OffscreenTexture(const Size size_, std::unique_ptr<RenderableResource> resource_) + : gfx::Renderable(size_, std::move(resource_)) { + } + +public: + virtual ~OffscreenTexture() = default; + + virtual PremultipliedImage readStillImage() = 0; + virtual gfx::Texture& getTexture() = 0; +}; + +} // namespace gfx +} // namespace mbgl diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index f4e565c766..d33ae067f6 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -6,6 +6,7 @@ #include <mbgl/gl/renderbuffer_resource.hpp> #include <mbgl/gl/draw_scope_resource.hpp> #include <mbgl/gl/texture.hpp> +#include <mbgl/gl/offscreen_texture.hpp> #include <mbgl/gl/command_encoder.hpp> #include <mbgl/gl/debugging_extension.hpp> #include <mbgl/gl/vertex_array_extension.hpp> @@ -553,6 +554,17 @@ void Context::updateTextureResourceSub(gfx::TextureResource& resource, Enum<gfx::TextureChannelDataType>::to(type), data)); } +std::unique_ptr<gfx::OffscreenTexture> +Context::createOffscreenTexture(const Size size, const gfx::TextureChannelDataType type) { + return std::make_unique<gl::OffscreenTexture>(*this, size, type); +} + +std::unique_ptr<gfx::OffscreenTexture> +Context::createOffscreenTexture(const Size size, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& depth, + gfx::TextureChannelDataType type) { + return std::make_unique<gl::OffscreenTexture>(*this, size, depth, type); +} std::unique_ptr<gfx::DrawScopeResource> Context::createDrawScopeResource() { return std::make_unique<gl::DrawScopeResource>(createVertexArray()); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 530ff1c73f..2fb1d242ce 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -201,6 +201,13 @@ private: void updateTextureResource(gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; void updateTextureResourceSub(gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture( + Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; + std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture( + Size, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&, + gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; + std::unique_ptr<gfx::RenderbufferResource> createRenderbufferResource(gfx::RenderbufferPixelType, Size size) override; std::unique_ptr<gfx::DrawScopeResource> createDrawScopeResource() override; diff --git a/src/mbgl/gl/offscreen_texture.cpp b/src/mbgl/gl/offscreen_texture.cpp new file mode 100644 index 0000000000..96d8b7e4c4 --- /dev/null +++ b/src/mbgl/gl/offscreen_texture.cpp @@ -0,0 +1,87 @@ +#include <mbgl/gl/offscreen_texture.hpp> +#include <mbgl/gl/renderable_resource.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/framebuffer.hpp> + +namespace mbgl { +namespace gl { + +class OffscreenTextureResource final : public gl::RenderableResource { +public: + OffscreenTextureResource(gl::Context& context_, + const Size size_, + const gfx::TextureChannelDataType type_) + : context(context_), size(size_), type(type_) { + assert(!size.isEmpty()); + } + + OffscreenTextureResource(gl::Context& context_, + const Size size_, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& depth_, + const gfx::TextureChannelDataType type_) + : context(context_), size(size_), depth(&depth_), type(type_) { + assert(!size.isEmpty()); + } + + void bind() override { + if (!framebuffer) { + texture = context.createTexture(size, gfx::TexturePixelType::RGBA, type); + if (depth) { + framebuffer = context.createFramebuffer(*texture, *depth); + } else { + framebuffer = context.createFramebuffer(*texture); + } + } else { + context.bindFramebuffer = framebuffer->framebuffer; + } + + context.activeTextureUnit = 0; + context.scissorTest = false; + context.viewport = { 0, 0, size }; + } + + PremultipliedImage readStillImage() { + assert(framebuffer); + context.bindFramebuffer = framebuffer->framebuffer; + return context.readFramebuffer<PremultipliedImage>(size); + } + + gfx::Texture& getTexture() { + assert(texture); + return *texture; + } + +private: + gl::Context& context; + const Size size; + optional<gfx::Texture> texture; + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>* depth = nullptr; + const gfx::TextureChannelDataType type; + optional<gl::Framebuffer> framebuffer; +}; + +OffscreenTexture::OffscreenTexture(gl::Context& context, + const Size size_, + const gfx::TextureChannelDataType type) + : gfx::OffscreenTexture(size, std::make_unique<OffscreenTextureResource>(context, size_, type)) { +} + +OffscreenTexture::OffscreenTexture( + gl::Context& context, + const Size size_, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& renderbuffer, + const gfx::TextureChannelDataType type) + : gfx::OffscreenTexture( + size, std::make_unique<OffscreenTextureResource>(context, size_, renderbuffer, type)) { +} + +PremultipliedImage OffscreenTexture::readStillImage() { + return getResource<OffscreenTextureResource>().readStillImage(); +} + +gfx::Texture& OffscreenTexture::getTexture() { + return getResource<OffscreenTextureResource>().getTexture(); +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/offscreen_texture.hpp b/src/mbgl/gl/offscreen_texture.hpp new file mode 100644 index 0000000000..5b211df505 --- /dev/null +++ b/src/mbgl/gl/offscreen_texture.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include <mbgl/gfx/offscreen_texture.hpp> +#include <mbgl/gfx/renderbuffer.hpp> + +namespace mbgl { +namespace gl { + +class Context; + +class OffscreenTexture final : public gfx::OffscreenTexture { +public: + OffscreenTexture(gl::Context&, + Size size, + gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte); + OffscreenTexture(gl::Context&, + Size size, + gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&, + gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte); + + PremultipliedImage readStillImage() override; + gfx::Texture& getTexture() override; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index 39eb6f151d..d7c59570c1 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -15,6 +15,7 @@ #include <mbgl/tile/geometry_tile.hpp> #include <mbgl/gfx/cull_face_mode.hpp> #include <mbgl/gl/context.hpp> +#include <mbgl/gl/renderable_resource.hpp> namespace mbgl { @@ -62,10 +63,11 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters, RenderSource* const auto& size = parameters.staticData.backendSize; if (!renderTexture || renderTexture->getSize() != size) { - renderTexture = OffscreenTexture(parameters.context, size, *parameters.staticData.depthRenderbuffer); + renderTexture.reset(); + renderTexture = parameters.context.createOffscreenTexture(size, *parameters.staticData.depthRenderbuffer); } - renderTexture->bind(); + renderTexture->getResource<gl::RenderableResource>().bind(); optional<float> depthClearValue = {}; if (parameters.staticData.depthRenderbuffer->needsClearing()) depthClearValue = 1.0; diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp index 886362f28e..6f14fcd7a8 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp @@ -3,8 +3,7 @@ #include <mbgl/renderer/render_layer.hpp> #include <mbgl/style/layers/fill_extrusion_layer_impl.hpp> #include <mbgl/style/layers/fill_extrusion_layer_properties.hpp> -#include <mbgl/util/optional.hpp> -#include <mbgl/util/offscreen_texture.hpp> +#include <mbgl/gfx/offscreen_texture.hpp> namespace mbgl { @@ -41,7 +40,7 @@ public: const style::FillExtrusionLayer::Impl& impl() const; - optional<OffscreenTexture> renderTexture; + std::unique_ptr<gfx::OffscreenTexture> renderTexture; private: CrossfadeParameters crossfade; }; diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index c720709e28..15345ffe9e 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -11,6 +11,7 @@ #include <mbgl/geometry/feature_index.hpp> #include <mbgl/gfx/cull_face_mode.hpp> #include <mbgl/gl/context.hpp> +#include <mbgl/gl/renderable_resource.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/intersection_tests.hpp> @@ -57,27 +58,27 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto size = Size{viewportSize.width / 4, viewportSize.height / 4}; if (!renderTexture || renderTexture->getSize() != size) { + renderTexture.reset(); if (parameters.context.supportsHalfFloatTextures) { - renderTexture = OffscreenTexture(parameters.context, size, gfx::TextureChannelDataType::HalfFloat); + renderTexture = parameters.context.createOffscreenTexture(size, gfx::TextureChannelDataType::HalfFloat); + // TODO: try binding in the offscreen texture constructor try { - renderTexture->bind(); + renderTexture->getResource<gl::RenderableResource>().bind(); } catch (const std::runtime_error& ex) { // can't render to a half-float texture; falling back to unsigned byte one - renderTexture = nullopt; + renderTexture.reset(); parameters.context.supportsHalfFloatTextures = false; } } - if (!parameters.context.supportsHalfFloatTextures || !renderTexture) { - renderTexture = OffscreenTexture(parameters.context, size, gfx::TextureChannelDataType::UnsignedByte); - renderTexture->bind(); + if (!renderTexture) { + renderTexture = parameters.context.createOffscreenTexture(size, gfx::TextureChannelDataType::UnsignedByte); } - - } else { - renderTexture->bind(); } + renderTexture->getResource<gl::RenderableResource>().bind(); + if (!colorRampTexture) { colorRampTexture = parameters.context.createTexture(colorRamp, gfx::TextureChannelDataType::UnsignedByte); } diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.hpp b/src/mbgl/renderer/layers/render_heatmap_layer.hpp index 364628a2b2..22fe48f374 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.hpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.hpp @@ -4,8 +4,8 @@ #include <mbgl/style/layers/heatmap_layer_impl.hpp> #include <mbgl/style/layers/heatmap_layer_properties.hpp> #include <mbgl/gfx/texture.hpp> +#include <mbgl/gfx/offscreen_texture.hpp> #include <mbgl/util/optional.hpp> -#include <mbgl/util/offscreen_texture.hpp> namespace mbgl { @@ -36,7 +36,7 @@ public: const style::HeatmapLayer::Impl& impl() const; PremultipliedImage colorRamp; - optional<OffscreenTexture> renderTexture; + std::unique_ptr<gfx::OffscreenTexture> renderTexture; optional<gfx::Texture> colorRampTexture; private: diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index 527d48f654..426c34e599 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -10,8 +10,9 @@ #include <mbgl/tile/tile.hpp> #include <mbgl/style/layers/hillshade_layer_impl.hpp> #include <mbgl/gfx/cull_face_mode.hpp> +#include <mbgl/gfx/offscreen_texture.hpp> +#include <mbgl/gl/renderable_resource.hpp> #include <mbgl/util/geo.hpp> -#include <mbgl/util/offscreen_texture.hpp> namespace mbgl { @@ -130,8 +131,8 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src assert(bucket.dem); const uint16_t stride = bucket.getDEMData().stride; const uint16_t tilesize = bucket.getDEMData().dim; - OffscreenTexture view(parameters.context, { tilesize, tilesize }); - view.bind(); + auto view = parameters.context.createOffscreenTexture({ tilesize, tilesize }); + view->getResource<gl::RenderableResource>().bind(); const Properties<>::PossiblyEvaluated properties; const HillshadePrepareProgram::Binders paintAttributeData{ properties, 0 }; @@ -173,7 +174,7 @@ void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src }, getID() ); - bucket.texture = std::move(view.getTexture()); + bucket.texture = std::move(view->getTexture()); bucket.setPrepared(true); } else if (parameters.pass == RenderPass::Translucent) { assert(bucket.texture); diff --git a/src/mbgl/util/offscreen_texture.cpp b/src/mbgl/util/offscreen_texture.cpp deleted file mode 100644 index 9fa1dcd90e..0000000000 --- a/src/mbgl/util/offscreen_texture.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include <mbgl/gl/context.hpp> -#include <mbgl/util/offscreen_texture.hpp> - -#include <cassert> -#include <cstring> - -namespace mbgl { - -OffscreenTexture::OffscreenTexture(OffscreenTexture&&) = default; -OffscreenTexture& OffscreenTexture::operator=(OffscreenTexture&&) = default; - -class OffscreenTexture::Impl { -public: - Impl(gl::Context& context_, const Size size_, const gfx::TextureChannelDataType type_) - : context(context_), size(std::move(size_)), type(type_) { - assert(!size.isEmpty()); - } - Impl(gl::Context& context_, - const Size size_, - gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& depth_, - const gfx::TextureChannelDataType type_) - : context(context_), size(std::move(size_)), depth(&depth_), type(type_) { - assert(!size.isEmpty()); - } - - void bind() { - if (!framebuffer) { - texture = context.createTexture(size, gfx::TexturePixelType::RGBA, type); - if (depth) { - framebuffer = context.createFramebuffer(*texture, *depth); - } else { - framebuffer = context.createFramebuffer(*texture); - } - } else { - context.bindFramebuffer = framebuffer->framebuffer; - } - - context.activeTextureUnit = 0; - context.scissorTest = false; - context.viewport = { 0, 0, size }; - } - - PremultipliedImage readStillImage() { - return context.readFramebuffer<PremultipliedImage>(size); - } - - gfx::Texture& getTexture() { - assert(texture); - return *texture; - } - - const Size& getSize() const { - return size; - } - -private: - gl::Context& context; - const Size size; - optional<gl::Framebuffer> framebuffer; - optional<gfx::Texture> texture; - gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>* depth = nullptr; - const gfx::TextureChannelDataType type; -}; - -OffscreenTexture::OffscreenTexture(gfx::Context& context, - const Size size, - const gfx::TextureChannelDataType type) - // TODO: remove cast - : impl(std::make_unique<Impl>(static_cast<gl::Context&>(context), std::move(size), type)) { - assert(!size.isEmpty()); -} - -OffscreenTexture::OffscreenTexture(gfx::Context& context, - const Size size, - gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>& renderbuffer, - const gfx::TextureChannelDataType type) - // TODO: remove cast - : impl(std::make_unique<Impl>(static_cast<gl::Context&>(context), std::move(size), renderbuffer, type)) { - assert(!size.isEmpty()); -} - -OffscreenTexture::~OffscreenTexture() = default; - -void OffscreenTexture::bind() { - impl->bind(); -} - -PremultipliedImage OffscreenTexture::readStillImage() { - return impl->readStillImage(); -} - -gfx::Texture& OffscreenTexture::getTexture() { - return impl->getTexture(); -} - -const Size& OffscreenTexture::getSize() const { - return impl->getSize(); -} - -} // namespace mbgl diff --git a/src/mbgl/util/offscreen_texture.hpp b/src/mbgl/util/offscreen_texture.hpp deleted file mode 100644 index db8cfac559..0000000000 --- a/src/mbgl/util/offscreen_texture.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include <mbgl/gfx/renderbuffer.hpp> -#include <mbgl/util/image.hpp> - -namespace mbgl { - -namespace gfx { -class Context; -class Texture; -} // namespace gfx - -class OffscreenTexture { -public: - OffscreenTexture(gfx::Context&, - Size size = { 256, 256 }, - gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte); - OffscreenTexture(gfx::Context&, - Size size, - gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&, - gfx::TextureChannelDataType type = gfx::TextureChannelDataType::UnsignedByte); - ~OffscreenTexture(); - OffscreenTexture(OffscreenTexture&&); - OffscreenTexture& operator=(OffscreenTexture&&); - - void bind(); - - PremultipliedImage readStillImage(); - - gfx::Texture& getTexture(); - - const Size& getSize() const; - -private: - class Impl; - std::unique_ptr<Impl> impl; -}; - -} // namespace mbgl diff --git a/test/util/offscreen_texture.test.cpp b/test/util/offscreen_texture.test.cpp index 0f24c1e9af..887a1cdc00 100644 --- a/test/util/offscreen_texture.test.cpp +++ b/test/util/offscreen_texture.test.cpp @@ -4,10 +4,11 @@ #include <mbgl/gl/context.hpp> #include <mbgl/gl/texture.hpp> #include <mbgl/gl/defines.hpp> +#include <mbgl/gl/renderable_resource.hpp> #include <mbgl/gl/headless_backend.hpp> #include <mbgl/renderer/backend_scope.hpp> +#include <mbgl/gl/offscreen_texture.hpp> -#include <mbgl/util/offscreen_texture.hpp> using namespace mbgl; using namespace mbgl::platform; @@ -132,13 +133,13 @@ void main() { // Then, create a texture, bind it, and render yellow to that texture. This should not // affect the originally bound FBO. - OffscreenTexture texture(context, { 128, 128 }); + gl::OffscreenTexture texture(context, { 128, 128 }); // Scissor test shouldn't leak after OffscreenTexture::bind(). MBGL_CHECK_ERROR(glScissor(32, 32, 64, 64)); context.scissorTest.setCurrentValue(true); - texture.bind(); + texture.getResource<gl::RenderableResource>().bind(); context.clear(Color(), {}, {}); |