From a28f496d30d32cf41414e2592711100be0729038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 15 Feb 2017 15:29:50 +0100 Subject: [core] use glTexSubImage2D for subsequent updates --- src/mbgl/gl/context.cpp | 15 +++++++++------ src/mbgl/gl/context.hpp | 8 +++++++- src/mbgl/sprite/sprite_atlas.cpp | 9 +++------ test/gl/object.test.cpp | 6 +++--- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index 5726eca5dc..4dfa685102 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -286,24 +286,27 @@ Framebuffer Context::createFramebuffer(const Texture& color) { UniqueTexture Context::createTexture(const Size size, const void* data, TextureFormat format, TextureUnit unit) { - auto obj = createTexture(); - updateTexture(obj, size, data, format, unit); + auto id = createTexture(); + activeTexture = unit; + texture[unit] = id; + MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, static_cast(format), size.width, + size.height, 0, static_cast(format), GL_UNSIGNED_BYTE, + data)); // 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)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); - return obj; + return id; } void Context::updateTexture( TextureID id, const Size size, const void* data, TextureFormat format, TextureUnit unit) { activeTexture = unit; texture[unit] = id; - MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, static_cast(format), size.width, - size.height, 0, static_cast(format), GL_UNSIGNED_BYTE, - data)); + MBGL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size.width, size.height, + static_cast(format), GL_UNSIGNED_BYTE, data)); } void Context::bindTexture(Texture& obj, diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index d1be794240..e8cc965e09 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -38,7 +38,6 @@ public: UniqueShader createShader(ShaderType type, const std::string& source); UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader); void linkProgram(ProgramID); - UniqueTexture createTexture(); UniqueVertexArray createVertexArray(); template @@ -90,12 +89,18 @@ public: // Create a texture from an image with data. template Texture createTexture(const Image& image, TextureUnit unit = 0) { + if (!image.valid()) { + throw new std::runtime_error("Image texture is invalid"); + } auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha; return { image.size, createTexture(image.size, image.data.get(), format, unit) }; } template void updateTexture(Texture& obj, const Image& image, TextureUnit unit = 0) { + if (!image.valid()) { + throw new std::runtime_error("Image texture is invalid"); + } auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha; updateTexture(obj.texture.get(), image.size, image.data.get(), format, unit); obj.size = image.size; @@ -196,6 +201,7 @@ private: UniqueBuffer createVertexBuffer(const void* data, std::size_t size); UniqueBuffer createIndexBuffer(const void* data, std::size_t size); + UniqueTexture createTexture(); UniqueTexture createTexture(Size size, const void* data, TextureFormat, TextureUnit); void updateTexture(TextureID, Size size, const void* data, TextureFormat, TextureUnit); UniqueFramebuffer createFramebuffer(); diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp index 2bf8a3095a..a1a86fab07 100644 --- a/src/mbgl/sprite/sprite_atlas.cpp +++ b/src/mbgl/sprite/sprite_atlas.cpp @@ -49,7 +49,10 @@ SpriteAtlas::SpriteAtlas(Size size_, float pixelRatio_) pixelRatio(pixelRatio_), observer(&nullObserver), bin(size.width, size.height), + image({ static_cast(std::ceil(size.width * pixelRatio)), + static_cast(std::ceil(size.height * pixelRatio)) }), dirty(true) { + image.fill(0); } SpriteAtlas::~SpriteAtlas() = default; @@ -257,12 +260,6 @@ optional SpriteAtlas::getImage(const std::string& name, } void SpriteAtlas::copy(const Entry& entry, optional> Entry::*entryRect) { - if (!image.valid()) { - image = PremultipliedImage({ static_cast(std::ceil(size.width * pixelRatio)), - static_cast(std::ceil(size.height * pixelRatio)) }); - image.fill(0); - } - const PremultipliedImage& src = entry.spriteImage->image; const Rect& rect = *(entry.*entryRect); diff --git a/test/gl/object.test.cpp b/test/gl/object.test.cpp index f1da93f1da..592e7f77d8 100644 --- a/test/gl/object.test.cpp +++ b/test/gl/object.test.cpp @@ -66,9 +66,9 @@ TEST(GLObject, Store) { gl::Context context; EXPECT_TRUE(context.empty()); - gl::UniqueTexture texture = context.createTexture(); - EXPECT_NE(texture.get(), 0u); - texture.reset(); + auto texture = context.createTexture(Size{ 1, 1 }); + EXPECT_NE(texture.texture.get(), 0u); + texture.texture.reset(); EXPECT_FALSE(context.empty()); context.performCleanup(); EXPECT_FALSE(context.empty()); -- cgit v1.2.1