From 865f8a6c03540e329ed6caef354799fb58b7ab6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Mon, 1 Apr 2019 13:48:20 +0200 Subject: [core] add gfx::Renderable and gfx::OffscreenTexture --- src/core-files.json | 7 +- src/mbgl/gfx/context.hpp | 10 +++ src/mbgl/gfx/offscreen_texture.hpp | 25 ++++++ src/mbgl/gl/context.cpp | 12 +++ src/mbgl/gl/context.hpp | 7 ++ src/mbgl/gl/offscreen_texture.cpp | 87 ++++++++++++++++++ src/mbgl/gl/offscreen_texture.hpp | 26 ++++++ .../layers/render_fill_extrusion_layer.cpp | 6 +- .../layers/render_fill_extrusion_layer.hpp | 5 +- src/mbgl/renderer/layers/render_heatmap_layer.cpp | 19 ++-- src/mbgl/renderer/layers/render_heatmap_layer.hpp | 4 +- .../renderer/layers/render_hillshade_layer.cpp | 9 +- src/mbgl/util/offscreen_texture.cpp | 100 --------------------- src/mbgl/util/offscreen_texture.hpp | 39 -------- 14 files changed, 195 insertions(+), 161 deletions(-) create mode 100644 src/mbgl/gfx/offscreen_texture.hpp create mode 100644 src/mbgl/gl/offscreen_texture.cpp create mode 100644 src/mbgl/gl/offscreen_texture.hpp delete mode 100644 src/mbgl/util/offscreen_texture.cpp delete mode 100644 src/mbgl/util/offscreen_texture.hpp (limited to 'src') 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_) @@ -123,6 +125,14 @@ protected: virtual void updateTextureResourceSub(TextureResource&, uint16_t xOffset, uint16_t yOffset, Size, const void* data, TexturePixelType, TextureChannelDataType) = 0; +public: + virtual std::unique_ptr createOffscreenTexture( + Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) = 0; + virtual std::unique_ptr createOffscreenTexture( + Size, + gfx::Renderbuffer&, + gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) = 0; + public: template Renderbuffer 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 +#include + +namespace mbgl { +namespace gfx { + +class Texture; + +class OffscreenTexture : public gfx::Renderable { +protected: + OffscreenTexture(const Size size_, std::unique_ptr 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 #include #include +#include #include #include #include @@ -553,6 +554,17 @@ void Context::updateTextureResourceSub(gfx::TextureResource& resource, Enum::to(type), data)); } +std::unique_ptr +Context::createOffscreenTexture(const Size size, const gfx::TextureChannelDataType type) { + return std::make_unique(*this, size, type); +} + +std::unique_ptr +Context::createOffscreenTexture(const Size size, + gfx::Renderbuffer& depth, + gfx::TextureChannelDataType type) { + return std::make_unique(*this, size, depth, type); +} std::unique_ptr Context::createDrawScopeResource() { return std::make_unique(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 createOffscreenTexture( + Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; + std::unique_ptr createOffscreenTexture( + Size, + gfx::Renderbuffer&, + gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; + std::unique_ptr createRenderbufferResource(gfx::RenderbufferPixelType, Size size) override; std::unique_ptr 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 +#include +#include +#include + +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& 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(size); + } + + gfx::Texture& getTexture() { + assert(texture); + return *texture; + } + +private: + gl::Context& context; + const Size size; + optional texture; + gfx::Renderbuffer* depth = nullptr; + const gfx::TextureChannelDataType type; + optional framebuffer; +}; + +OffscreenTexture::OffscreenTexture(gl::Context& context, + const Size size_, + const gfx::TextureChannelDataType type) + : gfx::OffscreenTexture(size, std::make_unique(context, size_, type)) { +} + +OffscreenTexture::OffscreenTexture( + gl::Context& context, + const Size size_, + gfx::Renderbuffer& renderbuffer, + const gfx::TextureChannelDataType type) + : gfx::OffscreenTexture( + size, std::make_unique(context, size_, renderbuffer, type)) { +} + +PremultipliedImage OffscreenTexture::readStillImage() { + return getResource().readStillImage(); +} + +gfx::Texture& OffscreenTexture::getTexture() { + return getResource().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 +#include + +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::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 #include #include +#include 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().bind(); optional 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 #include #include -#include -#include +#include namespace mbgl { @@ -41,7 +40,7 @@ public: const style::FillExtrusionLayer::Impl& impl() const; - optional renderTexture; + std::unique_ptr 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 #include #include +#include #include #include @@ -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().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().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 #include #include +#include #include -#include namespace mbgl { @@ -36,7 +36,7 @@ public: const style::HeatmapLayer::Impl& impl() const; PremultipliedImage colorRamp; - optional renderTexture; + std::unique_ptr renderTexture; optional 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 #include #include +#include +#include #include -#include 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().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 -#include - -#include -#include - -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& 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(size); - } - - gfx::Texture& getTexture() { - assert(texture); - return *texture; - } - - const Size& getSize() const { - return size; - } - -private: - gl::Context& context; - const Size size; - optional framebuffer; - optional texture; - gfx::Renderbuffer* 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(static_cast(context), std::move(size), type)) { - assert(!size.isEmpty()); -} - -OffscreenTexture::OffscreenTexture(gfx::Context& context, - const Size size, - gfx::Renderbuffer& renderbuffer, - const gfx::TextureChannelDataType type) - // TODO: remove cast - : impl(std::make_unique(static_cast(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 -#include - -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::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; -}; - -} // namespace mbgl -- cgit v1.2.1