[core] Reuse fill-extrusion textures between frames (#8896)

This commit is contained in:
Lauren Budorick
2017-05-08 09:06:07 -07:00
committed by GitHub
parent b622aed349
commit 1c9af3226f
5 changed files with 44 additions and 37 deletions

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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

View File

@@ -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