summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/sources/render_image_source.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/sources/render_image_source.cpp')
-rw-r--r--src/mbgl/renderer/sources/render_image_source.cpp165
1 files changed, 99 insertions, 66 deletions
diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp
index f5068b9d7f..d215dc8d13 100644
--- a/src/mbgl/renderer/sources/render_image_source.cpp
+++ b/src/mbgl/renderer/sources/render_image_source.cpp
@@ -1,19 +1,23 @@
#include <mbgl/map/transform_state.hpp>
#include <mbgl/math/log2.hpp>
#include <mbgl/renderer/buckets/raster_bucket.hpp>
-#include <mbgl/renderer/painter.hpp>
+#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/sources/render_image_source.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
+#include <mbgl/renderer/render_static_data.hpp>
+#include <mbgl/programs/programs.hpp>
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/util/tile_cover.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/constants.hpp>
namespace mbgl {
using namespace style;
RenderImageSource::RenderImageSource(Immutable<style::ImageSource::Impl> impl_)
- : RenderSource(impl_), shouldRender(false) {
+ : RenderSource(impl_) {
}
RenderImageSource::~RenderImageSource() = default;
@@ -26,7 +30,7 @@ bool RenderImageSource::isLoaded() const {
return !!bucket;
}
-void RenderImageSource::startRender(Painter& painter) {
+void RenderImageSource::startRender(PaintParameters& parameters) {
if (!isLoaded()) {
return;
}
@@ -36,31 +40,53 @@ void RenderImageSource::startRender(Painter& painter) {
for (size_t i = 0; i < tileIds.size(); i++) {
mat4 matrix;
matrix::identity(matrix);
- painter.state.matrixFor(matrix, tileIds[i]);
- matrix::multiply(matrix, painter.projMatrix, matrix);
+ parameters.state.matrixFor(matrix, tileIds[i]);
+ matrix::multiply(matrix, parameters.projMatrix, matrix);
matrices.push_back(matrix);
}
- if (bucket->needsUpload() && shouldRender) {
- bucket->upload(painter.context);
+ if (bucket->needsUpload()) {
+ bucket->upload(parameters.context);
}
}
-void RenderImageSource::finishRender(Painter& painter) {
- if (!isLoaded() || !shouldRender) {
+void RenderImageSource::finishRender(PaintParameters& parameters) {
+ if (!isLoaded() || !(parameters.debugOptions & MapDebugOptions::TileBorders)) {
return;
}
+
+ static const style::Properties<>::PossiblyEvaluated properties {};
+ static const DebugProgram::PaintPropertyBinders paintAttibuteData(properties, 0);
+
for (auto matrix : matrices) {
- painter.renderTileDebug(matrix);
+ parameters.programs.debug.draw(
+ parameters.context,
+ gl::LineStrip { 4.0f * parameters.pixelRatio },
+ gl::DepthMode::disabled(),
+ gl::StencilMode::disabled(),
+ gl::ColorMode::unblended(),
+ DebugProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_color::Value{ Color::red() }
+ },
+ parameters.staticData.tileVertexBuffer,
+ parameters.staticData.tileBorderIndexBuffer,
+ parameters.staticData.tileBorderSegments,
+ paintAttibuteData,
+ properties,
+ parameters.state.getZoom(),
+ "debug"
+ );
}
}
std::unordered_map<std::string, std::vector<Feature>>
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&,
- const RenderStyle&,
- const RenderedQueryOptions&) const {
- return {};
+ const std::vector<const RenderLayer*>&,
+ const RenderedQueryOptions&,
+ const CollisionIndex&) const {
+ return std::unordered_map<std::string, std::vector<Feature>> {};
}
std::vector<Feature> RenderImageSource::querySourceFeatures(const SourceQueryOptions&) const {
@@ -72,89 +98,106 @@ void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_,
const bool needsRendering,
const bool,
const TileParameters& parameters) {
- std::swap(baseImpl, baseImpl_);
-
enabled = needsRendering;
+ if (!needsRendering) {
+ return;
+ }
auto transformState = parameters.transformState;
- auto size = transformState.getSize();
- double viewportHeight = size.height;
+ std::swap(baseImpl, baseImpl_);
auto coords = impl().getCoordinates();
+ std::shared_ptr<PremultipliedImage> image = impl().getImage();
- // Compute the screen coordinates at wrap=0 for the given LatLng
- ScreenCoordinate nePixel = { -INFINITY, -INFINITY };
- ScreenCoordinate swPixel = { INFINITY, INFINITY };
-
- for (LatLng latLng : coords) {
- ScreenCoordinate pixel = transformState.latLngToScreenCoordinate(latLng);
- swPixel.x = std::min(swPixel.x, pixel.x);
- nePixel.x = std::max(nePixel.x, pixel.x);
- swPixel.y = std::min(swPixel.y, viewportHeight - pixel.y);
- nePixel.y = std::max(nePixel.y, viewportHeight - pixel.y);
- }
- double width = nePixel.x - swPixel.x;
- double height = nePixel.y - swPixel.y;
-
- // Don't bother drawing the ImageSource unless it occupies >4 screen pixels
- shouldRender = (width * height > 4);
- if (!shouldRender) {
+ if (!image || !image->valid()) {
+ enabled = false;
return;
}
+ // Compute the z0 tile coordinates for the given LatLngs
+ TileCoordinatePoint nePoint = { -INFINITY, -INFINITY };
+ TileCoordinatePoint swPoint = { INFINITY, INFINITY };
+ std::vector<TileCoordinatePoint> tileCoordinates;
+ for (LatLng latLng : coords) {
+ auto point = TileCoordinate::fromLatLng(0, latLng).p;
+ tileCoordinates.push_back(point);
+ swPoint.x = std::min(swPoint.x, point.x);
+ nePoint.x = std::max(nePoint.x, point.x);
+ swPoint.y = std::min(swPoint.y, point.y);
+ nePoint.y = std::max(nePoint.y, point.y);
+ }
+
// Calculate the optimum zoom level to determine the tile ids to use for transforms
- double minScale = INFINITY;
- if (width > 0 || height > 0) {
- double scaleX = double(size.width) / width;
- double scaleY = double(size.height) / height;
- minScale = util::min(scaleX, scaleY);
+ auto dx = nePoint.x - swPoint.x;
+ auto dy = nePoint.y - swPoint.y;
+ auto dMax = std::max(dx, dy);
+ double zoom = std::max(0.0, std::floor(-util::log2(dMax)));
+
+ // Only enable if the long side of the image is > 2 pixels. Resulting in a
+ // display of at least 2 x 1 px image
+ // A tile coordinate unit represents the length of one tile (tileSize) at a given zoom.
+ // To convert a tile coordinate to pixels, multiply by tileSize.
+ // Here dMax is in z0 tile units, so we also scale by 2^z to match current zoom.
+ enabled = dMax * std::pow(2.0, transformState.getZoom()) * util::tileSize > 2.0;
+ if (!enabled) {
+ return;
}
- double zoom = transformState.getZoom() + util::log2(minScale);
- zoom = util::clamp(zoom, transformState.getMinZoom(), transformState.getMaxZoom());
auto imageBounds = LatLngBounds::hull(coords[0], coords[1]);
imageBounds.extend(coords[2]);
imageBounds.extend(coords[3]);
- auto tileCover = util::tileCover(imageBounds, ::floor(zoom));
+ auto tileCover = util::tileCover(imageBounds, zoom);
tileIds.clear();
tileIds.push_back(tileCover[0]);
+ bool hasVisibleTile = false;
// Add additional wrapped tile ids if neccessary
auto idealTiles = util::tileCover(transformState, transformState.getZoom());
for (auto tile : idealTiles) {
if (tile.wrap != 0 && tileCover[0].canonical.isChildOf(tile.canonical)) {
tileIds.push_back({ tile.wrap, tileCover[0].canonical });
+ hasVisibleTile = true;
+ }
+ else if (!hasVisibleTile) {
+ for (auto coveringTile: tileCover) {
+ if(coveringTile.canonical == tile.canonical ||
+ coveringTile.canonical.isChildOf(tile.canonical) ||
+ tile.canonical.isChildOf(coveringTile.canonical)) {
+ hasVisibleTile = true;
+ }
+ }
}
}
+ enabled = hasVisibleTile;
+ if (!enabled) {
+ return;
+ }
+
// Calculate Geometry Coordinates based on tile cover at ideal zoom
GeometryCoordinates geomCoords;
- for (auto latLng : coords) {
- auto tc = TileCoordinate::fromLatLng(0, latLng);
- auto gc = TileCoordinate::toGeometryCoordinate(tileIds[0], tc.p);
+ for (auto tileCoords : tileCoordinates) {
+ auto gc = TileCoordinate::toGeometryCoordinate(tileIds[0], tileCoords);
geomCoords.push_back(gc);
}
-
- const UnassociatedImage& image = impl().getImage();
- if (!image.valid()) {
- return;
- }
-
- if (!bucket || image != bucket->image) {
- bucket = std::make_unique<RasterBucket>(image.clone());
+ if (!bucket) {
+ bucket = std::make_unique<RasterBucket>(image);
} else {
bucket->clear();
+ if (image != bucket->image) {
+ bucket->setImage(image);
+ }
}
// Set Bucket Vertices, Indices, and segments
bucket->vertices.emplace_back(
RasterProgram::layoutVertex({ geomCoords[0].x, geomCoords[0].y }, { 0, 0 }));
bucket->vertices.emplace_back(
- RasterProgram::layoutVertex({ geomCoords[1].x, geomCoords[1].y }, { 32767, 0 }));
+ RasterProgram::layoutVertex({ geomCoords[1].x, geomCoords[1].y }, { util::EXTENT, 0 }));
bucket->vertices.emplace_back(
- RasterProgram::layoutVertex({ geomCoords[3].x, geomCoords[3].y }, { 0, 32767 }));
+ RasterProgram::layoutVertex({ geomCoords[3].x, geomCoords[3].y }, { 0, util::EXTENT }));
bucket->vertices.emplace_back(
- RasterProgram::layoutVertex({ geomCoords[2].x, geomCoords[2].y }, { 32767, 32767 }));
+ RasterProgram::layoutVertex({ geomCoords[2].x, geomCoords[2].y }, { util::EXTENT, util::EXTENT }));
bucket->indices.emplace_back(0, 1, 2);
bucket->indices.emplace_back(1, 2, 3);
@@ -162,16 +205,6 @@ void RenderImageSource::update(Immutable<style::Source::Impl> baseImpl_,
bucket->segments.emplace_back(0, 0, 4, 6);
}
-void RenderImageSource::render(Painter& painter,
- PaintParameters& parameters,
- const RenderLayer& layer) {
- if (isLoaded() && !bucket->needsUpload() && shouldRender) {
- for (auto matrix : matrices) {
- bucket->render(painter, parameters, layer, matrix);
- }
- }
-}
-
void RenderImageSource::dumpDebugLogs() const {
Log::Info(Event::General, "RenderImageSource::id: %s", impl().id.c_str());
Log::Info(Event::General, "RenderImageSource::loaded: %s", isLoaded() ? "yes" : "no");