diff options
author | Vladimir Agafonkin <agafonkin@gmail.com> | 2018-02-07 17:09:12 +0200 |
---|---|---|
committer | Vladimir Agafonkin <agafonkin@gmail.com> | 2018-02-07 17:09:12 +0200 |
commit | 186c04e8bd3785b4a3a28efccb9896d3209c6bb8 (patch) | |
tree | 082eb618c6261c0669a0f1f1f3714310574a94ca | |
parent | 62d2b755086db3c48f0d16155d75adfc2f8be123 (diff) | |
download | qtlocation-mapboxgl-186c04e8bd3785b4a3a28efccb9896d3209c6bb8.tar.gz |
use half-float texture for heatmap if possible
Co-Authored-By: Konstantin Käfer <mail@kkaefer.com>
-rw-r--r-- | src/mbgl/gl/context.cpp | 29 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 23 | ||||
-rw-r--r-- | src/mbgl/gl/types.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_heatmap_layer.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/util/offscreen_texture.cpp | 22 | ||||
-rw-r--r-- | src/mbgl/util/offscreen_texture.hpp | 6 |
6 files changed, 73 insertions, 24 deletions
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index b6244d58c7..f810857968 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -60,6 +60,14 @@ static_assert(std::is_same<std::underlying_type_t<TextureFormat>, GLenum>::value static_assert(underlying_type(TextureFormat::RGBA) == GL_RGBA, "OpenGL type mismatch"); static_assert(underlying_type(TextureFormat::Alpha) == GL_ALPHA, "OpenGL type mismatch"); +static_assert(std::is_same<std::underlying_type_t<TextureType>, GLenum>::value, "OpenGL type mismatch"); +static_assert(underlying_type(TextureType::UnsignedByte) == GL_UNSIGNED_BYTE, "OpenGL type mismatch"); +#if MBGL_USE_GLES2 +static_assert(underlying_type(TextureType::HalfFloat) == GL_HALF_FLOAT_OES, "OpenGL type mismatch"); +#else +static_assert(underlying_type(TextureType::HalfFloat) == GL_HALF_FLOAT_ARB, "OpenGL type mismatch"); +#endif + static_assert(underlying_type(UniformDataType::Float) == GL_FLOAT, "OpenGL type mismatch"); static_assert(underlying_type(UniformDataType::FloatVec2) == GL_FLOAT_VEC2, "OpenGL type mismatch"); static_assert(underlying_type(UniformDataType::FloatVec3) == GL_FLOAT_VEC3, "OpenGL type mismatch"); @@ -116,6 +124,15 @@ void Context::initializeExtensions(const std::function<gl::ProcAddress(const cha programBinary = std::make_unique<extension::ProgramBinary>(fn); #endif +#if MBGL_USE_GLES2 + constexpr const char* halfFloatExtensionName = "OES_texture_half_float"; +#else + constexpr const char* halfFloatExtensionName = "ARB_half_float_pixel"; +#endif + if (strstr(extensions, halfFloatExtensionName) != nullptr) { + halfFloat = true; + } + if (!supportsVertexArrays()) { Log::Warning(Event::OpenGL, "Not using Vertex Array Objects"); } @@ -271,6 +288,10 @@ bool Context::supportsVertexArrays() const { vertexArray->deleteVertexArrays; } +bool Context::supportsHalfFloatTextures() const { + return halfFloat; +} + #if MBGL_HAS_BINARY_PROGRAMS bool Context::supportsProgramBinaries() const { if (!programBinary || !programBinary->programBinary || !programBinary->getProgramBinary) { @@ -491,10 +512,10 @@ Context::createFramebuffer(const Texture& color, } UniqueTexture -Context::createTexture(const Size size, const void* data, TextureFormat format, TextureUnit unit) { +Context::createTexture(const Size size, const void* data, TextureFormat format, TextureUnit unit, TextureType type) { auto obj = createTexture(); pixelStoreUnpack = { 1 }; - updateTexture(obj, size, data, format, unit); + updateTexture(obj, size, data, format, unit, 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)); @@ -505,11 +526,11 @@ Context::createTexture(const Size size, const void* data, TextureFormat format, } void Context::updateTexture( - TextureID id, const Size size, const void* data, TextureFormat format, TextureUnit unit) { + TextureID id, const Size size, const void* data, TextureFormat format, TextureUnit unit, TextureType type) { activeTextureUnit = unit; texture[unit] = id; MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, static_cast<GLenum>(format), size.width, - size.height, 0, static_cast<GLenum>(format), GL_UNSIGNED_BYTE, + size.height, 0, static_cast<GLenum>(format), static_cast<GLenum>(type), data)); } diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index bdf78b0f4e..9116aa7d93 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -53,6 +53,8 @@ public: UniqueTexture createTexture(); VertexArray createVertexArray(); + bool supportsHalfFloatTextures() const; + #if MBGL_HAS_BINARY_PROGRAMS bool supportsProgramBinaries() const; #else @@ -125,15 +127,20 @@ public: // Create a texture from an image with data. template <typename Image> - Texture createTexture(const Image& image, TextureUnit unit = 0) { + Texture createTexture(const Image& image, + TextureUnit unit = 0, + TextureType type = TextureType::UnsignedByte) { auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha; - return { image.size, createTexture(image.size, image.data.get(), format, unit) }; + return { image.size, createTexture(image.size, image.data.get(), format, unit, type) }; } template <typename Image> - void updateTexture(Texture& obj, const Image& image, TextureUnit unit = 0) { + void updateTexture(Texture& obj, + const Image& image, + TextureUnit unit = 0, + TextureType type = TextureType::UnsignedByte) { auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha; - updateTexture(obj.texture.get(), image.size, image.data.get(), format, unit); + updateTexture(obj.texture.get(), image.size, image.data.get(), format, unit, type); obj.size = image.size; } @@ -141,8 +148,9 @@ public: Texture createTexture(const Size size, TextureFormat format = TextureFormat::RGBA, TextureUnit unit = 0, + TextureType type = TextureType::UnsignedByte, const void* data = nullptr) { - return { size, createTexture(size, data, format, unit) }; + return { size, createTexture(size, data, format, unit, type) }; } void bindTexture(Texture&, @@ -210,6 +218,7 @@ private: #if MBGL_HAS_BINARY_PROGRAMS std::unique_ptr<extension::ProgramBinary> programBinary; #endif + bool halfFloat = false; public: State<value::ActiveTextureUnit> activeTextureUnit; @@ -260,8 +269,8 @@ private: void updateVertexBuffer(UniqueBuffer& buffer, const void* data, std::size_t size); UniqueBuffer createIndexBuffer(const void* data, std::size_t size, const BufferUsage usage); void updateIndexBuffer(UniqueBuffer& buffer, const void* data, std::size_t size); - UniqueTexture createTexture(Size size, const void* data, TextureFormat, TextureUnit); - void updateTexture(TextureID, Size size, const void* data, TextureFormat, TextureUnit); + UniqueTexture createTexture(Size size, const void* data, TextureFormat, TextureUnit, TextureType); + void updateTexture(TextureID, Size size, const void* data, TextureFormat, TextureUnit, TextureType); UniqueFramebuffer createFramebuffer(); UniqueRenderbuffer createRenderbuffer(RenderbufferType, Size size); std::unique_ptr<uint8_t[]> readFramebuffer(Size, TextureFormat, bool flip); diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index da08195e58..376a784a0c 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -64,6 +64,15 @@ enum class TextureFormat : uint32_t { #endif // MBGL_USE_GLES2 }; +enum class TextureType : uint32_t { + UnsignedByte = 0x1401, +#if MBGL_USE_GLES2 + HalfFloat = 0x8D61, +#else + HalfFloat = 0x140B, +#endif // MBGL_USE_GLES2 +}; + enum class PrimitiveType { Points = 0x0000, Lines = 0x0001, diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index f39c6c3efc..9daa4e0a5d 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -55,12 +55,16 @@ void RenderHeatmapLayer::render(PaintParameters& parameters, RenderSource*) { const auto size = Size{viewportSize.width / 4, viewportSize.height / 4}; if (!renderTexture || renderTexture->getSize() != size) { - renderTexture = OffscreenTexture(parameters.context, size); + const auto type = parameters.context.supportsHalfFloatTextures() ? + gl::TextureType::HalfFloat : gl::TextureType::UnsignedByte; + + renderTexture = OffscreenTexture(parameters.context, size, type); } if (!colorRampTexture) { const auto colorRampSize = Size{256, 1}; - colorRampTexture = parameters.context.createTexture(colorRampSize, gl::TextureFormat::RGBA, 1, colorRamp.data()); + colorRampTexture = parameters.context.createTexture(colorRampSize, gl::TextureFormat::RGBA, 1, + gl::TextureType::UnsignedByte, colorRamp.data()); } renderTexture->bind(); diff --git a/src/mbgl/util/offscreen_texture.cpp b/src/mbgl/util/offscreen_texture.cpp index 339e74b250..03f555eae0 100644 --- a/src/mbgl/util/offscreen_texture.cpp +++ b/src/mbgl/util/offscreen_texture.cpp @@ -11,20 +11,21 @@ OffscreenTexture& OffscreenTexture::operator=(OffscreenTexture&&) = default; class OffscreenTexture::Impl { public: - Impl(gl::Context& context_, const Size size_) - : context(context_), size(std::move(size_)) { + Impl(gl::Context& context_, const Size size_, const gl::TextureType type_) + : context(context_), size(std::move(size_)), type(type_) { assert(!size.isEmpty()); } Impl(gl::Context& context_, const Size size_, - gl::Renderbuffer<gl::RenderbufferType::DepthComponent>& depth_) - : context(context_), size(std::move(size_)), depth(&depth_) { + gl::Renderbuffer<gl::RenderbufferType::DepthComponent>& depth_, + const gl::TextureType type_) + : context(context_), size(std::move(size_)), depth(&depth_), type(type_) { assert(!size.isEmpty()); } void bind() { if (!framebuffer) { - texture = context.createTexture(size, gl::TextureFormat::RGBA); + texture = context.createTexture(size, gl::TextureFormat::RGBA, 0, type); if (depth) { framebuffer = context.createFramebuffer(*texture, *depth); } else { @@ -58,18 +59,21 @@ private: optional<gl::Framebuffer> framebuffer; optional<gl::Texture> texture; gl::Renderbuffer<gl::RenderbufferType::DepthComponent>* depth = nullptr; + const gl::TextureType type; }; OffscreenTexture::OffscreenTexture(gl::Context& context, - const Size size) - : impl(std::make_unique<Impl>(context, std::move(size))) { + const Size size, + const gl::TextureType type) + : impl(std::make_unique<Impl>(context, std::move(size), type)) { assert(!size.isEmpty()); } OffscreenTexture::OffscreenTexture(gl::Context& context, const Size size, - gl::Renderbuffer<gl::RenderbufferType::DepthComponent>& renderbuffer) - : impl(std::make_unique<Impl>(context, std::move(size), renderbuffer)) { + gl::Renderbuffer<gl::RenderbufferType::DepthComponent>& renderbuffer, + const gl::TextureType type) + : impl(std::make_unique<Impl>(context, std::move(size), renderbuffer, type)) { assert(!size.isEmpty()); } diff --git a/src/mbgl/util/offscreen_texture.hpp b/src/mbgl/util/offscreen_texture.hpp index 7f7e0f0338..36f24f16d3 100644 --- a/src/mbgl/util/offscreen_texture.hpp +++ b/src/mbgl/util/offscreen_texture.hpp @@ -12,10 +12,12 @@ class Texture; class OffscreenTexture { public: OffscreenTexture(gl::Context&, - Size size = { 256, 256 }); + Size size = { 256, 256 }, + gl::TextureType type = gl::TextureType::UnsignedByte); OffscreenTexture(gl::Context&, Size size, - gl::Renderbuffer<gl::RenderbufferType::DepthComponent>&); + gl::Renderbuffer<gl::RenderbufferType::DepthComponent>&, + gl::TextureType type = gl::TextureType::UnsignedByte); ~OffscreenTexture(); OffscreenTexture(OffscreenTexture&&); OffscreenTexture& operator=(OffscreenTexture&&); |