summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2016-06-22 16:15:37 +0200
committerKonstantin Käfer <mail@kkaefer.com>2016-07-04 14:24:32 +0200
commit1311ed24ad7b1f787727f086c341cd1a898fe06b (patch)
tree5235d6f78e911dfdfa44dd73c5a82dde092fddd0 /src
parent9f18d19a2016c193a71a10beb5e4dca79ad6189b (diff)
downloadqtlocation-mapboxgl-1311ed24ad7b1f787727f086c341cd1a898fe06b.tar.gz
[core] refactor Raster and allow explicit mipmapping levels
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/renderer/raster_bucket.cpp4
-rw-r--r--src/mbgl/util/raster.cpp62
-rw-r--r--src/mbgl/util/raster.hpp40
3 files changed, 55 insertions, 51 deletions
diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp
index 2020860396..1cf6f2c413 100644
--- a/src/mbgl/renderer/raster_bucket.cpp
+++ b/src/mbgl/renderer/raster_bucket.cpp
@@ -31,9 +31,9 @@ void RasterBucket::drawRaster(RasterShader& shader,
gl::Config& config,
gl::ObjectStore& store) {
config.activeTexture = GL_TEXTURE0;
- raster.bind(true, store);
+ raster.bind(store, Raster::Scaling::Linear);
config.activeTexture = GL_TEXTURE1;
- raster.bind(true, store);
+ raster.bind(store, Raster::Scaling::Linear);
array.bind(shader, vertices, BUFFER_OFFSET_0, store);
MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)vertices.index()));
}
diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp
index b4e838ec00..7417c8bcd5 100644
--- a/src/mbgl/util/raster.cpp
+++ b/src/mbgl/util/raster.cpp
@@ -10,53 +10,67 @@
namespace mbgl {
bool Raster::isLoaded() const {
- std::lock_guard<std::mutex> lock(mtx);
return loaded;
}
-void Raster::load(PremultipliedImage image) {
+void Raster::load(PremultipliedImage image, uint32_t mipmapLevel) {
assert(image.data.get());
- img = std::move(image);
- width = GLsizei(img.width);
- height = GLsizei(img.height);
+ if (images.size() <= mipmapLevel) {
+ images.resize(mipmapLevel + 1);
+ }
+ images.at(mipmapLevel) = std::move(image);
- std::lock_guard<std::mutex> lock(mtx);
loaded = true;
}
+void Raster::bind(gl::ObjectStore& store, Scaling newFilter, MipMap newMipMap) {
+ bool updateFilter = false;
-void Raster::bind(bool linear, gl::ObjectStore& store) {
- if (!width || !height) {
- Log::Error(Event::OpenGL, "trying to bind texture without dimension");
- return;
- }
-
- if (img.data && !texture) {
- upload(store);
- } else if (texture) {
+ if (!texture) {
+ if (images.empty()) {
+ Log::Error(Event::OpenGL, "trying to bind texture without images");
+ return;
+ } else {
+ upload(store);
+ updateFilter = true;
+ }
+ } else {
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
+ updateFilter = (filter != newFilter || mipmap != newMipMap);
}
- GLint new_filter = linear ? GL_LINEAR : GL_NEAREST;
- if (new_filter != this->filter) {
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, new_filter));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, new_filter));
- filter = new_filter;
+ if (updateFilter) {
+ filter = newFilter;
+ mipmap = newMipMap;
+ MBGL_CHECK_ERROR(glTexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ filter == Scaling::Linear
+ ? (mipmap == MipMap::Yes ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR)
+ : (mipmap == MipMap::Yes ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST)));
+ MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ filter == Scaling::Linear ? GL_LINEAR : GL_NEAREST));
}
}
void Raster::upload(gl::ObjectStore& store) {
- if (img.data && !texture) {
+ if (!images.empty() && !texture) {
texture = store.createTexture();
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture));
#ifndef GL_ES_VERSION_2_0
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
+ MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, images.size()));
#endif
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data.get()));
- img.data.reset();
+ GLint level = 0;
+ for (auto& img : images) {
+ assert(img.data.get());
+ MBGL_CHECK_ERROR(glTexImage2D(
+ GL_TEXTURE_2D, level++, GL_RGBA, static_cast<GLsizei>(img.width),
+ static_cast<GLsizei>(img.height), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data.get()));
+ }
+ images.clear();
+ images.shrink_to_fit();
}
}
diff --git a/src/mbgl/util/raster.hpp b/src/mbgl/util/raster.hpp
index 17319394c4..6223440bd6 100644
--- a/src/mbgl/util/raster.hpp
+++ b/src/mbgl/util/raster.hpp
@@ -2,22 +2,21 @@
#include <mbgl/gl/object_store.hpp>
#include <mbgl/util/image.hpp>
-#include <mbgl/util/ptr.hpp>
-#include <mbgl/util/chrono.hpp>
#include <mbgl/util/optional.hpp>
-
-#include <mutex>
+#include <mbgl/util/atomic.hpp>
namespace mbgl {
-class Raster : public std::enable_shared_from_this<Raster> {
-
+class Raster {
public:
+ enum class MipMap : bool { No = false, Yes = true };
+ enum class Scaling : bool { Nearest = false, Linear = true };
+
// load image data
- void load(PremultipliedImage);
+ void load(PremultipliedImage, uint32_t mipmapLevel = 0);
// bind current texture
- void bind(bool linear, gl::ObjectStore&);
+ void bind(gl::ObjectStore&, Scaling = Scaling::Nearest, MipMap = MipMap::No);
// uploads the texture if it hasn't been uploaded yet.
void upload(gl::ObjectStore&);
@@ -25,28 +24,19 @@ public:
// loaded status
bool isLoaded() const;
-public:
- // loaded image dimensions
- GLsizei width = 0;
- GLsizei height = 0;
-
- // GL buffer object handle.
- mbgl::optional<gl::UniqueTexture> texture;
-
- // texture opacity
- double opacity = 0;
-
private:
- mutable std::mutex mtx;
-
// raw pixels have been loaded
- bool loaded = false;
+ util::Atomic<bool> loaded { false };
- // min/mag filter
- GLint filter = 0;
+ // filters
+ Scaling filter = Scaling::Nearest;
+ MipMap mipmap = MipMap::No;
// the raw pixels
- PremultipliedImage img;
+ std::vector<PremultipliedImage> images;
+
+ // GL buffer object handle.
+ mbgl::optional<gl::UniqueTexture> texture;
};
} // namespace mbgl