diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-10-26 18:06:36 -0700 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2016-11-01 18:41:52 +0100 |
commit | ed155460d3ec3777bfd95ce3d40c809e583b07de (patch) | |
tree | ce362d4154cc300b75d78ff8051ebf782834f044 | |
parent | 7b50cac49f353524457e16d3f342299e0886e963 (diff) | |
download | qtlocation-mapboxgl-ed155460d3ec3777bfd95ce3d40c809e583b07de.tar.gz |
[core] convert LineAtlas to use managed texture handling
-rw-r--r-- | src/mbgl/geometry/line_atlas.cpp | 83 | ||||
-rw-r--r-- | src/mbgl/geometry/line_atlas.hpp | 13 | ||||
-rw-r--r-- | src/mbgl/gl/context.cpp | 41 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/gl/texture.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/gl/types.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_line.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_symbol.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/style.cpp | 2 |
9 files changed, 69 insertions, 81 deletions
diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp index 50e82cc015..5e11fe5c49 100644 --- a/src/mbgl/geometry/line_atlas.cpp +++ b/src/mbgl/geometry/line_atlas.cpp @@ -11,10 +11,8 @@ namespace mbgl { -LineAtlas::LineAtlas(uint16_t w, uint16_t h) - : width(w), - height(h), - data(std::make_unique<char[]>(w * h)), +LineAtlas::LineAtlas(const Size size) + : image(size), dirty(true) { } @@ -40,11 +38,11 @@ LinePatternPos LineAtlas::getDashPosition(const std::vector<float>& dasharray, } LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatternCap patternCap) { - int n = patternCap == LinePatternCap::Round ? 7 : 0; - int dashheight = 2 * n + 1; + const uint8_t n = patternCap == LinePatternCap::Round ? 7 : 0; + const uint8_t dashheight = 2 * n + 1; const uint8_t offset = 128; - if (nextRow + dashheight > height) { + if (nextRow + dashheight > image.size.height) { Log::Warning(Event::OpenGL, "line atlas bitmap overflow"); return LinePatternPos(); } @@ -54,7 +52,7 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte length += part; } - float stretch = width / length; + float stretch = image.size.width / length; float halfWidth = stretch * 0.5; // If dasharray has an odd length, both the first and last parts // are dashes and should be joined seamlessly. @@ -62,7 +60,7 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte for (int y = -n; y <= n; y++) { int row = nextRow + n + y; - int index = width * row; + int index = image.size.width * row; float left = 0; float right = dasharray[0]; @@ -72,7 +70,7 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte left -= dasharray.back(); } - for (int x = 0; x < width; x++) { + for (uint32_t x = 0; x < image.size.width; x++) { while (right < x / stretch) { left = right; @@ -104,13 +102,13 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte signedDistance = int((inside ? 1 : -1) * dist); } - data[index + x] = fmax(0, fmin(255, signedDistance + offset)); + image.data[index + x] = fmax(0, fmin(255, signedDistance + offset)); } } LinePatternPos position; - position.y = (0.5 + nextRow + n) / height; - position.height = (2.0 * n) / height; + position.y = (0.5 + nextRow + n) / image.size.height; + position.height = (2.0 * n) / image.size.height; position.width = length; nextRow += dashheight; @@ -120,59 +118,24 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte return position; } -void LineAtlas::upload(gl::Context& context, gl::TextureUnit unit) { - if (dirty) { - bind(context, unit); - } +Size LineAtlas::getSize() const { + return image.size; } -void LineAtlas::bind(gl::Context& context, gl::TextureUnit unit) { - bool first = false; +void LineAtlas::upload(gl::Context& context, gl::TextureUnit unit) { if (!texture) { - texture = context.createTexture(); - context.activeTexture = unit; - context.texture[unit] = *texture; - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - first = true; - } else if (context.texture[unit] != *texture) { - context.activeTexture = unit; - context.texture[unit] = *texture; + texture = context.createTexture(image, unit); + } else if (dirty) { + context.updateTexture(*texture, image, unit); } - if (dirty) { - context.activeTexture = unit; - if (first) { - MBGL_CHECK_ERROR(glTexImage2D( - GL_TEXTURE_2D, // GLenum target - 0, // GLint level - GL_ALPHA, // GLint internalformat - width, // GLsizei width - height, // GLsizei height - 0, // GLint border - GL_ALPHA, // GLenum format - GL_UNSIGNED_BYTE, // GLenum type - data.get() // const GLvoid * data - )); - } else { - MBGL_CHECK_ERROR(glTexSubImage2D( - GL_TEXTURE_2D, // GLenum target - 0, // GLint level - 0, // GLint xoffset - 0, // GLint yoffset - width, // GLsizei width - height, // GLsizei height - GL_ALPHA, // GLenum format - GL_UNSIGNED_BYTE, // GLenum type - data.get() // const GLvoid *pixels - )); - } - + dirty = false; +} - dirty = false; - } +void LineAtlas::bind(gl::Context& context, gl::TextureUnit unit) { + upload(context, unit); + context.bindTexture(*texture, unit, gl::TextureFilter::Linear, gl::TextureMipMap::No, + gl::TextureWrap::Repeat, gl::TextureWrap::Clamp); } } // namespace mbgl diff --git a/src/mbgl/geometry/line_atlas.hpp b/src/mbgl/geometry/line_atlas.hpp index 66a2343a42..b1e7a670c1 100644 --- a/src/mbgl/geometry/line_atlas.hpp +++ b/src/mbgl/geometry/line_atlas.hpp @@ -1,6 +1,8 @@ #pragma once +#include <mbgl/gl/texture.hpp> #include <mbgl/gl/object.hpp> +#include <mbgl/util/image.hpp> #include <mbgl/util/optional.hpp> #include <vector> @@ -27,7 +29,7 @@ enum class LinePatternCap : bool { class LineAtlas { public: - LineAtlas(uint16_t width, uint16_t height); + LineAtlas(Size); ~LineAtlas(); // Binds the atlas texture to the GPU, and uploads data if it is out of date. @@ -40,14 +42,13 @@ public: LinePatternPos getDashPosition(const std::vector<float>&, LinePatternCap); LinePatternPos addDash(const std::vector<float>& dasharray, LinePatternCap); - const uint16_t width; - const uint16_t height; + Size getSize() const; private: - const std::unique_ptr<char[]> data; + const AlphaImage image; bool dirty; - mbgl::optional<gl::UniqueTexture> texture; - int nextRow = 0; + mbgl::optional<gl::Texture> texture; + uint32_t nextRow = 0; std::unordered_map<size_t, LinePatternPos> positions; }; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 41f02b6364..fc35028473 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -211,19 +211,38 @@ void Context::updateTexture( void Context::bindTexture(Texture& obj, TextureUnit unit, TextureFilter filter, - TextureMipMap mipmap) { - if (filter != obj.filter || mipmap != obj.mipmap) { + TextureMipMap mipmap, + TextureWrap wrapX, + TextureWrap wrapY) { + if (filter != obj.filter || mipmap != obj.mipmap || wrapX != obj.wrapX || wrapY != obj.wrapY) { activeTexture = unit; texture[unit] = obj.texture; - MBGL_CHECK_ERROR(glTexParameteri( - GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - filter == TextureFilter::Linear - ? (mipmap == TextureMipMap::Yes ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR) - : (mipmap == TextureMipMap::Yes ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST))); - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, - filter == TextureFilter::Linear ? GL_LINEAR : GL_NEAREST)); - obj.filter = filter; - obj.mipmap = mipmap; + + if (filter != obj.filter || mipmap != obj.mipmap) { + MBGL_CHECK_ERROR(glTexParameteri( + GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + filter == TextureFilter::Linear + ? (mipmap == TextureMipMap::Yes ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR) + : (mipmap == TextureMipMap::Yes ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST))); + MBGL_CHECK_ERROR( + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + filter == TextureFilter::Linear ? GL_LINEAR : GL_NEAREST)); + obj.filter = filter; + obj.mipmap = mipmap; + } + if (wrapX != obj.wrapX) { + + MBGL_CHECK_ERROR( + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + wrapX == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT)); + obj.wrapX = wrapX; + } + if (wrapY != obj.wrapY) { + MBGL_CHECK_ERROR( + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + wrapY == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT)); + obj.wrapY = wrapY; + } } else if (texture[unit] != obj.texture) { // We are checking first to avoid setting the active texture without a subsequent // texture bind. diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 4e9320f7d1..e0f9b871cc 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -86,7 +86,9 @@ public: void bindTexture(Texture&, TextureUnit = 0, TextureFilter = TextureFilter::Nearest, - TextureMipMap = TextureMipMap::No); + TextureMipMap = TextureMipMap::No, + TextureWrap wrapX = TextureWrap::Clamp, + TextureWrap wrapY = TextureWrap::Clamp); void clear(optional<mbgl::Color> color, optional<float> depth, diff --git a/src/mbgl/gl/texture.hpp b/src/mbgl/gl/texture.hpp index 802dac9eb2..5330689ac2 100644 --- a/src/mbgl/gl/texture.hpp +++ b/src/mbgl/gl/texture.hpp @@ -12,6 +12,8 @@ public: UniqueTexture texture; TextureFilter filter = TextureFilter::Nearest; TextureMipMap mipmap = TextureMipMap::No; + TextureWrap wrapX = TextureWrap::Clamp; + TextureWrap wrapY = TextureWrap::Clamp; }; } // namespace gl diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 10cf0a9730..16a37d58c1 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -46,6 +46,7 @@ enum class RenderbufferType : uint32_t { enum class TextureMipMap : bool { No = false, Yes = true }; enum class TextureFilter : bool { Nearest = false, Linear = true }; +enum class TextureWrap : bool { Clamp, Repeat }; enum class TextureFormat : uint32_t { RGBA = 0x1908, Alpha = 0x1906, diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp index 9fa6b15559..377c956e7c 100644 --- a/src/mbgl/renderer/painter_line.cpp +++ b/src/mbgl/renderer/painter_line.cpp @@ -55,7 +55,7 @@ void Painter::renderLine(PaintParameters& parameters, posA, posB, layer.impl->dashLineWidth, - lineAtlas->width)); + lineAtlas->getSize().width)); } else if (!properties.linePattern.value.from.empty()) { optional<SpriteAtlasPosition> posA = spriteAtlas->getPosition( diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index e13c04120c..9e3638a3a8 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -101,7 +101,7 @@ void Painter::renderSymbol(PaintParameters& parameters, auto values = layer.impl->textPropertyValues(layout); - const Size texsize = glyphAtlas->getSize()x§; + const Size texsize = glyphAtlas->getSize(); if (values.hasHalo()) { draw(parameters.shaders.symbolGlyph, diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index bcc062f82e..3c2b97b65d 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -40,7 +40,7 @@ Style::Style(FileSource& fileSource_, float pixelRatio) : fileSource(fileSource_), glyphAtlas(std::make_unique<GlyphAtlas>(Size{ 2048, 2048 }, fileSource)), spriteAtlas(std::make_unique<SpriteAtlas>(Size{ 1024, 1024 }, pixelRatio)), - lineAtlas(std::make_unique<LineAtlas>(256, 512)), + lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })), observer(&nullObserver) { glyphAtlas->setObserver(this); spriteAtlas->setObserver(this); |