From 3c656d2bf2227a8a36580904bd5e212d47541d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Tue, 15 Apr 2014 14:30:05 -0400 Subject: [PATCH] add debug markers for easier gl debugging --- include/llmr/map/source.hpp | 2 +- include/llmr/platform/gl.hpp | 24 ++++++++++++++++++++++++ include/llmr/util/string.hpp | 9 +++++++-- src/map/source.cpp | 4 ++-- src/map/tile_data.cpp | 11 +++++------ src/renderer/painter.cpp | 22 ++++++++++++++++++++++ 6 files changed, 61 insertions(+), 11 deletions(-) diff --git a/include/llmr/map/source.hpp b/include/llmr/map/source.hpp index 3ddebb0ee..8af66ff57 100644 --- a/include/llmr/map/source.hpp +++ b/include/llmr/map/source.hpp @@ -53,7 +53,7 @@ private: Type type; std::list zooms; - const char *url; + const std::string url; uint32_t tile_size; uint32_t min_zoom; uint32_t max_zoom; diff --git a/include/llmr/platform/gl.hpp b/include/llmr/platform/gl.hpp index acd8a8f06..b695b4ed8 100644 --- a/include/llmr/platform/gl.hpp +++ b/include/llmr/platform/gl.hpp @@ -1,6 +1,8 @@ #ifndef LLMR_RENDERER_GL #define LLMR_RENDERER_GL +#include + #ifdef NVIDIA #include #include @@ -33,6 +35,28 @@ #include #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 diff --git a/include/llmr/util/string.hpp b/include/llmr/util/string.hpp index 4e7ae6d4b..50293b9f4 100644 --- a/include/llmr/util/string.hpp +++ b/include/llmr/util/string.hpp @@ -6,13 +6,18 @@ namespace llmr { namespace util { -template +template 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 +inline std::string sprintf(const std::string &msg, Args... args) { + return sprintf(msg.c_str(), args...); +} + } } diff --git a/src/map/source.cpp b/src/map/source.cpp index 4cb2b4f60..b84efe470 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -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(normalized_id, map.getStyle(), map.getGlyphAtlas(), formed_url, (type == Source::Type::raster)); diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 203b147c8..3c379bd1a 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -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() { diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index 71b1e362a..ee6c625cb 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -18,6 +18,7 @@ #include #include #include +#include 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& 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& 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& tile_data, const std strata = i * strata_thickness; renderLayer(tile_data, *it); } + gl::end_group(); } void Painter::renderLayer(const std::shared_ptr& 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);