[core] Reuse fill-extrusion textures between frames (#8896)
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Map;
|
||||
|
||||
class View : private util::noncopyable {
|
||||
class View {
|
||||
public:
|
||||
virtual ~View() = default;
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#include <mbgl/util/mat3.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include <mbgl/util/offscreen_texture.hpp>
|
||||
|
||||
#include <mbgl/util/stopwatch.hpp>
|
||||
|
||||
#include <cassert>
|
||||
@@ -328,8 +326,11 @@ void Painter::renderPass(PaintParameters& parameters,
|
||||
} else if (layer.is<RenderFillExtrusionLayer>()) {
|
||||
const auto size = context.viewport.getCurrentValue().size;
|
||||
|
||||
OffscreenTexture texture(context, size);
|
||||
texture.bindRenderbuffers(1);
|
||||
if (!extrusionTexture || extrusionTexture->getSize() != size) {
|
||||
extrusionTexture = OffscreenTexture(context, size, OffscreenTextureAttachment::Depth);
|
||||
}
|
||||
|
||||
extrusionTexture->bind();
|
||||
|
||||
context.setStencilMode(gl::StencilMode::disabled());
|
||||
context.setDepthMode(depthModeForSublayer(0, gl::DepthMode::ReadWrite));
|
||||
@@ -344,6 +345,7 @@ void Painter::renderPass(PaintParameters& parameters,
|
||||
}
|
||||
|
||||
parameters.view.bind();
|
||||
context.bindTexture(extrusionTexture->getTexture());
|
||||
|
||||
mat4 viewportMat;
|
||||
matrix::ortho(viewportMat, 0, size.width, size.height, 0, 0, 1);
|
||||
@@ -355,11 +357,10 @@ void Painter::renderPass(PaintParameters& parameters,
|
||||
colorModeForRenderPass(),
|
||||
ExtrusionTextureProgram::UniformValues{
|
||||
uniforms::u_matrix::Value{ viewportMat }, uniforms::u_world::Value{ size },
|
||||
uniforms::u_image::Value{ 1 },
|
||||
uniforms::u_opacity::Value{
|
||||
layer.as<RenderFillExtrusionLayer>()->evaluated.get<FillExtrusionOpacity>() } },
|
||||
extrusionTextureVertexBuffer, quadTriangleIndexBuffer,
|
||||
extrusionTextureSegments,
|
||||
uniforms::u_image::Value{ 0 },
|
||||
uniforms::u_opacity::Value{ layer.as<RenderFillExtrusionLayer>()
|
||||
->evaluated.get<FillExtrusionOpacity>() } },
|
||||
extrusionTextureVertexBuffer, quadTriangleIndexBuffer, extrusionTextureSegments,
|
||||
ExtrusionTextureProgram::PaintPropertyBinders{ properties, 0 }, properties,
|
||||
state.getZoom());
|
||||
} else {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/offscreen_texture.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
@@ -158,6 +159,8 @@ private:
|
||||
GlyphAtlas* glyphAtlas = nullptr;
|
||||
LineAtlas* lineAtlas = nullptr;
|
||||
|
||||
optional<OffscreenTexture> extrusionTexture;
|
||||
|
||||
EvaluatedLight evaluatedLight;
|
||||
|
||||
FrameHistory frameHistory;
|
||||
|
||||
@@ -6,16 +6,28 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
OffscreenTexture::OffscreenTexture(OffscreenTexture&&) = default;
|
||||
OffscreenTexture& OffscreenTexture::operator=(OffscreenTexture&&) = default;
|
||||
|
||||
class OffscreenTexture::Impl {
|
||||
public:
|
||||
Impl(gl::Context& context_, const Size size_) : context(context_), size(std::move(size_)) {
|
||||
Impl(gl::Context& context_, const Size size_, OffscreenTextureAttachment type_)
|
||||
: context(context_), size(std::move(size_)), type(type_) {
|
||||
assert(!size.isEmpty());
|
||||
}
|
||||
|
||||
void bind() {
|
||||
if (!framebuffer) {
|
||||
texture = context.createTexture(size, gl::TextureFormat::RGBA);
|
||||
framebuffer = context.createFramebuffer(*texture);
|
||||
|
||||
if (type == OffscreenTextureAttachment::Depth) {
|
||||
gl::Renderbuffer<gl::RenderbufferType::DepthComponent> depth =
|
||||
context.createRenderbuffer<gl::RenderbufferType::DepthComponent>(size);
|
||||
framebuffer = context.createFramebuffer(*texture, depth);
|
||||
|
||||
} else {
|
||||
framebuffer = context.createFramebuffer(*texture);
|
||||
}
|
||||
} else {
|
||||
context.bindFramebuffer = framebuffer->framebuffer;
|
||||
}
|
||||
@@ -37,29 +49,18 @@ public:
|
||||
return size;
|
||||
}
|
||||
|
||||
void bindRenderbuffers(gl::TextureUnit unit) {
|
||||
if (!framebuffer) {
|
||||
texture = context.createTexture(size, gl::TextureFormat::RGBA, unit);
|
||||
gl::Renderbuffer<gl::RenderbufferType::DepthComponent> depthTarget = context.createRenderbuffer<gl::RenderbufferType::DepthComponent>(size);
|
||||
framebuffer = context.createFramebuffer(*texture, depthTarget);
|
||||
|
||||
} else {
|
||||
context.bindFramebuffer = framebuffer->framebuffer;
|
||||
}
|
||||
|
||||
context.activeTexture = unit;
|
||||
context.viewport = { 0, 0, size };
|
||||
}
|
||||
|
||||
private:
|
||||
gl::Context& context;
|
||||
const Size size;
|
||||
OffscreenTextureAttachment type;
|
||||
optional<gl::Framebuffer> framebuffer;
|
||||
optional<gl::Texture> texture;
|
||||
};
|
||||
|
||||
OffscreenTexture::OffscreenTexture(gl::Context& context, const Size size)
|
||||
: impl(std::make_unique<Impl>(context, std::move(size))) {
|
||||
OffscreenTexture::OffscreenTexture(gl::Context& context,
|
||||
const Size size,
|
||||
OffscreenTextureAttachment type)
|
||||
: impl(std::make_unique<Impl>(context, std::move(size), type)) {
|
||||
assert(!size.isEmpty());
|
||||
}
|
||||
|
||||
@@ -81,8 +82,4 @@ const Size& OffscreenTexture::getSize() const {
|
||||
return impl->getSize();
|
||||
}
|
||||
|
||||
void OffscreenTexture::bindRenderbuffers(gl::TextureUnit unit) {
|
||||
impl->bindRenderbuffers(unit);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -10,13 +10,21 @@ class Context;
|
||||
class Texture;
|
||||
} // namespace gl
|
||||
|
||||
enum class OffscreenTextureAttachment {
|
||||
None,
|
||||
Depth,
|
||||
};
|
||||
|
||||
class OffscreenTexture : public View {
|
||||
public:
|
||||
OffscreenTexture(gl::Context&, Size size = { 256, 256 });
|
||||
OffscreenTexture(gl::Context&,
|
||||
Size size = { 256, 256 },
|
||||
OffscreenTextureAttachment type = OffscreenTextureAttachment::None);
|
||||
~OffscreenTexture();
|
||||
OffscreenTexture(OffscreenTexture&&);
|
||||
OffscreenTexture& operator=(OffscreenTexture&&);
|
||||
|
||||
void bind() override;
|
||||
void bindRenderbuffers(gl::TextureUnit unit = 0);
|
||||
|
||||
PremultipliedImage readStillImage();
|
||||
|
||||
@@ -26,7 +34,7 @@ public:
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
const std::unique_ptr<Impl> impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
Reference in New Issue
Block a user