[core] Prepare render sources before render layers are initialized

This commit is contained in:
Mikhail Pozdnyakov
2019-05-19 11:41:22 +03:00
parent e2ed9833c4
commit 84d3b5f899
23 changed files with 84 additions and 58 deletions

View File

@@ -51,7 +51,7 @@ void RenderAnnotationSource::upload(gfx::UploadPass& uploadPass) {
tilePyramid.upload(uploadPass);
}
void RenderAnnotationSource::prepare(PaintParameters& parameters) {
void RenderAnnotationSource::prepare(const SourcePrepareParameters& parameters) {
tilePyramid.prepare(parameters);
}

View File

@@ -19,7 +19,7 @@ public:
const TileParameters&) final;
void upload(gfx::UploadPass&) final;
void prepare(PaintParameters&) final;
void prepare(const SourcePrepareParameters&) final;
void finishRender(PaintParameters&) final;
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final;

View File

@@ -10,11 +10,27 @@
namespace mbgl {
TransformParameters::TransformParameters(const TransformState& state_)
: state(state_) {
// Update the default matrices to the current viewport dimensions.
state.getProjMatrix(projMatrix);
// Also compute a projection matrix that aligns with the current pixel grid, taking into account
// odd viewport sizes.
state.getProjMatrix(alignedProjMatrix, 1, true);
// Calculate a second projection matrix with the near plane clipped to 100 so as
// not to waste lots of depth buffer precision on very close empty space, for layer
// types (fill-extrusion) that use the depth buffer to emulate real-world space.
state.getProjMatrix(nearClippedProjMatrix, 100);
}
PaintParameters::PaintParameters(gfx::Context& context_,
float pixelRatio_,
gfx::RendererBackend& backend_,
const UpdateParameters& updateParameters,
const EvaluatedLight& evaluatedLight_,
const TransformParameters& transformParams_,
RenderStaticData& staticData_,
ImageManager& imageManager_,
LineAtlas& lineAtlas_)
@@ -23,6 +39,7 @@ PaintParameters::PaintParameters(gfx::Context& context_,
encoder(context.createCommandEncoder()),
state(updateParameters.transformState),
evaluatedLight(evaluatedLight_),
transformParams(transformParams_),
staticData(staticData_),
imageManager(imageManager_),
lineAtlas(lineAtlas_),
@@ -36,18 +53,6 @@ PaintParameters::PaintParameters(gfx::Context& context_,
programs(staticData_.programs)
#endif
{
// Update the default matrices to the current viewport dimensions.
state.getProjMatrix(projMatrix);
// Also compute a projection matrix that aligns with the current pixel grid, taking into account
// odd viewport sizes.
state.getProjMatrix(alignedProjMatrix, 1, true);
// Calculate a second projection matrix with the near plane clipped to 100 so as
// not to waste lots of depth buffer precision on very close empty space, for layer
// types (fill-extrusion) that use the depth buffer to emulate real-world space.
state.getProjMatrix(nearClippedProjMatrix, 100);
pixelsToGLUnits = {{ 2.0f / state.getSize().width, -2.0f / state.getSize().height }};
if (state.getViewportMode() == ViewportMode::FlippedY) {
@@ -60,7 +65,7 @@ PaintParameters::~PaintParameters() = default;
mat4 PaintParameters::matrixForTile(const UnwrappedTileID& tileID, bool aligned) const {
mat4 matrix;
state.matrixFor(matrix, tileID);
matrix::multiply(matrix, aligned ? alignedProjMatrix : projMatrix, matrix);
matrix::multiply(matrix, aligned ? transformParams.alignedProjMatrix : transformParams.projMatrix, matrix);
return matrix;
}

View File

@@ -31,6 +31,16 @@ class CommandEncoder;
class RenderPass;
} // namespace gfx
class TransformParameters {
public:
TransformParameters(const TransformState&);
mat4 projMatrix;
mat4 alignedProjMatrix;
mat4 nearClippedProjMatrix;
const TransformState& state;
};
class PaintParameters {
public:
PaintParameters(gfx::Context&,
@@ -38,6 +48,7 @@ public:
gfx::RendererBackend&,
const UpdateParameters&,
const EvaluatedLight&,
const TransformParameters&,
RenderStaticData&,
ImageManager&,
LineAtlas&);
@@ -50,6 +61,7 @@ public:
const TransformState& state;
const EvaluatedLight& evaluatedLight;
const TransformParameters& transformParams;
RenderStaticData& staticData;
ImageManager& imageManager;
@@ -71,10 +83,6 @@ public:
mat4 matrixForTile(const UnwrappedTileID&, bool aligned = false) const;
mat4 projMatrix;
mat4 alignedProjMatrix;
mat4 nearClippedProjMatrix;
// Stencil handling
public:
void renderTileClippingMasks(const std::vector<std::reference_wrapper<RenderTile>>&);

View File

@@ -55,6 +55,8 @@ RenderSource::RenderSource(Immutable<style::Source::Impl> impl)
observer(&nullObserver) {
}
RenderSource::~RenderSource() = default;
void RenderSource::setObserver(RenderSourceObserver* observer_) {
observer = observer_;
}

View File

@@ -1,5 +1,6 @@
#pragma once
#include <mbgl/map/mode.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/tile/tile_observer.hpp>
#include <mbgl/util/mat4.hpp>
@@ -26,14 +27,22 @@ class Tile;
class RenderSourceObserver;
class TileParameters;
class CollisionIndex;
class TransformParameters;
namespace gfx {
class UploadPass;
} // namespace gfx
class SourcePrepareParameters {
public:
const TransformParameters& transform;
const MapDebugOptions& debugOptions;
};
class RenderSource : protected TileObserver {
public:
static std::unique_ptr<RenderSource> create(Immutable<style::Source::Impl>);
virtual ~RenderSource();
// Check whether this source is of the given subtype.
template <class T>
@@ -60,7 +69,7 @@ public:
const TileParameters&) = 0;
virtual void upload(gfx::UploadPass&) = 0;
virtual void prepare(PaintParameters&) = 0;
virtual void prepare(const SourcePrepareParameters&) = 0;
virtual void finishRender(PaintParameters&) = 0;
// Returns a list of RenderTiles, sorted by tile id.

View File

@@ -1,6 +1,8 @@
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/buckets/debug_bucket.hpp>
#include <mbgl/renderer/render_source.hpp>
#include <mbgl/renderer/render_static_data.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/map/transform_state.hpp>
@@ -70,7 +72,7 @@ void RenderTile::upload(gfx::UploadPass& uploadPass) {
}
}
void RenderTile::prepare(PaintParameters& parameters) {
void RenderTile::prepare(const SourcePrepareParameters& parameters) {
if (parameters.debugOptions != MapDebugOptions::NoDebug &&
(!debugBucket || debugBucket->renderable != tile.isRenderable() ||
debugBucket->complete != tile.isComplete() ||
@@ -86,10 +88,11 @@ void RenderTile::prepare(PaintParameters& parameters) {
// Calculate two matrices for this tile: matrix is the standard tile matrix; nearClippedMatrix
// clips the near plane to 100 to save depth buffer precision
parameters.state.matrixFor(matrix, id);
parameters.state.matrixFor(nearClippedMatrix, id);
matrix::multiply(matrix, parameters.projMatrix, matrix);
matrix::multiply(nearClippedMatrix, parameters.nearClippedProjMatrix, nearClippedMatrix);
const auto& transform = parameters.transform;
transform.state.matrixFor(matrix, id);
transform.state.matrixFor(nearClippedMatrix, id);
matrix::multiply(matrix, transform.projMatrix, matrix);
matrix::multiply(nearClippedMatrix, transform.nearClippedProjMatrix, nearClippedMatrix);
}
void RenderTile::finishRender(PaintParameters& parameters) {

View File

@@ -1,5 +1,6 @@
#pragma once
#include <mbgl/map/mode.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/util/mat4.hpp>
#include <mbgl/style/types.hpp>
@@ -18,6 +19,7 @@ class Tile;
class TransformState;
class PaintParameters;
class DebugBucket;
class SourcePrepareParameters;
class RenderTile final {
public:
@@ -46,7 +48,7 @@ public:
void setMask(TileMask&&);
void upload(gfx::UploadPass&);
void prepare(PaintParameters&);
void prepare(const SourcePrepareParameters&);
void finishRender(PaintParameters&);
mat4 translateVtxMatrix(const mat4& tileMatrix,

View File

@@ -291,6 +291,15 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
observer->onWillStartRenderingFrame();
TransformParameters transformParams(updateParameters.transformState);
// Update all matrices and generate data that we should upload to the GPU.
for (const auto& entry : renderSources) {
if (entry.second->isEnabled()) {
entry.second->prepare({transformParams, updateParameters.debugOptions});
}
}
// Set render tiles to the render items.
for (auto& renderItem : renderItems) {
if (!renderItem.source) {
@@ -312,13 +321,11 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
bool symbolBucketsChanged = false;
const bool placementChanged = !placement->stillRecent(updateParameters.timePoint);
std::set<std::string> usedSymbolLayers;
mat4 projMatrix;
if (placementChanged) {
placement = std::make_unique<Placement>(
updateParameters.transformState, updateParameters.mode,
updateParameters.transitionOptions, updateParameters.crossSourceCollisions,
std::move(placement));
updateParameters.transformState.getProjMatrix(projMatrix);
}
for (auto it = layersNeedPlacement.rbegin(); it != layersNeedPlacement.rend(); ++it) {
@@ -327,7 +334,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
if (placementChanged) {
usedSymbolLayers.insert(layer.getID());
placement->placeLayer(layer, projMatrix, updateParameters.debugOptions & MapDebugOptions::Collision);
placement->placeLayer(layer, transformParams.projMatrix, updateParameters.debugOptions & MapDebugOptions::Collision);
}
}
@@ -357,6 +364,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
backend,
updateParameters,
renderLight.getEvaluated(),
transformParams,
*staticData,
*imageManager,
*lineAtlas,
@@ -364,18 +372,6 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
parameters.symbolFadeChange = placement->symbolFadeChange(updateParameters.timePoint);
// TODO: move this pass to before the PaintParameters initialization
// - PREPARE PASS -------------------------------------------------------------------------------
// Runs an initialization pass for all sources.
{
// Update all matrices and generate data that we should upload to the GPU.
for (const auto& entry : renderSources) {
if (entry.second->isEnabled()) {
entry.second->prepare(parameters);
}
}
}
// - UPLOAD PASS -------------------------------------------------------------------------------
// Uploads all required buffers and images before we do any actual rendering.
{

View File

@@ -51,7 +51,7 @@ void RenderCustomGeometrySource::upload(gfx::UploadPass& uploadPass) {
tilePyramid.upload(uploadPass);
}
void RenderCustomGeometrySource::prepare(PaintParameters& parameters) {
void RenderCustomGeometrySource::prepare(const SourcePrepareParameters& parameters) {
tilePyramid.prepare(parameters);
}

View File

@@ -19,7 +19,7 @@ public:
const TileParameters&) final;
void upload(gfx::UploadPass&) final;
void prepare(PaintParameters&) final;
void prepare(const SourcePrepareParameters&) final;
void finishRender(PaintParameters&) final;
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final;

View File

@@ -127,7 +127,7 @@ void RenderGeoJSONSource::upload(gfx::UploadPass& parameters) {
tilePyramid.upload(parameters);
}
void RenderGeoJSONSource::prepare(PaintParameters& parameters) {
void RenderGeoJSONSource::prepare(const SourcePrepareParameters& parameters) {
tilePyramid.prepare(parameters);
}

View File

@@ -24,7 +24,7 @@ public:
const TileParameters&) final;
void upload(gfx::UploadPass&) final;
void prepare(PaintParameters&) final;
void prepare(const SourcePrepareParameters&) final;
void finishRender(PaintParameters&) final;
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final;

View File

@@ -37,18 +37,18 @@ void RenderImageSource::upload(gfx::UploadPass& uploadPass) {
}
}
void RenderImageSource::prepare(PaintParameters& parameters) {
void RenderImageSource::prepare(const SourcePrepareParameters& parameters) {
if (!isLoaded()) {
return;
}
matrices.clear();
const auto& transformParams = parameters.transform;
for (auto& tileId : tileIds) {
mat4 matrix;
matrix::identity(matrix);
parameters.state.matrixFor(matrix, tileId);
matrix::multiply(matrix, parameters.alignedProjMatrix, matrix);
transformParams.state.matrixFor(matrix, tileId);
matrix::multiply(matrix, transformParams.alignedProjMatrix, matrix);
matrices.push_back(matrix);
}
}

View File

@@ -16,7 +16,7 @@ public:
bool isLoaded() const final;
void upload(gfx::UploadPass&) final;
void prepare(PaintParameters&) final;
void prepare(const SourcePrepareParameters&) final;
void finishRender(PaintParameters&) final;
void update(Immutable<style::Source::Impl>,

View File

@@ -130,7 +130,7 @@ void RenderRasterDEMSource::upload(gfx::UploadPass& parameters) {
tilePyramid.upload(parameters);
}
void RenderRasterDEMSource::prepare(PaintParameters& parameters) {
void RenderRasterDEMSource::prepare(const SourcePrepareParameters& parameters) {
algorithm::updateTileMasks(tilePyramid.getRenderTiles());
tilePyramid.prepare(parameters);
}

View File

@@ -19,7 +19,7 @@ public:
const TileParameters&) final;
void upload(gfx::UploadPass&) final;
void prepare(PaintParameters&) final;
void prepare(const SourcePrepareParameters&) final;
void finishRender(PaintParameters&) final;
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final;

View File

@@ -61,7 +61,7 @@ void RenderRasterSource::upload(gfx::UploadPass& parameters) {
tilePyramid.upload(parameters);
}
void RenderRasterSource::prepare(PaintParameters& parameters) {
void RenderRasterSource::prepare(const SourcePrepareParameters& parameters) {
algorithm::updateTileMasks(tilePyramid.getRenderTiles());
tilePyramid.prepare(parameters);
}

View File

@@ -19,7 +19,7 @@ public:
const TileParameters&) final;
void upload(gfx::UploadPass&) final;
void prepare(PaintParameters&) final;
void prepare(const SourcePrepareParameters&) final;
void finishRender(PaintParameters&) final;
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final;

View File

@@ -61,7 +61,7 @@ void RenderVectorSource::upload(gfx::UploadPass& parameters) {
tilePyramid.upload(parameters);
}
void RenderVectorSource::prepare(PaintParameters& parameters) {
void RenderVectorSource::prepare(const SourcePrepareParameters& parameters) {
tilePyramid.prepare(parameters);
}

View File

@@ -19,7 +19,7 @@ public:
const TileParameters&) final;
void upload(gfx::UploadPass&) final;
void prepare(PaintParameters&) final;
void prepare(const SourcePrepareParameters&) final;
void finishRender(PaintParameters&) final;
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles() final;

View File

@@ -46,7 +46,7 @@ void TilePyramid::upload(gfx::UploadPass& parameters) {
}
}
void TilePyramid::prepare(PaintParameters& parameters) {
void TilePyramid::prepare(const SourcePrepareParameters& parameters) {
for (auto& tile : renderTiles) {
tile.prepare(parameters);
}

View File

@@ -25,6 +25,7 @@ class RenderLayer;
class RenderedQueryOptions;
class SourceQueryOptions;
class TileParameters;
class SourcePrepareParameters;
class TilePyramid {
public:
@@ -44,7 +45,7 @@ public:
std::function<std::unique_ptr<Tile> (const OverscaledTileID&)> createTile);
void upload(gfx::UploadPass&);
void prepare(PaintParameters&);
void prepare(const SourcePrepareParameters&);
void finishRender(PaintParameters&);
std::vector<std::reference_wrapper<RenderTile>> getRenderTiles();