Drawable Renderer (#1570), Move layer update to where more state is available.

Evaluate properties and use actual style color.
Fix problems with attribute bindings and depth modes.
This commit is contained in:
Tim Sylvester
2023-04-27 14:25:43 -07:00
committed by Bart Louwers
parent 3122f81328
commit b8c0b1a97c
18 changed files with 224 additions and 102 deletions

View File

@@ -15,6 +15,8 @@ class PaintParameters;
namespace gfx {
enum class DepthMaskType : bool;
class DrawableTweaker;
class ShaderProgramBase;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
@@ -47,6 +49,9 @@ public:
mat4 getMatrix() const { return matrix; }
void setMatrix(mat4 value) { matrix = value; }
DepthMaskType getDepthType() const { return depthType; }
void setDepthType(DepthMaskType value) { depthType = value; }
/// Get the number of vertexes
std::size_t getVertexCount() const { return getVertexAttributes().getMaxCount(); }
@@ -72,6 +77,7 @@ protected:
mat4 matrix; //= matrix::identity4();
std::optional<OverscaledTileID> tileID;
DrawPriority drawPriority = 0;
DepthMaskType depthType;// = DepthMaskType::ReadOnly;
std::vector<DrawableTweakerPtr> tweakers;
};

View File

@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/gfx/types.hpp>
#include <mbgl/gfx/vertex_attribute.hpp>
#include <memory>
@@ -59,6 +60,9 @@ public:
const Color& getColor() const;
void setColor(const Color& value);
DepthMaskType getDepthType() const { return depthType; }
void setDepthType(DepthMaskType value) { depthType = value; }
/// Which shader to use when rendering emitted drawables
const gfx::ShaderProgramBasePtr& getShader() const { return shader; }
void setShader(gfx::ShaderProgramBasePtr value) { shader = std::move(value); }
@@ -88,14 +92,11 @@ protected:
protected:
DrawPriority drawPriority = 0;
DepthMaskType depthType = DepthMaskType::ReadOnly;
gfx::ShaderProgramBasePtr shader;
mat4 matrix;
DrawablePtr currentDrawable;
std::vector<DrawablePtr> drawables;
std::vector<DrawableTweakerPtr> tweakers;
struct Impl;

View File

@@ -11,6 +11,7 @@
namespace mbgl {
class PaintParameters;
class ProgramParameters;
namespace gfx {
@@ -90,7 +91,7 @@ public:
public:
/// Activate the shader, vertex attributes, etc., specified by the drawable
virtual bool setupDraw(const gfx::Drawable&) = 0;
virtual bool setupDraw(const PaintParameters&, const gfx::Drawable&) = 0;
};
} // namespace gfx

View File

@@ -1,11 +1,13 @@
#include <mbgl/gfx/drawable.hpp>
#include <mbgl/gfx/types.hpp>
#include <mbgl/util/mat4.hpp>
namespace mbgl {
namespace gfx {
Drawable::Drawable() :
matrix(matrix::identity4())
matrix(matrix::identity4()),
depthType(DepthMaskType::ReadOnly)
{
}

View File

@@ -28,6 +28,7 @@ void DrawableBuilder::flush() {
if (!impl->vertices.empty()) {
auto draw = getCurrentDrawable(/*createIfNone=*/true);
currentDrawable->setDrawPriority(drawPriority);
currentDrawable->setDepthType(depthType);
currentDrawable->setShader(shader);
currentDrawable->setMatrix(matrix);
currentDrawable->setVertexAttributes(getVertexAttributes());

View File

@@ -10,13 +10,12 @@
#include <mbgl/gl/command_encoder.hpp>
#include <mbgl/gl/debugging_extension.hpp>
#include <mbgl/gl/defines.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/util/traits.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/gl/index_buffer_resource.hpp>
#include <cstring>
#include <iterator>
@@ -449,7 +448,7 @@ void Context::setDirtyState() {
globalVertexArrayState.setDirty();
}
bool Context::setupDraw(const gfx::Drawable& drawable) {
bool Context::setupDraw(const PaintParameters& parameters, const gfx::Drawable& drawable) {
if (const auto &shader = drawable.getShader()) {
const auto& shaderGL = static_cast<const ShaderProgramGL&>(*shader);
if (shaderGL.getGLProgramID() != program.getCurrentValue()) {
@@ -459,7 +458,7 @@ bool Context::setupDraw(const gfx::Drawable& drawable) {
program = value::Program::Default;
}
//setDepthMode(...);
setDepthMode(parameters.depthModeForSublayer(0, drawable.getDepthType()));
setStencilMode(gfx::StencilMode::disabled());
setColorMode(gfx::ColorMode::alphaBlended());
setCullFaceMode(gfx::CullFaceMode::disabled());

View File

@@ -104,7 +104,7 @@ public:
void setCleanupOnDestruction(bool cleanup) { cleanupOnDestruction = cleanup; }
bool setupDraw(const gfx::Drawable&) override;
bool setupDraw(const PaintParameters&, const gfx::Drawable&) override;
private:
RendererBackend& backend;

View File

@@ -2,6 +2,7 @@
#include <mbgl/gfx/drawable_builder_impl.hpp>
#include <mbgl/gl/drawable_gl.hpp>
#include <mbgl/util/convert.hpp>
namespace mbgl {
namespace gl {
@@ -20,13 +21,22 @@ void DrawableGLBuilder::init() {
posAttr->set(index++, gfx::VertexAttribute::int2{vert.a1[0], vert.a1[1]});
}
}
if (auto colorAttr = attrs.getOrAdd("a_color")) {
std::size_t index = 0;
for (const auto& color : impl->colors) {
const auto comp = util::convert<float>(color.toArray());
const auto norm = gfx::VertexAttribute::float4{comp[0]/255.f,comp[1]/255.f,comp[2]/255.f,comp[3]};
colorAttr->set(index++, norm);
}
}
constexpr auto indexOffset = 0;
const auto indexCount = impl->indexes.elements();
drawableGL.setIndexData(impl->indexes.vector(), indexOffset, indexCount);
impl->indexes.clear();
impl->vertices.clear();
impl->colors.clear();
}
} // namespace gl

View File

@@ -70,40 +70,35 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) {
gl::Context& glContext = static_cast<gl::Context&>(*context);
// "layout (location = 0) in vec2 a_pos;\nuniform mat4 u_matrix;\n\nvoid main() {\n
// gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n", fragment = "uniform vec4 u_color;\nuniform float u_opacity;\n\nvoid main() {\n fragColor = u_color * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n fragColor = vec4(1.0);\n#endif\n}\n"
auto shader = shaders.get<gl::ShaderProgramGL>(shaderName);
if (!shader) {
constexpr auto vert = R"(#version 300 es
precision highp float;
layout (location = 0) in vec2 a_pos;
uniform mat4 u_matrix;
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec4 a_color;
out vec4 v_color;
void main() {
v_color = a_color;
gl_Position = u_matrix * vec4(a_pos, 0, 1);
})";
constexpr auto frag = R"(#version 300 es
precision highp float;
in vec4 pos;
out vec4 color;
in vec4 v_color;
out vec4 fragColor;
void main() {
color = vec4(0.5,0.0,0.0,0.5);
fragColor = v_color;
})";
try {
// Compile
shader = gl::ShaderProgramGL::create(glContext, shaderName, vert, frag);
if (shader) {
// Set uniforms
//shader->setUniform("a", 0, 3.21f);
//shader->setUniform("b", 0, 4.32f);
// Set default values
//shader->setAttribute("d", 0, 12.3f);
//shader->setAttribute("e", 0, 123);
//shader->setAttribute("f", 0, gfx::VertexAttribute::matf2{ 1.0f, 2.0f, 3.0f, 4.0f });
//shader->setAttribute("a_color", gfx::VertexAttribute::matf4{ 1.0f, 1.0f, 1.0f, 1.0f });
// Add to the registry
if (!shaders.registerShader(shader, shaderName)) {

View File

@@ -7,6 +7,7 @@
#include <mbgl/gl/vertex_buffer_resource.hpp>
#include <mbgl/gl/index_buffer_resource.hpp>
#include <mbgl/gl/texture_resource.hpp>
#include <mbgl/util/logging.hpp>
#include <algorithm>
@@ -138,7 +139,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer) {
AttributeBindingArray bindings;
bindings.reserve(defaults.size());
bindings.resize(defaults.size());
constexpr std::size_t align = 16;
constexpr std::uint8_t padding = 0;
@@ -147,41 +148,55 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
allData.reserve(defaults.getTotalSize() * vertexCount);
// For each attribute in the program, with the corresponding default and optional override...
defaults.resolve(overrides, [&](const std::string& /*name*/,
defaults.resolve(overrides, [&](const std::string& name,
const gfx::VertexAttribute& defaultAttr,
const gfx::VertexAttribute* overrideAttr)->void {
const auto& effectiveAttr = overrideAttr ? *overrideAttr : defaultAttr;
const auto& effectiveGL = static_cast<const gl::VertexAttributeGL&>(effectiveAttr);
const auto& defaultGL = static_cast<const gl::VertexAttributeGL&>(defaultAttr);
const auto stride = defaultAttr.getStride();
const auto offset = static_cast<uint8_t>(allData.size());
bindings.emplace_back(gfx::AttributeBinding{
/*.attribute = */ gfx::AttributeDescriptor{ defaultAttr.getDataType(), offset },
/*.vertexStride = */ static_cast<uint8_t>(defaultAttr.getStride()),
/*.vertexBufferResource = */nullptr, // buffer pointer established later
/*.vertexOffset = */ static_cast<uint32_t>(defaultGL.getIndex())
});
// Get the raw data for the values in the desired format
const auto& rawData = effectiveGL.getRaw(defaultGL.getGLType());
if (rawData.size() == defaultAttr.getStride()) {
if (rawData.size() == stride * vertexCount) {
// The override provided a value for each vertex, append it as-is
allData.insert(allData.end(), rawData.begin(), rawData.end());
} else if (rawData.size() == stride) {
// We only have one value, append a copy for each vertex
for (std::size_t i = 0; i < vertexCount; ++i) {
allData.insert(allData.begin(), rawData.begin(), rawData.end());
allData.insert(allData.end(), rawData.begin(), rawData.end());
}
} else if (rawData.size() == defaultAttr.getStride() * vertexCount) {
allData.insert(allData.begin(), rawData.begin(), rawData.end());
} else {
// TODO: log? throw?
allData.insert(allData.begin(), defaultAttr.getStride() * vertexCount, 0);
// something else, the binding is invalid
// TODO: throw?
Log::Warning(Event::General,
"Got " + util::toString(rawData.size()) + " bytes for attribute '" + name +
"' (" + util::toString(defaultGL.getIndex()) + "), expected " +
util::toString(stride) + " or " + util::toString(stride * vertexCount));
return;
}
bindings[defaultGL.getIndex()] = {
/*.attribute = */ { defaultAttr.getDataType(), offset },
/*.vertexStride = */ static_cast<uint8_t>(stride),
/*.vertexBufferResource = */nullptr, // buffer pointer established later
/*.vertexOffset = */ 0,
};
pad(allData, align, padding);
});
auto vertBuf = createVertexBufferResource(&allData[0], allData.size(), usage);
auto vertBuf = createVertexBufferResource(allData.data(), allData.size(), usage);
// Assign to each element
std::for_each(bindings.begin(), bindings.end(), [&](auto& b){ b->vertexBufferResource = vertBuf.get(); });
// Go back and fill in the newly-allocated buffer in each binding that was generated
std::for_each(bindings.begin(), bindings.end(), [&](auto& b) {
if (b) {
b->vertexBufferResource = vertBuf.get();
}
});
outBuffer = std::move(vertBuf);
return bindings;

View File

@@ -770,18 +770,20 @@ void RenderOrchestrator::removeDrawable(const util::SimpleIdentity& drawableId)
drawables.erase(drawableId);
}
void RenderOrchestrator::updateLayers(PaintParameters& parameters) {
void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders,
const TransformState& state,
const PropertyEvaluationParameters& evalParameters) {
std::vector<std::unique_ptr<ChangeRequest>> changes;
for (auto& kv : layersRemoved) {
kv.second->layerRemoved(parameters, changes);
kv.second->layerRemoved(changes);
}
for (auto& kv : layersAdded) {
kv.second->layerAdded(parameters, changes);
kv.second->layerAdded(shaders, state, evalParameters, changes);
}
for (auto& impl : *layerImpls) {
impl->update(parameters, changes);
impl->update(state, evalParameters, changes);
}
addChanges(changes);

View File

@@ -36,6 +36,8 @@ class RenderTree;
namespace gfx {
class Drawable;
class ShaderRegistry;
using DrawablePtr = std::shared_ptr<Drawable>;
} // namespace gfx
@@ -97,10 +99,14 @@ public:
void addDrawable(gfx::DrawablePtr);
void removeDrawable(const util::SimpleIdentity& drawableId);
void updateLayers(PaintParameters&);
void updateLayers(gfx::ShaderRegistry&,
const TransformState&,
const PropertyEvaluationParameters&);
void processChanges();
const ZoomHistory& getZoomHistory() const { return zoomHistory; }
private:
bool isLoaded() const;
bool hasTransitions(TimePoint) const;

View File

@@ -2,7 +2,9 @@
#include <mbgl/layermanager/layer_manager.hpp>
#include <mbgl/renderer/renderer_impl.hpp>
#include <mbgl/renderer/render_static_data.hpp>
#include <mbgl/renderer/render_tree.hpp>
#include <mbgl/renderer/update_parameters.hpp>
#include <mbgl/gfx/backend_scope.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
@@ -29,6 +31,24 @@ void Renderer::render(const std::shared_ptr<UpdateParameters>& updateParameters)
assert(updateParameters);
if (auto renderTree = impl->orchestrator.createRenderTree(updateParameters)) {
renderTree->prepare();
const bool isMapModeContinuous = updateParameters->mode == MapMode::Continuous;
const auto transitionOptions = isMapModeContinuous ? updateParameters->transitionOptions : style::TransitionOptions();
//const TransitionParameters transitionParameters{updateParameters->timePoint, transitionOptions};
const auto defDuration = isMapModeContinuous ? util::DEFAULT_TRANSITION_DURATION : Duration::zero();
const PropertyEvaluationParameters evalParameters {
impl->orchestrator.getZoomHistory(),
updateParameters->timePoint,
transitionOptions.duration.value_or(defDuration),
};
const auto& renderTreeParameters = renderTree->getParameters();
const auto& state = renderTreeParameters.transformParams.state;
if (impl->staticData && impl->staticData->shaders) {
impl->orchestrator.updateLayers(*impl->staticData->shaders, state, evalParameters);
}
impl->render(*renderTree);
}
}

View File

@@ -81,8 +81,6 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
renderTree.getLineAtlas(),
renderTree.getPatternAtlas()};
orchestrator.updateLayers(parameters);
parameters.symbolFadeChange = renderTreeParameters.symbolFadeChange;
parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
const auto& sourceRenderItems = renderTree.getSourceRenderItems();
@@ -195,6 +193,39 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
"main buffer", {parameters.backend.getDefaultRenderable(), color, 1.0f, 0});
}
// Draw Drawables
{
// TODO: figure out how to make drawables participate in the depth system
// Maybe make it a function mapping draw priority to the depth range (always (0,1)?)
parameters.pass = RenderPass::Opaque;
parameters.currentLayer = parameters.opaquePassCutoff;
parameters.depthRangeSize = 1 - (1 + 2) * parameters.numSublayers * parameters.depthEpsilon;
const auto debugGroup(parameters.renderPass->createDebugGroup("drawables"));
for (const auto &pair : orchestrator.getDrawables()) {
const auto& drawable = *pair.second;
if (!context.setupDraw(parameters, drawable)) {
continue;
}
mat4 matrix = drawable.getMatrix();
if (drawable.getTileID()) {
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
const auto tileMat = parameters.matrixForTile(tileID);
matrix::multiply(matrix, drawable.getMatrix(), tileMat);
matrix = tileMat;
}
if (auto& shader = drawable.getShader()) {
shader->setUniform("u_matrix", 0, util::convert<float>(matrix));
shader->updateUniforms();
}
drawable.draw(parameters);
}
}
// Actually render the layers
parameters.depthRangeSize = 1 - (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon;
@@ -210,6 +241,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
for (auto it = layerRenderItems.rbegin(); it != layerRenderItems.rend(); ++it, ++i) {
parameters.currentLayer = i;
const RenderItem& renderItem = it->get();
if (renderItem.getName() == "background") { // Replaced by drawables, above
continue;
}
if (renderItem.hasRenderPass(parameters.pass)) {
const auto layerDebugGroup(parameters.renderPass->createDebugGroup(renderItem.getName().c_str()));
renderItem.render(parameters);
@@ -234,32 +268,6 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
}
}
// Draw Drawables
{
for (const auto &pair : orchestrator.getDrawables()) {
const auto& drawable = *pair.second;
if (!context.setupDraw(drawable)) {
continue;
}
mat4 matrix = drawable.getMatrix();
if (drawable.getTileID()) {
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
const auto tileMat = parameters.matrixForTile(tileID);
matrix::multiply(matrix, drawable.getMatrix(), tileMat);
matrix = tileMat;
}
if (auto& shader = drawable.getShader()) {
shader->setUniform("u_matrix", 0, util::convert<float>(matrix));
shader->updateUniforms();
}
drawable.draw(parameters);
}
}
// - DEBUG PASS --------------------------------------------------------------------------------
// Renders debug overlays.
{

View File

@@ -103,7 +103,7 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(
std::string_view vertexSource,
std::string_view fragmentSource) noexcept(false) {
const auto firstAttrib = "pos";
const auto firstAttrib = "a_pos";
// throws on compile error
auto vertProg = context.createShader(ShaderType::Vertex, std::initializer_list<const char*>{vertexSource.data()});

View File

@@ -16,10 +16,16 @@ namespace mbgl {
class ChangeRequest;
class PaintParameters;
class PropertyEvaluationParameters;
class TransformState;
using UniqueChangeRequest = std::unique_ptr<ChangeRequest>;
using UniqueChangeRequestVec = std::vector<UniqueChangeRequest>;
namespace gfx {
class ShaderRegistry;
} // namespace gfx
namespace style {
/**
@@ -56,10 +62,15 @@ public:
virtual void populateFontStack(std::set<FontStack>& fontStack) const;
/// Generate any changes needed by the layer
virtual void update(PaintParameters&, UniqueChangeRequestVec&) const { }
virtual void update(const TransformState&,
const PropertyEvaluationParameters&,
UniqueChangeRequestVec&) const { }
virtual void layerAdded(PaintParameters&, UniqueChangeRequestVec&) const { }
virtual void layerRemoved(PaintParameters&, UniqueChangeRequestVec&) const { }
virtual void layerAdded(gfx::ShaderRegistry&,
const TransformState&,
const PropertyEvaluationParameters&,
UniqueChangeRequestVec&) const { }
virtual void layerRemoved(UniqueChangeRequestVec&) const { }
std::string id;
std::string source;

View File

@@ -7,6 +7,7 @@
#include <mbgl/renderer/change_request.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/style/layer_properties.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/tile_cover.hpp>
@@ -29,19 +30,22 @@ bool BackgroundLayer::Impl::hasLayoutDifference(const Layer::Impl&) const {
constexpr auto shaderName = "background_generic";
void BackgroundLayer::Impl::layerAdded(PaintParameters& parameters, UniqueChangeRequestVec& changes) const {
void BackgroundLayer::Impl::layerAdded(gfx::ShaderRegistry& shaders,
const TransformState& state,
const PropertyEvaluationParameters& evalParameters,
UniqueChangeRequestVec& changes) const {
{
std::unique_lock<std::mutex> guard(mutex);
if (!shader) {
shader = parameters.shaders.get<gl::ShaderProgramGL>(shaderName);
shader = shaders.get<gl::ShaderProgramGL>(shaderName);
}
}
// Add all the tiles
update(parameters, changes);
update(state, evalParameters, changes);
}
void BackgroundLayer::Impl::layerRemoved(PaintParameters&, UniqueChangeRequestVec& changes) const {
void BackgroundLayer::Impl::layerRemoved(UniqueChangeRequestVec& changes) const {
// Remove everything
decltype(tileDrawables) localDrawables;
{
@@ -55,20 +59,43 @@ void BackgroundLayer::Impl::layerRemoved(PaintParameters&, UniqueChangeRequestVe
}
}
void BackgroundLayer::Impl::update(PaintParameters& parameters, UniqueChangeRequestVec& changes) const {
void BackgroundLayer::Impl::update(const TransformState& state,
const PropertyEvaluationParameters& evalParameters,
UniqueChangeRequestVec& changes) const {
std::unique_lock<std::mutex> guard(mutex);
std::unique_ptr<gfx::DrawableBuilder> builder = std::make_unique<gl::DrawableGLBuilder>(); // from GL-specific code via virtual method on ...Context?
builder->setShader(shader);
builder->addTweaker(std::make_shared<gl::DrawableGLTweaker>()); // generally shared across drawables
const auto uneval = paint.untransitioned();
const auto eval = uneval.evaluate(evalParameters);
const auto zoom = parameters.state.getIntegerZoom();
const auto tileCover = util::tileCover(parameters.state, zoom);
//const auto passes = eval.get<style::BackgroundOpacity>() == 0.0f
// ? RenderPass::None
// : (!uneval.get<style::BackgroundPattern>().isUndefined()
// || eval.get<style::BackgroundOpacity>() < 1.0f
// || eval.get<style::BackgroundColor>().a < 1.0f)
// ? RenderPass::Translucent
// : RenderPass::Opaque | RenderPass::Translucent; // evaluated based on opaquePassCutoff in render()
//unevaluated.hasTransition();
//getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
std::optional<Color> color;
if (eval.get<BackgroundPattern>().from.empty()) {
const auto opacity = eval.get<style::BackgroundOpacity>();
if (opacity > 0.0f) {
color = eval.get<BackgroundColor>() * eval.get<BackgroundOpacity>();
}
}
const auto zoom = state.getIntegerZoom();
const auto tileCover = util::tileCover(state, zoom);
// Drawables per overscaled or canonical tile?
//const UnwrappedTileID unwrappedTileID = tileID.toUnwrapped();
std::unordered_set<OverscaledTileID> newTileIDs(tileCover.begin(), tileCover.end());
// Put the tile cover into a searchable form.
// TODO: Likely better to sort and `std::binary_search` the vector.
// If it's returned in a well-defined order, we might not even need to sort.
const std::unordered_set<OverscaledTileID> newTileIDs(tileCover.begin(), tileCover.end());
// For each existing tile drawable...
for (auto iter = tileDrawables.begin(); iter != tileDrawables.end(); ) {
@@ -85,28 +112,39 @@ void BackgroundLayer::Impl::update(PaintParameters& parameters, UniqueChangeRequ
}
}
if (!color) {
return;
}
std::unique_ptr<gfx::DrawableBuilder> builder;
// For each tile in the cover set, add a tile drawable if one doesn't already exist.
// We currently assume only one drawable per tile.
for (const auto& tileID : tileCover) {
const auto result = tileDrawables.insert(std::make_pair(tileID, gfx::DrawablePtr()));
if (!result.second) {
// Already present
// TODO: Update matrix uniform here or in the tweaker?
// TODO: Update matrix here or in the tweaker?
continue;
}
// We actually need to build things, so set up a builder if we haven't already
if (!builder) {
builder = std::make_unique<gl::DrawableGLBuilder>(); // from GL-specific code via virtual method on ...Context?
builder->setShader(shader);
builder->addTweaker(std::make_shared<gl::DrawableGLTweaker>()); // generally shared across drawables
builder->setColor(*color);
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
}
// Tile coordinates are fixed...
builder->addQuad(0, 0, util::EXTENT, util::EXTENT);
// ... they're placed with the matrix in the uniforms
// ... they're placed with the matrix in the uniforms, which changes with the view
builder->setMatrix(/*parameters.matrixForTile(tileID.toUnwrapped())*/ matrix::identity4());
//builder->setUniform("u_matrix", matrix);
builder->flush();
// TODO: Store Tile ID with drawable?
// Drawables aren't always tile-specific, but it may be needed sometimes.
auto drawables = builder->clearDrawables();
if (!drawables.empty()) {
auto& drawable = drawables[0];

View File

@@ -14,6 +14,8 @@ namespace gfx {
class Drawable;
class ShaderProgramBase;
class ShaderRegistry;
using DrawablePtr = std::shared_ptr<Drawable>;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
@@ -29,11 +31,16 @@ public:
bool hasLayoutDifference(const Layer::Impl&) const override;
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
void layerAdded(PaintParameters&, UniqueChangeRequestVec&) const override;
void layerRemoved(PaintParameters&, UniqueChangeRequestVec&) const override;
void layerAdded(gfx::ShaderRegistry&,
const TransformState&,
const PropertyEvaluationParameters&,
UniqueChangeRequestVec&) const override;
void layerRemoved(UniqueChangeRequestVec&) const override;
/// Generate any changes needed by the layer
void update(PaintParameters&, UniqueChangeRequestVec&) const override;
void update(const TransformState&,
const PropertyEvaluationParameters&,
UniqueChangeRequestVec&) const override;
private:
mutable std::mutex mutex;