121 lines
4.2 KiB
C++
121 lines
4.2 KiB
C++
#include <mbgl/renderer/render_target.hpp>
|
|
|
|
#include <mbgl/gfx/context.hpp>
|
|
#include <mbgl/gfx/offscreen_texture.hpp>
|
|
#include <mbgl/gfx/render_pass.hpp>
|
|
#include <mbgl/renderer/layer_group.hpp>
|
|
#include <mbgl/renderer/layer_tweaker.hpp>
|
|
#include <mbgl/renderer/paint_parameters.hpp>
|
|
#include <mbgl/renderer/render_tree.hpp>
|
|
|
|
namespace mbgl {
|
|
|
|
RenderTarget::RenderTarget(gfx::Context& context_, const Size size, const gfx::TextureChannelDataType type)
|
|
: context(context_) {
|
|
offscreenTexture = context.createOffscreenTexture(size, type);
|
|
}
|
|
|
|
RenderTarget::~RenderTarget() {}
|
|
|
|
const gfx::Texture2DPtr& RenderTarget::getTexture() {
|
|
return offscreenTexture->getTexture();
|
|
};
|
|
|
|
bool RenderTarget::isRenderable() {
|
|
return offscreenTexture && offscreenTexture->isRenderable();
|
|
}
|
|
|
|
bool RenderTarget::addLayerGroup(LayerGroupBasePtr layerGroup, const bool replace) {
|
|
const auto index = layerGroup->getLayerIndex();
|
|
const auto result = layerGroupsByLayerIndex.insert(std::make_pair(index, LayerGroupBasePtr{}));
|
|
if (result.second) {
|
|
// added
|
|
result.first->second = std::move(layerGroup);
|
|
return true;
|
|
} else {
|
|
// not added
|
|
if (replace) {
|
|
result.first->second = std::move(layerGroup);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool RenderTarget::removeLayerGroup(const int32_t layerIndex) {
|
|
const auto hit = layerGroupsByLayerIndex.find(layerIndex);
|
|
if (hit != layerGroupsByLayerIndex.end()) {
|
|
layerGroupsByLayerIndex.erase(hit);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
size_t RenderTarget::numLayerGroups() const noexcept {
|
|
return layerGroupsByLayerIndex.size();
|
|
}
|
|
|
|
static const LayerGroupBasePtr no_group;
|
|
|
|
const LayerGroupBasePtr& RenderTarget::getLayerGroup(const int32_t layerIndex) const {
|
|
const auto hit = layerGroupsByLayerIndex.find(layerIndex);
|
|
return (hit == layerGroupsByLayerIndex.end()) ? no_group : hit->second;
|
|
}
|
|
|
|
void RenderTarget::upload(gfx::UploadPass& uploadPass) {
|
|
visitLayerGroups(([&](LayerGroupBase& layerGroup) { layerGroup.upload(uploadPass); }));
|
|
}
|
|
|
|
void RenderTarget::render(RenderOrchestrator& orchestrator, const RenderTree& renderTree, PaintParameters& parameters) {
|
|
parameters.renderPass = parameters.encoder->createRenderPass("render target",
|
|
{.renderable = *offscreenTexture,
|
|
.clearColor = Color{0.0f, 0.0f, 0.0f, 1.0f},
|
|
.clearDepth = {},
|
|
.clearStencil = {}});
|
|
parameters.beginRenderTarget();
|
|
|
|
const gfx::ScissorRect prevScissorRect = parameters.scissorRect;
|
|
const auto& size = getTexture()->getSize();
|
|
parameters.scissorRect = {.x = 0, .y = 0, .width = size.width, .height = size.height};
|
|
|
|
// Run layer tweakers to update any dynamic elements
|
|
parameters.currentLayer = 0;
|
|
visitLayerGroups([&](LayerGroupBase& layerGroup) {
|
|
layerGroup.runTweakers(renderTree, parameters);
|
|
parameters.currentLayer++;
|
|
});
|
|
|
|
// draw layer groups, opaque pass
|
|
parameters.pass = RenderPass::Opaque;
|
|
parameters.depthRangeSize = 1 -
|
|
(numLayerGroups() + 2) * PaintParameters::numSublayers * PaintParameters::depthEpsilon;
|
|
|
|
parameters.currentLayer = 0;
|
|
visitLayerGroupsReversed([&](LayerGroupBase& layerGroup) {
|
|
layerGroup.render(orchestrator, parameters);
|
|
parameters.currentLayer++;
|
|
});
|
|
|
|
// draw layer groups, translucent pass
|
|
parameters.pass = RenderPass::Translucent;
|
|
parameters.depthRangeSize = 1 -
|
|
(numLayerGroups() + 2) * PaintParameters::numSublayers * PaintParameters::depthEpsilon;
|
|
|
|
parameters.currentLayer = static_cast<uint32_t>(numLayerGroups()) - 1;
|
|
visitLayerGroups([&](LayerGroupBase& layerGroup) {
|
|
layerGroup.render(orchestrator, parameters);
|
|
if (parameters.currentLayer > 0) {
|
|
parameters.currentLayer--;
|
|
}
|
|
});
|
|
|
|
parameters.renderPass.reset();
|
|
parameters.encoder->present(*offscreenTexture);
|
|
|
|
parameters.scissorRect = prevScissorRect;
|
|
}
|
|
|
|
} // namespace mbgl
|