add debug markers for easier gl debugging
This commit is contained in:
@@ -53,7 +53,7 @@ private:
|
||||
|
||||
Type type;
|
||||
std::list<uint32_t> zooms;
|
||||
const char *url;
|
||||
const std::string url;
|
||||
uint32_t tile_size;
|
||||
uint32_t min_zoom;
|
||||
uint32_t max_zoom;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef LLMR_RENDERER_GL
|
||||
#define LLMR_RENDERER_GL
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef NVIDIA
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
@@ -33,6 +35,28 @@
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
|
||||
namespace llmr {
|
||||
namespace gl {
|
||||
// Debug group markers, useful for debuggin on iOS
|
||||
inline void start_group(const std::string &str) {
|
||||
#if GL_EXT_debug_marker
|
||||
glPushGroupMarkerEXT(0, str.c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void end_group() {
|
||||
#if GL_EXT_debug_marker
|
||||
glPopGroupMarkerEXT();
|
||||
#endif
|
||||
}
|
||||
|
||||
struct group {
|
||||
inline group(const std::string &str) { start_group(str); }
|
||||
~group() { end_group(); };
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GL_ES_VERSION_2_0
|
||||
#define glClearDepth glClearDepthf
|
||||
#define glDepthRange glDepthRangef
|
||||
|
||||
@@ -6,13 +6,18 @@
|
||||
namespace llmr {
|
||||
namespace util {
|
||||
|
||||
template<typename... Args>
|
||||
template<size_t max, typename... Args>
|
||||
inline std::string sprintf(const char *msg, Args... args) {
|
||||
char res[1024];
|
||||
char res[max];
|
||||
int len = snprintf(res, sizeof(res), msg, args...);
|
||||
return std::string(res, len);
|
||||
}
|
||||
|
||||
template<size_t max, typename... Args>
|
||||
inline std::string sprintf(const std::string &msg, Args... args) {
|
||||
return sprintf<max>(msg.c_str(), args...);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,9 +110,9 @@ TileData::State Source::addTile(const Tile::ID& id) {
|
||||
std::string formed_url;
|
||||
|
||||
if (type == Source::Type::vector) {
|
||||
formed_url = util::sprintf(url, normalized_id.z, normalized_id.x, normalized_id.y);
|
||||
formed_url = util::sprintf<256>(url, normalized_id.z, normalized_id.x, normalized_id.y);
|
||||
} else {
|
||||
formed_url = util::sprintf(url, normalized_id.z, normalized_id.x, normalized_id.y, (map.getPixelRatio() > 1.0 ? "@2x" : ""));
|
||||
formed_url = util::sprintf<256>(url, normalized_id.z, normalized_id.x, normalized_id.y, (map.getPixelRatio() > 1.0 ? "@2x" : ""));
|
||||
}
|
||||
|
||||
new_tile.data = std::make_shared<TileData>(normalized_id, map.getStyle(), map.getGlyphAtlas(), formed_url, (type == Source::Type::raster));
|
||||
|
||||
@@ -13,17 +13,16 @@ using namespace llmr;
|
||||
|
||||
TileData::TileData(Tile::ID id, const Style& style, GlyphAtlas& glyphAtlas, const std::string url, const bool is_raster)
|
||||
: id(id),
|
||||
url(url),
|
||||
state(State::initial),
|
||||
is_raster(is_raster),
|
||||
raster(),
|
||||
url(url),
|
||||
is_raster(is_raster),
|
||||
style(style),
|
||||
glyphAtlas(glyphAtlas) {
|
||||
|
||||
// Initialize tile debug coordinates
|
||||
char coord[32];
|
||||
snprintf(coord, sizeof(coord), "%d/%d/%d", id.z, id.x, id.y);
|
||||
debugFontBuffer.addText(coord, 50, 200, 5);
|
||||
const std::string str = util::sprintf<32>("%d/%d/%d", id.z, id.x, id.y);
|
||||
debugFontBuffer.addText(str.c_str(), 50, 200, 5);
|
||||
}
|
||||
|
||||
TileData::~TileData() {
|
||||
@@ -32,7 +31,7 @@ TileData::~TileData() {
|
||||
}
|
||||
|
||||
const std::string TileData::toString() const {
|
||||
return util::sprintf("[tile %d/%d/%d]", id.z, id.x, id.y);
|
||||
return util::sprintf<32>("[tile %d/%d/%d]", id.z, id.x, id.y);
|
||||
}
|
||||
|
||||
void TileData::request() {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <llmr/style/style.hpp>
|
||||
#include <llmr/style/sprite.hpp>
|
||||
#include <llmr/util/raster.hpp>
|
||||
#include <llmr/util/string.hpp>
|
||||
|
||||
using namespace llmr;
|
||||
|
||||
@@ -116,6 +117,7 @@ void Painter::changeMatrix() {
|
||||
}
|
||||
|
||||
void Painter::prepareClippingMask() {
|
||||
gl::start_group("clipping masks");
|
||||
useProgram(plainShader->program);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
depthMask(false);
|
||||
@@ -125,6 +127,7 @@ void Painter::prepareClippingMask() {
|
||||
}
|
||||
|
||||
void Painter::drawClippingMask(const mat4& matrix, uint8_t clip_id) {
|
||||
gl::group group("mask");
|
||||
plainShader->setMatrix(matrix);
|
||||
|
||||
plainShader->setColor(style.computed.background.color);
|
||||
@@ -138,9 +141,11 @@ void Painter::finishClippingMask() {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
depthMask(true);
|
||||
glStencilMask(0x0);
|
||||
gl::end_group();
|
||||
}
|
||||
|
||||
void Painter::clear() {
|
||||
gl::group group("clear");
|
||||
glStencilMask(0xFF);
|
||||
depthMask(true);
|
||||
#ifdef NVIDIA
|
||||
@@ -153,6 +158,8 @@ void Painter::clear() {
|
||||
}
|
||||
|
||||
void Painter::render(const Tile& tile) {
|
||||
gl::group group(util::sprintf<32>("render %d/%d/%d", tile.id.z, tile.id.y, tile.id.z));
|
||||
|
||||
assert(tile.data);
|
||||
if (tile.data->state != TileData::State::parsed) {
|
||||
return;
|
||||
@@ -176,6 +183,7 @@ void Painter::renderLayers(const std::shared_ptr<TileData>& tile_data, const std
|
||||
// - FIRST PASS ------------------------------------------------------------
|
||||
// Render everything top-to-bottom by using reverse iterators. Render opaque
|
||||
// objects first.
|
||||
gl::start_group("opaque pass");
|
||||
pass = Opaque;
|
||||
glDisable(GL_BLEND);
|
||||
depthMask(true);
|
||||
@@ -186,10 +194,12 @@ void Painter::renderLayers(const std::shared_ptr<TileData>& tile_data, const std
|
||||
strata = i * strata_thickness;
|
||||
renderLayer(tile_data, *it);
|
||||
}
|
||||
gl::end_group();
|
||||
|
||||
// - SECOND PASS -----------------------------------------------------------
|
||||
// Make a second pass, rendering translucent objects. This time, we render
|
||||
// bottom-to-top.
|
||||
gl::start_group("translucent pass");
|
||||
pass = Translucent;
|
||||
glEnable(GL_BLEND);
|
||||
depthMask(false);
|
||||
@@ -200,6 +210,7 @@ void Painter::renderLayers(const std::shared_ptr<TileData>& tile_data, const std
|
||||
strata = i * strata_thickness;
|
||||
renderLayer(tile_data, *it);
|
||||
}
|
||||
gl::end_group();
|
||||
}
|
||||
|
||||
void Painter::renderLayer(const std::shared_ptr<TileData>& tile_data, const LayerDescription& layer_desc) {
|
||||
@@ -231,6 +242,8 @@ void Painter::renderRaster(const std::string& layer_name, const std::shared_ptr<
|
||||
const RasterProperties& properties = style.computed.rasters[layer_name];
|
||||
if (!properties.enabled) return;
|
||||
|
||||
gl::group group(layer_name + " (raster)");
|
||||
|
||||
useProgram(rasterShader->program);
|
||||
rasterShader->setMatrix(matrix);
|
||||
rasterShader->setImage(0);
|
||||
@@ -268,6 +281,7 @@ void Painter::renderFill(FillBucket& bucket, const std::string& layer_name, cons
|
||||
stroke_color = fill_color;
|
||||
}
|
||||
|
||||
gl::group group(layer_name + " (fill)");
|
||||
// Because we're drawing top-to-bottom, and we update the stencil mask
|
||||
// below, we have to draw the outline first (!)
|
||||
if (outline && pass == Translucent) {
|
||||
@@ -393,6 +407,7 @@ void Painter::renderLine(LineBucket& bucket, const std::string& layer_name, cons
|
||||
color[3] *= properties.opacity;
|
||||
|
||||
|
||||
gl::group group(layer_name + " (line)");
|
||||
glDepthRange(strata, 1.0f);
|
||||
|
||||
// We're only drawing end caps + round line joins if the line is > 2px. Otherwise, they aren't visible anyway.
|
||||
@@ -459,6 +474,8 @@ void Painter::renderPoint(PointBucket& bucket, const std::string& layer_name, co
|
||||
const PointProperties& properties = style.computed.points[layer_name];
|
||||
if (!properties.enabled) return;
|
||||
|
||||
gl::group group(layer_name + " (point)");
|
||||
|
||||
Color color = properties.color;
|
||||
color[0] *= properties.opacity;
|
||||
color[1] *= properties.opacity;
|
||||
@@ -501,6 +518,8 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
|
||||
const TextProperties& properties = style.computed.texts[layer_name];
|
||||
if (!properties.enabled) return;
|
||||
|
||||
gl::group group(layer_name + " (text)");
|
||||
|
||||
mat4 exMatrix;
|
||||
matrix::copy(exMatrix, projMatrix);
|
||||
if (bucket.geom_desc.path == TextPathType::Curve) {
|
||||
@@ -594,6 +613,8 @@ void Painter::renderText(TextBucket& bucket, const std::string& layer_name, cons
|
||||
}
|
||||
|
||||
void Painter::renderDebug(const TileData::Ptr& tile_data) {
|
||||
gl::group group("debug");
|
||||
|
||||
// Disable depth test and don't count this towards the depth buffer,
|
||||
// but *don't* disable stencil test, as we want to clip the red tile border
|
||||
// to the tile viewport.
|
||||
@@ -621,6 +642,7 @@ void Painter::renderDebug(const TileData::Ptr& tile_data) {
|
||||
}
|
||||
|
||||
void Painter::renderMatte() {
|
||||
gl::group group("matte");
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glStencilFunc(GL_EQUAL, 0x0, 0xFF);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user