Raster layer (Tiles) #1168 (#1195)

Co-authored-by: Bart Louwers <bart@emeel.net>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Tim Sylvester <tim@wetdogweather.com>
Co-authored-by: Alex Cristici <alex.cristici@gmail.com>
This commit is contained in:
Stefan Karschti
2023-06-06 18:28:25 +03:00
committed by Bart Louwers
parent 326f669568
commit 7f33ddfef4
19 changed files with 588 additions and 3 deletions

View File

@@ -530,6 +530,8 @@ list(APPEND SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/circle_layer_tweaker.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/fill_layer_tweaker.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/fill_layer_tweaker.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/raster_layer_tweaker.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/raster_layer_tweaker.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_background_layer.cpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_background_layer.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_circle_layer.cpp
@@ -946,6 +948,7 @@ if(MLN_WITH_OPENGL)
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_pattern.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_raster.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background_pattern.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/circle.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/clipping_mask.hpp

View File

@@ -60,6 +60,8 @@ protected:
DrawableGL(std::unique_ptr<Impl>);
private:
void uploadTextures() const;
void bindUniformBuffers() const;
void unbindUniformBuffers() const;

View File

@@ -0,0 +1,107 @@
// Generated code, do not modify this file!
#pragma once
#include <mbgl/shaders/shader_source.hpp>
namespace mbgl {
namespace shaders {
template <>
struct ShaderSource<BuiltIn::RasterShader, gfx::Backend::Type::OpenGL> {
static constexpr const char* name = "RasterShader";
static constexpr const char* vertex = R"(layout (std140) uniform RasterDrawableUBO {
highp mat4 u_matrix;
highp vec3 u_spin_weights;
highp vec2 u_tl_parent;
highp float u_scale_parent;
highp float u_buffer_scale;
highp float u_fade_t;
highp float u_opacity;
highp float u_brightness_low;
highp float u_brightness_high;
highp float u_saturation_factor;
highp float u_contrast_factor;
highp float pad1;
highp float pad2;
};
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec2 a_texture_pos;
out vec2 v_pos0;
out vec2 v_pos1;
void main() {
gl_Position = u_matrix * vec4(a_pos, 0, 1);
// We are using Int16 for texture position coordinates to give us enough precision for
// fractional coordinates. We use 8192 to scale the texture coordinates in the buffer
// as an arbitrarily high number to preserve adequate precision when rendering.
// This is also the same value as the EXTENT we are using for our tile buffer pos coordinates,
// so math for modifying either is consistent.
v_pos0 = (((a_texture_pos / 8192.0) - 0.5) / u_buffer_scale ) + 0.5;
v_pos1 = (v_pos0 * u_scale_parent) + u_tl_parent;
}
)";
static constexpr const char* fragment = R"(layout (std140) uniform RasterDrawableUBO {
highp mat4 u_matrix;
highp vec3 u_spin_weights;
highp vec2 u_tl_parent;
highp float u_scale_parent;
highp float u_buffer_scale;
highp float u_fade_t;
highp float u_opacity;
highp float u_brightness_low;
highp float u_brightness_high;
highp float u_saturation_factor;
highp float u_contrast_factor;
highp float pad1;
highp float pad2;
};
uniform sampler2D u_image0;
uniform sampler2D u_image1;
in vec2 v_pos0;
in vec2 v_pos1;
void main() {
// read and cross-fade colors from the main and parent tiles
vec4 color0 = texture(u_image0, v_pos0);
vec4 color1 = texture(u_image1, v_pos1);
if (color0.a > 0.0) {
color0.rgb = color0.rgb / color0.a;
}
if (color1.a > 0.0) {
color1.rgb = color1.rgb / color1.a;
}
vec4 color = mix(color0, color1, u_fade_t);
color.a *= u_opacity;
vec3 rgb = color.rgb;
// spin
rgb = vec3(
dot(rgb, u_spin_weights.xyz),
dot(rgb, u_spin_weights.zxy),
dot(rgb, u_spin_weights.yzx));
// saturation
float average = (color.r + color.g + color.b) / 3.0;
rgb += (average - rgb) * u_saturation_factor;
// contrast
rgb = (rgb - 0.5) * u_contrast_factor + 0.5;
// brightness
vec3 u_high_vec = vec3(u_brightness_low, u_brightness_low, u_brightness_low);
vec3 u_low_vec = vec3(u_brightness_high, u_brightness_high, u_brightness_high);
fragColor = vec4(mix(u_high_vec, u_low_vec, rgb) * color.a, color.a);
#ifdef OVERDRAW_INSPECTOR
fragColor = vec4(1.0);
#endif
}
)";
};
} // namespace shaders
} // namespace mbgl

View File

@@ -28,6 +28,8 @@ public:
const std::string& fragmentSource,
const std::string& additionalDefines = "") noexcept(false);
std::optional<uint32_t> getSamplerLocation(const std::string& name) const override;
const gfx::UniformBlockArray& getUniformBlocks() const override { return uniformBlocks; }
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }

View File

@@ -10,6 +10,7 @@
#include <mbgl/shaders/gl/drawable_fill_outline.hpp>
#include <mbgl/shaders/gl/drawable_fill_pattern.hpp>
#include <mbgl/shaders/gl/drawable_fill_outline_pattern.hpp>
#include <mbgl/shaders/gl/drawable_raster.hpp>
#include <mbgl/shaders/gl/prelude.hpp>
#include <mbgl/shaders/gl/background.hpp>
#include <mbgl/shaders/gl/background_pattern.hpp>

View File

@@ -6,6 +6,7 @@
#include <mbgl/util/identity.hpp>
#include <string>
#include <optional>
namespace mbgl {
namespace gfx {
@@ -29,6 +30,10 @@ protected:
public:
const util::SimpleIdentity& getID() const { return shaderProgramID; }
/// @brief Gets the sampler location
/// @param name uniform name
virtual std::optional<uint32_t> getSamplerLocation(const std::string& name) const = 0;
/// Get the available uniform blocks attached to this shader
virtual const gfx::UniformBlockArray& getUniformBlocks() const = 0;

View File

@@ -16,6 +16,7 @@ enum class BuiltIn {
FillOutlineShader,
FillPatternShader,
FillOutlinePatternShader,
RasterShader,
Prelude,
BackgroundProgram,
BackgroundPatternProgram,

View File

@@ -0,0 +1,59 @@
layout (std140) uniform RasterDrawableUBO {
highp mat4 u_matrix;
highp vec3 u_spin_weights;
highp vec2 u_tl_parent;
highp float u_scale_parent;
highp float u_buffer_scale;
highp float u_fade_t;
highp float u_opacity;
highp float u_brightness_low;
highp float u_brightness_high;
highp float u_saturation_factor;
highp float u_contrast_factor;
highp float pad1;
highp float pad2;
};
uniform sampler2D u_image0;
uniform sampler2D u_image1;
in vec2 v_pos0;
in vec2 v_pos1;
void main() {
// read and cross-fade colors from the main and parent tiles
vec4 color0 = texture(u_image0, v_pos0);
vec4 color1 = texture(u_image1, v_pos1);
if (color0.a > 0.0) {
color0.rgb = color0.rgb / color0.a;
}
if (color1.a > 0.0) {
color1.rgb = color1.rgb / color1.a;
}
vec4 color = mix(color0, color1, u_fade_t);
color.a *= u_opacity;
vec3 rgb = color.rgb;
// spin
rgb = vec3(
dot(rgb, u_spin_weights.xyz),
dot(rgb, u_spin_weights.zxy),
dot(rgb, u_spin_weights.yzx));
// saturation
float average = (color.r + color.g + color.b) / 3.0;
rgb += (average - rgb) * u_saturation_factor;
// contrast
rgb = (rgb - 0.5) * u_contrast_factor + 0.5;
// brightness
vec3 u_high_vec = vec3(u_brightness_low, u_brightness_low, u_brightness_low);
vec3 u_low_vec = vec3(u_brightness_high, u_brightness_high, u_brightness_high);
fragColor = vec4(mix(u_high_vec, u_low_vec, rgb) * color.a, color.a);
#ifdef OVERDRAW_INSPECTOR
fragColor = vec4(1.0);
#endif
}

View File

@@ -0,0 +1,32 @@
layout (std140) uniform RasterDrawableUBO {
highp mat4 u_matrix;
highp vec3 u_spin_weights;
highp vec2 u_tl_parent;
highp float u_scale_parent;
highp float u_buffer_scale;
highp float u_fade_t;
highp float u_opacity;
highp float u_brightness_low;
highp float u_brightness_high;
highp float u_saturation_factor;
highp float u_contrast_factor;
highp float pad1;
highp float pad2;
};
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec2 a_texture_pos;
out vec2 v_pos0;
out vec2 v_pos1;
void main() {
gl_Position = u_matrix * vec4(a_pos, 0, 1);
// We are using Int16 for texture position coordinates to give us enough precision for
// fractional coordinates. We use 8192 to scale the texture coordinates in the buffer
// as an arbitrarily high number to preserve adequate precision when rendering.
// This is also the same value as the EXTENT we are using for our tile buffer pos coordinates,
// so math for modifying either is consistent.
v_pos0 = (((a_texture_pos / 8192.0) - 0.5) / u_buffer_scale ) + 0.5;
v_pos1 = (v_pos0 * u_scale_parent) + u_tl_parent;
}

View File

@@ -48,6 +48,13 @@
"glsl_frag": "drawable.fill_outline_pattern.fragment.glsl",
"uses_ubos": true
},
{
"name": "RasterShader",
"header": "drawable_raster",
"glsl_vert": "drawable.raster.vertex.glsl",
"glsl_frag": "drawable.raster.fragment.glsl",
"uses_ubos": true
},
{
"name": "Prelude",

View File

@@ -178,6 +178,19 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
glSeg.setVertexArray(std::move(vertexArray));
};
}
const bool texturesNeedUpload = std::any_of(
textures.begin(), textures.end(), [](const auto& tex) { return tex.texture->needsUpload(); });
if (texturesNeedUpload) {
uploadTextures();
}
}
void DrawableGL::uploadTextures() const {
for (const auto& tex : textures) {
std::static_pointer_cast<gl::Texture2D>(tex.texture)->upload();
}
}
void DrawableGL::bindTextures() const {

View File

@@ -99,7 +99,8 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar
shaders::BuiltIn::FillShader,
shaders::BuiltIn::FillOutlineShader,
shaders::BuiltIn::FillOutlinePatternShader,
shaders::BuiltIn::FillPatternShader>(shaders, static_cast<gl::Context&>(*context), programParameters);
shaders::BuiltIn::FillPatternShader,
shaders::BuiltIn::RasterShader>(shaders, static_cast<gl::Context&>(*context), programParameters);
}
} // namespace gl

View File

@@ -148,6 +148,7 @@ void Texture2D::bind(int32_t location, int32_t textureUnit) noexcept {
// Link the bound texture unit with the requested sampler in the active shader
glUniform1i(location, textureUnit);
boundLocation = location;
}
void Texture2D::unbind() noexcept {

View File

@@ -0,0 +1,86 @@
#include <mbgl/renderer/layers/raster_layer_tweaker.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/style/layers/raster_layer_properties.hpp>
#include <mbgl/util/convert.hpp>
namespace mbgl {
using namespace style;
struct alignas(16) RasterDrawableUBO {
std::array<float, 4 * 4> matrix;
std::array<float, 4> spin_weights;
std::array<float, 2> tl_parent;
float scale_parent;
float buffer_scale;
float fade_t;
float opacity;
float brightness_low;
float brightness_high;
float saturation_factor;
float contrast_factor;
float pad1;
float pad2;
};
static_assert(sizeof(RasterDrawableUBO) == 128);
static_assert(sizeof(RasterDrawableUBO) % 16 == 0);
void RasterLayerTweaker::execute([[maybe_unused]] LayerGroup& layerGroup,
[[maybe_unused]] const RenderTree& renderTree,
[[maybe_unused]] const PaintParameters& parameters) {
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
if (!drawable.getTileID()) {
return;
}
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
const auto matrix = parameters.matrixForTile(tileID, !parameters.state.isChanging());
auto spinWeights = [](float spin) -> std::array<float, 4> {
spin = util::deg2radf(spin);
float s = std::sin(spin);
float c = std::cos(spin);
std::array<float, 4> spin_weights = {
{(2 * c + 1) / 3, (-std::sqrt(3.0f) * s - c + 1) / 3, (std::sqrt(3.0f) * s - c + 1) / 3, 0}};
return spin_weights;
};
auto saturationFactor = [](float saturation) -> float {
if (saturation > 0) {
return 1.f - 1.f / (1.001f - saturation);
} else {
return -saturation;
}
};
auto contrastFactor = [](float contrast) -> float {
if (contrast > 0) {
return 1 / (1 - contrast);
} else {
return 1 + contrast;
}
};
RasterDrawableUBO drawableUBO{/*.matrix = */ util::cast<float>(matrix),
/*.spin_weigths = */ spinWeights(evaluated.get<RasterHueRotate>()),
/*.tl_parent = */ {{0.0f, 0.0f}},
/*.scale_parent = */ 1.0f,
/*.buffer_scale = */ 1.0f,
/*.fade_t = */ 1.0f,
/*.opacity = */ evaluated.get<RasterOpacity>(),
/*.brightness_low = */ evaluated.get<RasterBrightnessMin>(),
/*.brightness_high = */ evaluated.get<RasterBrightnessMax>(),
/*.saturation_factor = */ saturationFactor(evaluated.get<RasterSaturation>()),
/*.contrast_factor = */ contrastFactor(evaluated.get<RasterContrast>()),
0,
0};
auto drawableUniformBuffer = parameters.context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
drawable.mutableUniformBuffers().addOrReplace("RasterDrawableUBO", drawableUniformBuffer);
});
}
} // namespace mbgl

View File

@@ -0,0 +1,29 @@
#pragma once
#include <mbgl/renderer/layer_tweaker.hpp>
namespace mbgl {
namespace gfx {
class UniformBuffer;
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
} // namespace gfx
/**
Raster layer tweaker
*/
class RasterLayerTweaker : public LayerTweaker {
public:
RasterLayerTweaker(Immutable<style::LayerProperties> properties)
: LayerTweaker(properties){};
public:
~RasterLayerTweaker() override = default;
void execute(LayerGroup&, const RenderTree&, const PaintParameters&) override;
protected:
gfx::UniformBufferPtr evaluatedPropsUniformBuffer = nullptr;
};
} // namespace mbgl

View File

@@ -1,5 +1,7 @@
#include <mbgl/renderer/layers/render_raster_layer.hpp>
#include <mbgl/renderer/layers/raster_layer_tweaker.hpp>
#include <mbgl/renderer/buckets/raster_bucket.hpp>
#include <mbgl/renderer/layer_group.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_static_data.hpp>
@@ -7,9 +9,12 @@
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/raster_program.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/gfx/drawable_builder.hpp>
#include <mbgl/gfx/cull_face_mode.hpp>
#include <mbgl/math/angles.hpp>
#include <mbgl/style/layers/raster_layer_impl.hpp>
#include <mbgl/shaders/shader_program_base.hpp>
namespace mbgl {
@@ -40,6 +45,10 @@ void RenderRasterLayer::evaluate(const PropertyEvaluationParameters& parameters)
passes = properties->evaluated.get<style::RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
properties->renderPasses = mbgl::underlying_type(passes);
evaluatedProperties = std::move(properties);
if (tileLayerGroup && tileLayerGroup->getLayerTweaker()) {
tileLayerGroup->setLayerTweaker(std::make_shared<RasterLayerTweaker>(evaluatedProperties));
}
}
bool RenderRasterLayer::hasTransition() const {
@@ -197,4 +206,211 @@ void RenderRasterLayer::render(PaintParameters& parameters) {
}
}
void RenderRasterLayer::layerRemoved(UniqueChangeRequestVec& changes) {
// Remove everything
if (tileLayerGroup) {
changes.emplace_back(std::make_unique<RemoveLayerGroupRequest>(tileLayerGroup->getLayerIndex()));
tileLayerGroup.reset();
}
}
void RenderRasterLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
stats.tileDrawablesRemoved += tileLayerGroup->removeDrawables(renderPass, tileID).size();
}
void RenderRasterLayer::update(gfx::ShaderRegistry& shaders,
gfx::Context& context,
const TransformState& /*state*/,
[[maybe_unused]] const RenderTree& renderTree,
[[maybe_unused]] UniqueChangeRequestVec& changes) {
std::unique_lock<std::mutex> guard(mutex);
if ((!renderTiles || renderTiles->empty()) && !imageData) {
if (tileLayerGroup) {
stats.tileDrawablesRemoved += tileLayerGroup->getDrawableCount();
tileLayerGroup->clearDrawables();
}
return;
}
// Set up a layer group
if (!tileLayerGroup) {
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64);
if (!tileLayerGroup) {
return;
}
tileLayerGroup->setLayerTweaker(std::make_shared<RasterLayerTweaker>(evaluatedProperties));
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
}
auto renderPass = RenderPass::Translucent;
if (!rasterShader) {
rasterShader = context.getGenericShader(shaders, "RasterShader");
}
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
RasterProgram::Binders paintAttributeData{evaluated, 0};
const gfx::TextureFilterType filter = evaluated.get<RasterResampling>() == RasterResamplingType::Nearest
? gfx::TextureFilterType::Nearest
: gfx::TextureFilterType::Linear;
(void)filter;
if (imageData && !imageData->bucket->needsUpload()) {
// TODO: implement arbitrary image
RasterBucket& bucket = *imageData->bucket;
assert(bucket.texture);
// size_t i = 0;
for (const auto& matrix_ : imageData->matrices) {
/*draw(matrix_,
*bucket.vertexBuffer,
*bucket.indexBuffer,
bucket.segments,
RasterProgram::TextureBindings{
textures::image0::Value{bucket.texture->getResource(), filter},
textures::image1::Value{bucket.texture->getResource(), filter},
},
std::to_string(i++));*/
(void)matrix_;
}
} else if (renderTiles) {
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
// Has this tile dropped out of the cover set?
if (const auto it = std::find_if(renderTiles->begin(),
renderTiles->end(),
[&drawable](const auto& renderTile) {
return drawable->getTileID() == renderTile.get().getOverscaledTileID();
});
it == renderTiles->end()) {
// remove it
drawable.reset();
++stats.tileDrawablesRemoved;
}
});
for (const RenderTile& tile : *renderTiles) {
const auto& tileID = tile.getOverscaledTileID();
auto* bucket_ = tile.getBucket(*baseImpl);
if (!bucket_) {
continue;
}
auto& bucket = static_cast<RasterBucket&>(*bucket_);
if (!bucket.hasData()) continue;
if (tileLayerGroup->getDrawableCount(renderPass, tileID) > 0) continue;
if (bucket.image) {
std::unique_ptr<gfx::DrawableBuilder> builder{context.createDrawableBuilder("raster")};
builder->setShader(rasterShader);
builder->setRenderPass(renderPass);
builder->setColorAttrMode(gfx::DrawableBuilder::ColorAttrMode::None);
builder->setSubLayerIndex(0);
builder->setDepthType((renderPass == RenderPass::Opaque) ? gfx::DepthMaskType::ReadWrite
: gfx::DepthMaskType::ReadOnly);
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
builder->setVertexAttrName("a_pos");
// render data
auto buildRenderData = [](const TileMask& mask,
std::vector<std::array<int16_t, 2>>& vertices,
std::vector<std::array<int16_t, 2>>& attributes,
std::vector<uint16_t>& indices,
std::vector<Segment<void>>& segments) {
constexpr const uint16_t vertexLength = 4;
// Create the vertex buffer for the specified tile mask.
for (const auto& id : mask) {
// Create a quad for every masked tile.
const int32_t vertexExtent = util::EXTENT >> id.z;
const Point<int16_t> tlVertex = {static_cast<int16_t>(id.x * vertexExtent),
static_cast<int16_t>(id.y * vertexExtent)};
const Point<int16_t> brVertex = {static_cast<int16_t>(tlVertex.x + vertexExtent),
static_cast<int16_t>(tlVertex.y + vertexExtent)};
if (segments.empty() ||
(segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max())) {
// Move to a new segments because the old one can't hold the geometry.
segments.emplace_back(vertices.size(), indices.size());
}
vertices.emplace_back(std::array<int16_t, 2>{{tlVertex.x, tlVertex.y}});
attributes.emplace_back(std::array<int16_t, 2>{{tlVertex.x, tlVertex.y}});
vertices.emplace_back(std::array<int16_t, 2>{{brVertex.x, tlVertex.y}});
attributes.emplace_back(std::array<int16_t, 2>{{brVertex.x, tlVertex.y}});
vertices.emplace_back(std::array<int16_t, 2>{{tlVertex.x, brVertex.y}});
attributes.emplace_back(std::array<int16_t, 2>{{tlVertex.x, brVertex.y}});
vertices.emplace_back(std::array<int16_t, 2>{{brVertex.x, brVertex.y}});
attributes.emplace_back(std::array<int16_t, 2>{{brVertex.x, brVertex.y}});
auto& segment = segments.back();
assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max());
const auto offset = static_cast<uint16_t>(segment.vertexLength);
// 0, 1, 2
// 1, 2, 3
indices.insert(indices.end(),
{offset, static_cast<uint16_t>(offset + 1), static_cast<uint16_t>(offset + 2u)});
indices.insert(indices.end(),
{static_cast<uint16_t>(offset + 1),
static_cast<uint16_t>(offset + 2),
static_cast<uint16_t>(offset + 3)});
segment.vertexLength += vertexLength;
segment.indexLength += 6;
}
};
std::vector<std::array<int16_t, 2>> vertices, attributes;
std::vector<uint16_t> indices;
std::vector<Segment<void>> segments;
buildRenderData(bucket.mask, vertices, attributes, indices, segments);
builder->addVertices(vertices, 0, vertices.size());
builder->setSegments(gfx::Triangles(), indices, segments);
// attributes
{
gfx::VertexAttributeArray vertexAttrs;
if (auto& attr = vertexAttrs.getOrAdd("a_texture_pos")) {
std::size_t index{0};
for (auto& a : attributes) {
attr->set<gfx::VertexAttribute::int2>(index++, {a[0], a[1]});
}
}
builder->setVertexAttributes(std::move(vertexAttrs));
}
// textures
// TODO: move texture creation into gfx::Context
std::shared_ptr<gfx::Texture2D> tex0 = context.createTexture2D();
tex0->setImage(bucket.image).create();
auto location0 = rasterShader->getSamplerLocation("u_image0");
if (location0.has_value()) {
builder->setTexture(tex0, location0.value());
}
std::shared_ptr<gfx::Texture2D> tex1 = context.createTexture2D();
tex1->setImage(bucket.image).create();
auto location1 = rasterShader->getSamplerLocation("u_image1");
if (location1.has_value()) {
builder->setTexture(tex1, location1.value());
}
// finish
builder->flush();
for (auto& drawable : builder->clearDrawables()) {
drawable->setTileID(tileID);
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
++stats.tileDrawablesAdded;
}
};
}
}
}
} // namespace mbgl

View File

@@ -14,6 +14,15 @@ public:
explicit RenderRasterLayer(Immutable<style::RasterLayer::Impl>);
~RenderRasterLayer() override;
void layerRemoved(UniqueChangeRequestVec&) override;
/// Generate any changes needed by the layer
void update(gfx::ShaderRegistry&,
gfx::Context&,
const TransformState&,
const RenderTree&,
UniqueChangeRequestVec&) override;
private:
void transition(const TransitionParameters&) override;
void evaluate(const PropertyEvaluationParameters&) override;
@@ -22,12 +31,17 @@ private:
void prepare(const LayerPrepareParameters&) override;
void render(PaintParameters&) override;
/// Remove all drawables for the tile from the layer group
void removeTile(RenderPass, const OverscaledTileID&);
// Paint properties
style::RasterPaintProperties::Unevaluated unevaluated;
const ImageSourceRenderData* imageData = nullptr;
// Programs
std::shared_ptr<RasterProgram> rasterProgram;
gfx::ShaderProgramBasePtr rasterShader;
};
} // namespace mbgl

View File

@@ -111,7 +111,8 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
});
// Give the layers a chance to do setup
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.preRender(orchestrator, parameters); });
// orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.preRender(orchestrator, parameters);
// });
// - UPLOAD PASS -------------------------------------------------------------------------------
// Uploads all required buffers and images before we do any actual rendering.
@@ -320,7 +321,7 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
}
#endif
// Give the layers a chance to do cleanup
// Give the layers a chance to do cleanup
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.postRender(orchestrator, parameters); });
// Ends the RenderPass

View File

@@ -111,6 +111,11 @@ static void addAttr(
}
}
std::optional<uint32_t> ShaderProgramGL::getSamplerLocation(const std::string& name) const {
GLint sampler_location = MBGL_CHECK_ERROR(glGetUniformLocation(glProgram, name.c_str()));
return (sampler_location == -1) ? std::optional<uint32_t>{} : sampler_location;
}
std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(Context& context,
const ProgramParameters& programParameters,
const std::string& /*name*/,