#include #include #include #include #include #include #include #include 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(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