add gl::groups back for easier debugging in Xcode

This commit is contained in:
Konstantin Käfer
2015-04-23 18:34:29 +02:00
parent f89f7f1bc2
commit 914b6f01f8
3 changed files with 99 additions and 65 deletions

View File

@@ -159,7 +159,7 @@ inline void start_group(const std::string &str) {
if (gl::PushDebugGroup != nullptr) {
MBGL_CHECK_ERROR(gl::PushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, GLsizei(str.size()), str.c_str()));
} else if (gl::PushGroupMarkerEXT != nullptr) {
MBGL_CHECK_ERROR(gl::PushGroupMarkerEXT(GLsizei(str.size()), str.c_str()));
MBGL_CHECK_ERROR(gl::PushGroupMarkerEXT(GLsizei(str.size() + 1), str.c_str()));
}
// fprintf(stderr, "%s%s\n", std::string(indent * 4, ' ').c_str(), str.c_str());
// indent++;

View File

@@ -249,6 +249,12 @@ std::chrono::steady_clock::duration secondsAsDuration(float duration)
gl::IsVertexArray = glIsVertexArrayOES;
}
if (extensions.find("GL_EXT_debug_marker") != std::string::npos) {
gl::InsertEventMarkerEXT = glInsertEventMarkerEXT;
gl::PushGroupMarkerEXT = glPushGroupMarkerEXT;
gl::PopGroupMarkerEXT = glPopGroupMarkerEXT;
}
if (extensions.find("GL_OES_packed_depth_stencil") != std::string::npos) {
gl::isPackedDepthStencilSupported = YES;
}

View File

@@ -218,109 +218,137 @@ void Painter::render(const Style& style, TransformState state_, TimePoint time)
}
}
// - UPLOAD PASS -------------------------------------------------------------------------------
// Uploads all required buffers and images before we do any actual rendering.
// Figure out what buckets we have to draw and what order we have to draw them in.
const auto order = determineRenderOrder(style);
tileStencilBuffer.upload();
tileBorderBuffer.upload();
spriteAtlas.upload();
lineAtlas.upload();
glyphAtlas.upload();
// - UPLOAD PASS -------------------------------------------------------------------------------
// Uploads all required buffers and images before we do any actual rendering.
{
const gl::group upload("upload");
for (const auto& item : order) {
if (item.bucket && item.bucket->needsUpload()) {
item.bucket->upload();
tileStencilBuffer.upload();
tileBorderBuffer.upload();
spriteAtlas.upload();
lineAtlas.upload();
glyphAtlas.upload();
for (const auto& item : order) {
if (item.bucket && item.bucket->needsUpload()) {
item.bucket->upload();
}
}
}
// - CLIPPING MASKS ----------------------------------------------------------------------------
// Draws the clipping masks to the stencil buffer.
{
const gl::group clip("clip");
// Update all clipping IDs.
ClipIDGenerator generator;
for (const auto& source : sources) {
generator.update(source->getLoadedTiles());
source->updateMatrices(projMatrix, state);
// Update all clipping IDs.
ClipIDGenerator generator;
for (const auto& source : sources) {
generator.update(source->getLoadedTiles());
source->updateMatrices(projMatrix, state);
}
clear();
resize();
changeMatrix();
drawClippingMasks(sources);
}
clear();
resize();
changeMatrix();
drawClippingMasks(sources);
frameHistory.record(time, state.getNormalizedZoom());
// Actually render the layers
if (debug::renderTree) { Log::Info(Event::Render, "{"); indent++; }
// TODO: Correctly compute the number of layers recursively beforehand.
const float strata_thickness = 1.0f / (order.size() + 1);
// Layer index
int i = 0;
// - OPAQUE PASS -------------------------------------------------------------------------------
// Render everything top-to-bottom by using reverse iterators. Render opaque objects first.
{
const gl::group _("opaque");
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s", indent++ * 4, "", "OPAQUE {");
}
int i = 0;
setOpaque();
for (auto it = order.rbegin(), end = order.rend(); it != end; ++it, ++i) {
const auto& item = *it;
if (item.bucket && item.tile) {
if (item.hasRenderPass(RenderPass::Opaque)) {
setStrata(i * strata_thickness);
prepareTile(*item.tile);
item.bucket->render(*this, item.layer, item.tile->id, item.tile->matrix);
}
} else {
renderBackground(item.layer);
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s", indent++ * 4, "", "OPAQUE {");
}
i = 0;
setOpaque();
for (auto it = order.rbegin(), end = order.rend(); it != end; ++it, ++i) {
const auto& item = *it;
if (item.bucket && item.tile) {
if (item.hasRenderPass(RenderPass::Opaque)) {
const gl::group group(item.layer.id + " - " + std::string(item.tile->id));
setStrata(i * strata_thickness);
prepareTile(*item.tile);
item.bucket->render(*this, item.layer, item.tile->id, item.tile->matrix);
}
} else {
const gl::group group("background");
renderBackground(item.layer);
}
}
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s", --indent * 4, "", "}");
}
}
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s", --indent * 4, "", "}");
}
// - TRANSLUCENT PASS --------------------------------------------------------------------------
// Make a second pass, rendering translucent objects. This time, we render bottom-to-top.
{
const gl::group _("translucent");
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s", indent++ * 4, "", "TRANSLUCENT {");
}
--i;
setTranslucent();
for (auto it = order.begin(), end = order.end(); it != end; ++it, --i) {
const auto& item = *it;
if (item.bucket && item.tile) {
if (item.hasRenderPass(RenderPass::Translucent)) {
setStrata(i * strata_thickness);
prepareTile(*item.tile);
item.bucket->render(*this, item.layer, item.tile->id, item.tile->matrix);
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s", indent++ * 4, "", "TRANSLUCENT {");
}
--i; // After the last iteration, this is incremented, so we have to decrement it again.
setTranslucent();
for (auto it = order.begin(), end = order.end(); it != end; ++it, --i) {
const auto& item = *it;
if (item.bucket && item.tile) {
if (item.hasRenderPass(RenderPass::Translucent)) {
const gl::group group(item.layer.id + " - " + std::string(item.tile->id));
setStrata(i * strata_thickness);
prepareTile(*item.tile);
item.bucket->render(*this, item.layer, item.tile->id, item.tile->matrix);
}
}
}
}
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s", --indent * 4, "", "}");
if (debug::renderTree) {
Log::Info(Event::Render, "%*s%s", --indent * 4, "", "}");
}
}
if (debug::renderTree) { Log::Info(Event::Render, "}"); indent--; }
// Finalize the rendering, e.g. by calling debug render calls per tile.
// This guarantees that we have at least one function per tile called.
// When only rendering layers via the stylesheet, it's possible that we don't
// ever visit a tile during rendering.
for (const auto& source : sources) {
source->finishRender(*this);
// - DEBUG PASS --------------------------------------------------------------------------------
// Renders debug overlays.
{
const gl::group _("debug");
// Finalize the rendering, e.g. by calling debug render calls per tile.
// This guarantees that we have at least one function per tile called.
// When only rendering layers via the stylesheet, it's possible that we don't
// ever visit a tile during rendering.
for (const auto& source : sources) {
source->finishRender(*this);
}
}
// TODO: Find a better way to unbind VAOs after we're done with them without introducing
// unnecessary bind(0)/bind(N) sequences.
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, 0));
MBGL_CHECK_ERROR(gl::BindVertexArray(0));
{
const gl::group _("cleanup");
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, 0));
MBGL_CHECK_ERROR(gl::BindVertexArray(0));
}
}
std::vector<RenderItem> Painter::determineRenderOrder(const Style& style) {