summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2016-10-26 18:06:36 -0700
committerKonstantin Käfer <mail@kkaefer.com>2016-11-01 18:41:52 +0100
commited155460d3ec3777bfd95ce3d40c809e583b07de (patch)
treece362d4154cc300b75d78ff8051ebf782834f044
parent7b50cac49f353524457e16d3f342299e0886e963 (diff)
downloadqtlocation-mapboxgl-ed155460d3ec3777bfd95ce3d40c809e583b07de.tar.gz
[core] convert LineAtlas to use managed texture handling
-rw-r--r--src/mbgl/geometry/line_atlas.cpp83
-rw-r--r--src/mbgl/geometry/line_atlas.hpp13
-rw-r--r--src/mbgl/gl/context.cpp41
-rw-r--r--src/mbgl/gl/context.hpp4
-rw-r--r--src/mbgl/gl/texture.hpp2
-rw-r--r--src/mbgl/gl/types.hpp1
-rw-r--r--src/mbgl/renderer/painter_line.cpp2
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp2
-rw-r--r--src/mbgl/style/style.cpp2
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);