summaryrefslogtreecommitdiff
path: root/src/mbgl/gl
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2019-03-07 17:50:02 +0100
committerKonstantin Käfer <mail@kkaefer.com>2019-03-11 14:04:19 +0100
commitc83d9a6cc56b88b97ee1b455ed1d02b85fdd43e0 (patch)
tree4686cced26b195374c97f2c389dc39482309484c /src/mbgl/gl
parent0bb5e431621b45d29f812a25d8cf26cd26006067 (diff)
downloadqtlocation-mapboxgl-c83d9a6cc56b88b97ee1b455ed1d02b85fdd43e0.tar.gz
[core] add texture bindings to draw call instead of Context member fnupstream/gfx-refactor-3
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r--src/mbgl/gl/context.cpp58
-rw-r--r--src/mbgl/gl/context.hpp11
-rw-r--r--src/mbgl/gl/program.hpp18
-rw-r--r--src/mbgl/gl/texture.cpp54
-rw-r--r--src/mbgl/gl/texture.hpp52
-rw-r--r--src/mbgl/gl/texture_resource.hpp4
-rw-r--r--src/mbgl/gl/uniform.cpp5
-rw-r--r--src/mbgl/gl/uniform.hpp2
8 files changed, 137 insertions, 67 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index 2758e236e4..ca06ab660d 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -3,6 +3,7 @@
#include <mbgl/gl/vertex_buffer_resource.hpp>
#include <mbgl/gl/index_buffer_resource.hpp>
#include <mbgl/gl/texture_resource.hpp>
+#include <mbgl/gl/texture.hpp>
#include <mbgl/gl/debugging_extension.hpp>
#include <mbgl/gl/vertex_array_extension.hpp>
#include <mbgl/gl/program_binary_extension.hpp>
@@ -511,16 +512,15 @@ Context::createFramebuffer(const gfx::Texture& color,
return { depthTarget.size, std::move(fbo) };
}
-std::unique_ptr<const gfx::TextureResource>
+std::unique_ptr<gfx::TextureResource>
Context::createTextureResource(const Size size,
const void* data,
gfx::TexturePixelType format,
- uint8_t unit,
gfx::TextureChannelDataType type) {
auto obj = createUniqueTexture();
- std::unique_ptr<const gfx::TextureResource> resource = std::make_unique<gl::TextureResource>(std::move(obj));
+ std::unique_ptr<gfx::TextureResource> resource = std::make_unique<gl::TextureResource>(std::move(obj));
pixelStoreUnpack = { 1 };
- updateTextureResource(*resource, size, data, format, unit, type);
+ updateTextureResource(*resource, size, data, format, type);
// We are using clamp to edge here since OpenGL ES doesn't allow GL_REPEAT on NPOT textures.
// We use those when the pixelRatio isn't a power of two, e.g. on iPhone 6 Plus.
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
@@ -534,60 +534,16 @@ void Context::updateTextureResource(const gfx::TextureResource& resource,
const Size size,
const void* data,
gfx::TexturePixelType format,
- uint8_t unit,
gfx::TextureChannelDataType type) {
- activeTextureUnit = unit;
- texture[unit] = reinterpret_cast<const gl::TextureResource&>(resource).texture;
+ // Always use texture unit 0 for manipulating it.
+ activeTextureUnit = 0;
+ texture[0] = reinterpret_cast<const gl::TextureResource&>(resource).texture;
MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, Enum<gfx::TexturePixelType>::to(format),
size.width, size.height, 0,
Enum<gfx::TexturePixelType>::to(format),
Enum<gfx::TextureChannelDataType>::to(type), data));
}
-void Context::bindTexture(gfx::Texture& obj,
- uint8_t unit,
- gfx::TextureFilterType filter,
- gfx::TextureMipMapType mipmap,
- gfx::TextureWrapType wrapX,
- gfx::TextureWrapType wrapY) {
- TextureID id = reinterpret_cast<const gl::TextureResource&>(*obj.resource).texture;
- if (filter != obj.filter || mipmap != obj.mipmap || wrapX != obj.wrapX || wrapY != obj.wrapY) {
- activeTextureUnit = unit;
- texture[unit] = id;
-
- if (filter != obj.filter || mipmap != obj.mipmap) {
- MBGL_CHECK_ERROR(glTexParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- filter == gfx::TextureFilterType::Linear
- ? (mipmap == gfx::TextureMipMapType::Yes ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR)
- : (mipmap == gfx::TextureMipMapType::Yes ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST)));
- MBGL_CHECK_ERROR(
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- filter == gfx::TextureFilterType::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 == gfx::TextureWrapType::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 == gfx::TextureWrapType::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
- obj.wrapY = wrapY;
- }
- } else if (texture[unit] != id) {
- // We are checking first to avoid setting the active texture without a subsequent
- // texture bind.
- activeTextureUnit = unit;
- texture[unit] = id;
- }
-}
-
void Context::reset() {
std::copy(pooledTextures.begin(), pooledTextures.end(), std::back_inserter(abandonedTextures));
pooledTextures.resize(0);
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index 1200e3b49a..51b79200ba 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -88,13 +88,6 @@ public:
return { size, readFramebuffer(size, format, flip) };
}
- void bindTexture(gfx::Texture&,
- uint8_t unit = 0,
- gfx::TextureFilterType = gfx::TextureFilterType::Nearest,
- gfx::TextureMipMapType = gfx::TextureMipMapType::No,
- gfx::TextureWrapType wrapX = gfx::TextureWrapType::Clamp,
- gfx::TextureWrapType wrapY = gfx::TextureWrapType::Clamp) override;
-
#if not MBGL_USE_GLES2
template <typename Image>
void drawPixels(const Image& image) {
@@ -220,8 +213,8 @@ private:
std::unique_ptr<const gfx::IndexBufferResource> createIndexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override;
void updateIndexBufferResource(const gfx::IndexBufferResource&, const void* data, std::size_t size) override;
- std::unique_ptr<const gfx::TextureResource> createTextureResource(Size, const void* data, gfx::TexturePixelType, uint8_t, gfx::TextureChannelDataType) override;
- void updateTextureResource(const gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, uint8_t, gfx::TextureChannelDataType) override;
+ std::unique_ptr<gfx::TextureResource> createTextureResource(Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override;
+ void updateTextureResource(const gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override;
UniqueFramebuffer createFramebuffer();
UniqueRenderbuffer createRenderbuffer(RenderbufferType, Size size);
diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp
index 050ec6c268..ffa3e07391 100644
--- a/src/mbgl/gl/program.hpp
+++ b/src/mbgl/gl/program.hpp
@@ -8,6 +8,7 @@
#include <mbgl/gl/vertex_array.hpp>
#include <mbgl/gl/attribute.hpp>
#include <mbgl/gl/uniform.hpp>
+#include <mbgl/gl/texture.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/logging.hpp>
@@ -20,7 +21,7 @@
namespace mbgl {
namespace gl {
-template <class P, class As, class Us, class TBs>
+template <class P, class As, class Us, class TextureList>
class Program {
public:
using Primitive = P;
@@ -29,7 +30,7 @@ public:
using UniformValues = typename Uniforms::Values;
using AttributeBindings = typename Attributes::Bindings;
- using TextureBindings = TBs;
+ using TextureBindings = gfx::TextureBindings<TextureList>;
Program(Context& context, const std::string& vertexSource, const std::string& fragmentSource)
: program(
@@ -37,13 +38,15 @@ public:
context.createShader(ShaderType::Fragment, fragmentSource))),
uniformsState((context.linkProgram(program), Uniforms::bindLocations(program))),
attributeLocations(Attributes::bindLocations(context, program)) {
-
// Re-link program after manually binding only active attributes in Attributes::bindLocations
context.linkProgram(program);
// We have to re-initialize the uniforms state from the bindings as the uniform locations
// get shifted on some implementations
uniformsState = Uniforms::bindLocations(program);
+
+ // Texture units are specified via uniforms as well, so we need query their locations
+ textures.queryLocations(program);
}
template <class BinaryProgram>
@@ -51,6 +54,7 @@ public:
: program(context.createProgram(binaryProgram.format(), binaryProgram.code())),
uniformsState(Uniforms::loadNamedLocations(binaryProgram)),
attributeLocations(Attributes::loadNamedLocations(binaryProgram)) {
+ textures.loadNamedLocations(binaryProgram);
}
static Program createProgram(gl::Context& context,
@@ -108,7 +112,8 @@ public:
if (auto binaryProgram = context.getBinaryProgram(program)) {
return BinaryProgram{ binaryProgram->first, std::move(binaryProgram->second),
identifier, Attributes::getNamedLocations(attributeLocations),
- Uniforms::getNamedLocations(uniformsState) };
+ Uniforms::getNamedLocations(uniformsState),
+ textures.getNamedLocations() };
}
return {};
}
@@ -129,8 +134,6 @@ public:
std::size_t indexLength) {
static_assert(std::is_same<Primitive, typename DrawMode::Primitive>::value, "incompatible draw mode");
- (void)textureBindings;
-
context.setDrawMode(drawMode);
context.setDepthMode(depthMode);
context.setStencilMode(stencilMode);
@@ -141,6 +144,8 @@ public:
Uniforms::bind(uniformsState, uniformValues);
+ textures.bind(context, textureBindings);
+
vertexArray.bind(context,
indexBuffer,
Attributes::toBindingArray(attributeLocations, attributeBindings));
@@ -155,6 +160,7 @@ private:
typename Uniforms::State uniformsState;
typename Attributes::Locations attributeLocations;
+ gl::Textures<TextureList> textures;
};
} // namespace gl
diff --git a/src/mbgl/gl/texture.cpp b/src/mbgl/gl/texture.cpp
new file mode 100644
index 0000000000..2b41e7ae8e
--- /dev/null
+++ b/src/mbgl/gl/texture.cpp
@@ -0,0 +1,54 @@
+#include <mbgl/gl/texture.hpp>
+#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/texture_resource.hpp>
+#include <mbgl/gl/defines.hpp>
+
+namespace mbgl {
+namespace gl {
+
+using namespace platform;
+
+void bindTexture(gl::Context& context, const uint8_t unit, const gfx::TextureBinding& binding) {
+ auto& resource = reinterpret_cast<gl::TextureResource&>(*binding.resource);
+ if (binding.filter != resource.filter || binding.mipmap != resource.mipmap ||
+ binding.wrapX != resource.wrapX || binding.wrapY != resource.wrapY) {
+ context.activeTextureUnit = unit;
+ context.texture[unit] = resource.texture;
+
+ if (binding.filter != resource.filter || binding.mipmap != resource.mipmap) {
+ MBGL_CHECK_ERROR(glTexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ binding.filter == gfx::TextureFilterType::Linear
+ ? (binding.mipmap == gfx::TextureMipMapType::Yes ? GL_LINEAR_MIPMAP_NEAREST
+ : GL_LINEAR)
+ : (binding.mipmap == gfx::TextureMipMapType::Yes ? GL_NEAREST_MIPMAP_NEAREST
+ : GL_NEAREST)));
+ MBGL_CHECK_ERROR(glTexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ binding.filter == gfx::TextureFilterType::Linear ? GL_LINEAR : GL_NEAREST));
+ resource.filter = binding.filter;
+ resource.mipmap = binding.mipmap;
+ }
+ if (binding.wrapX != resource.wrapX) {
+
+ MBGL_CHECK_ERROR(glTexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+ binding.wrapX == gfx::TextureWrapType::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
+ resource.wrapX = binding.wrapX;
+ }
+ if (binding.wrapY != resource.wrapY) {
+ MBGL_CHECK_ERROR(glTexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+ binding.wrapY == gfx::TextureWrapType::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
+ resource.wrapY = binding.wrapY;
+ }
+ } else if (context.texture[unit] != resource.texture) {
+ // We are checking first to avoid setting the active texture without a subsequent
+ // texture bind.
+ context.activeTextureUnit = unit;
+ context.texture[unit] = resource.texture;
+ }
+}
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/texture.hpp b/src/mbgl/gl/texture.hpp
new file mode 100644
index 0000000000..8230be1652
--- /dev/null
+++ b/src/mbgl/gl/texture.hpp
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <mbgl/gfx/texture.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/ignore.hpp>
+
+#include <vector>
+#include <string>
+
+namespace mbgl {
+namespace gl {
+
+class Context;
+
+void bindTexture(gl::Context&, uint8_t unit, const gfx::TextureBinding&);
+
+template <class>
+class Textures;
+
+template <class... Ts>
+class Textures<TypeList<Ts...>> {
+ using State =
+ IndexedTuple<TypeList<Ts...>, TypeList<ExpandToType<Ts, gl::UniformState<uint8_t>>...>>;
+ using NamedLocations = std::vector<std::pair<const std::string, gl::UniformLocation>>;
+
+public:
+ void queryLocations(const ProgramID& id) {
+ state = State{ gl::uniformLocation(id, Ts::name())... };
+ }
+
+ template <class BinaryProgram>
+ void loadNamedLocations(const BinaryProgram& program) {
+ state = State{ program.textureLocation(Ts::name())... };
+ }
+
+ NamedLocations getNamedLocations() const {
+ return NamedLocations{ { Ts::name(), state.template get<Ts>().location }... };
+ }
+
+ void bind(gl::Context& context, const gfx::TextureBindings<TypeList<Ts...>>& bindings) {
+ util::ignore(
+ { (state.template get<Ts>() = TypeIndex<Ts, Ts...>::value,
+ gl::bindTexture(context, TypeIndex<Ts, Ts...>::value, bindings.template get<Ts>()),
+ 0)... });
+ }
+
+private:
+ State state;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/texture_resource.hpp b/src/mbgl/gl/texture_resource.hpp
index 4803f9b7f4..ed742e75b7 100644
--- a/src/mbgl/gl/texture_resource.hpp
+++ b/src/mbgl/gl/texture_resource.hpp
@@ -12,6 +12,10 @@ public:
}
UniqueTexture texture;
+ gfx::TextureFilterType filter = gfx::TextureFilterType::Nearest;
+ gfx::TextureMipMapType mipmap = gfx::TextureMipMapType::No;
+ gfx::TextureWrapType wrapX = gfx::TextureWrapType::Clamp;
+ gfx::TextureWrapType wrapY = gfx::TextureWrapType::Clamp;
};
} // namespace gl
diff --git a/src/mbgl/gl/uniform.cpp b/src/mbgl/gl/uniform.cpp
index 21017d6436..8d99d4b467 100644
--- a/src/mbgl/gl/uniform.cpp
+++ b/src/mbgl/gl/uniform.cpp
@@ -68,6 +68,11 @@ void bindUniform<uint32_t>(UniformLocation location, const uint32_t& t) {
}
template <>
+void bindUniform<uint8_t>(UniformLocation location, const uint8_t& t) {
+ bindUniform(location, int32_t(t));
+}
+
+template <>
void bindUniform<Color>(UniformLocation location, const Color& t) {
bindUniform(location, std::array<float, 4> {{ t.r, t.g, t.b, t.a }});
}
diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp
index c5aa2d6c39..3827015bb3 100644
--- a/src/mbgl/gl/uniform.hpp
+++ b/src/mbgl/gl/uniform.hpp
@@ -35,7 +35,7 @@ ActiveUniforms activeUniforms(ProgramID);
template <class Value>
class UniformState {
public:
- UniformState(UniformLocation location_) : location(std::move(location_)) {
+ UniformState(UniformLocation location_ = -1) : location(std::move(location_)) {
}
void operator=(const Value& value) {