summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2019-11-19 14:50:56 +0100
committerKonstantin Käfer <mail@kkaefer.com>2019-11-22 16:36:17 +0100
commit3600dd8a1a4d91290d752d699ed964eab03bb1a5 (patch)
tree8c2a1c0fca867d1c8be62f3766f81fa1f6c45d71
parent17a544176807538c9e7a85048b81b014e97566e9 (diff)
downloadqtlocation-mapboxgl-3600dd8a1a4d91290d752d699ed964eab03bb1a5.tar.gz
[core] fix rendering of dashed lines with round caps
In https://github.com/mapbox/mapbox-gl-native/pull/15862, we introduced individual textures for line dash patterns to eliminate atlas overflows. Unfortunately, this broke dashed lines that had round caps (dashed lines with straight caps still rendered correctly). Line pattern textures for round caps were now using 256×15 pixel textures. The OpenGL ES 2.0 spec, section 3.8.2 states: Calling a sampler from a fragment shader will return `(R,G,B,A) = (0,0,0,1)` if any of the following conditions are true: […] - A two-dimensional sampler is called, the corresponding texture image is a non-power-of-two image […], and either the texture wrap mode is not `CLAMP_TO_EDGE`, or the minification filter is neither `NEAREST` nor `LINEAR`. […] This means that texture lookups won't work for NPOT textures unless they use `GL_CLAMP_TO_EDGE`. We're using `GL_CLAMP_TO_EDGE` for the vertical direction, but GL_REPEAT for the horizontal direction, which means that we need a power-of-two texture for our line dash patterns to work on OpenGL ES 2.0 conforming implementations. Fortunately, this just means changing the height from 15 to 16, and from 30 to 32, so we don't waste many pixels.
-rw-r--r--src/mbgl/geometry/line_atlas.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp
index 2e4de3edbe..f272101a5b 100644
--- a/src/mbgl/geometry/line_atlas.cpp
+++ b/src/mbgl/geometry/line_atlas.cpp
@@ -1,5 +1,6 @@
#include <mbgl/geometry/line_atlas.hpp>
#include <mbgl/gfx/upload_pass.hpp>
+#include <mbgl/math/log2.hpp>
#include <mbgl/math/minmax.hpp>
#include <mbgl/util/hash.hpp>
#include <mbgl/util/logging.hpp>
@@ -107,8 +108,25 @@ DashPatternTexture::DashPatternTexture(const std::vector<float>& from_,
const LinePatternCap cap) {
const bool patternsIdentical = from_ == to_;
const int32_t patternHeight = cap == LinePatternCap::Round ? 15 : 1;
-
- AlphaImage image({256, static_cast<uint32_t>((patternsIdentical ? 1 : 2) * patternHeight)});
+ const uint32_t height = (patternsIdentical ? 1 : 2) * patternHeight;
+
+ // The OpenGL ES 2.0 spec, section 3.8.2 states:
+ //
+ // Calling a sampler from a fragment shader will return (R,G,B,A) = (0,0,0,1) if any of the
+ // following conditions are true:
+ // […]
+ // - A two-dimensional sampler is called, the corresponding texture image is a
+ // non-power-of-two image […], and either the texture wrap mode is not CLAMP_TO_EDGE, or
+ // the minification filter is neither NEAREST nor LINEAR.
+ // […]
+ //
+ // This means that texture lookups won't work for NPOT textures unless they use GL_CLAMP_TO_EDGE.
+ // We're using GL_CLAMP_TO_EDGE for the vertical direction, but GL_REPEAT for the horizontal
+ // direction, which means that we need a power-of-two texture for our line dash patterns to work
+ // on OpenGL ES 2.0 conforming implementations. Fortunately, this just means changing the height
+ // from 15 to 16, and from 30 to 32, so we don't waste many pixels.
+ const uint32_t textureHeight = 1 << util::ceil_log2(height);
+ AlphaImage image({256, textureHeight});
from = addDashPattern(image, 0, from_, cap);
to = patternsIdentical ? from : addDashPattern(image, patternHeight, to_, cap);