diff options
Diffstat (limited to 'src/mbgl/gl')
-rw-r--r-- | src/mbgl/gl/command_encoder.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/gl/command_encoder.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/gl/context.cpp | 112 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 17 | ||||
-rw-r--r-- | src/mbgl/gl/object.cpp | 3 | ||||
-rw-r--r-- | src/mbgl/gl/object.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/gl/offscreen_texture.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/gl/upload_pass.cpp | 117 | ||||
-rw-r--r-- | src/mbgl/gl/upload_pass.hpp | 42 |
9 files changed, 202 insertions, 101 deletions
diff --git a/src/mbgl/gl/command_encoder.cpp b/src/mbgl/gl/command_encoder.cpp index 37c4479734..a7df14df09 100644 --- a/src/mbgl/gl/command_encoder.cpp +++ b/src/mbgl/gl/command_encoder.cpp @@ -1,4 +1,5 @@ #include <mbgl/gl/command_encoder.hpp> +#include <mbgl/gl/upload_pass.hpp> #include <mbgl/gl/render_pass.hpp> #include <mbgl/gl/context.hpp> #include <mbgl/gl/renderable_resource.hpp> @@ -15,6 +16,11 @@ CommandEncoder::~CommandEncoder() { context.performCleanup(); } +std::unique_ptr<gfx::UploadPass> +CommandEncoder::createUploadPass(const char* name) { + return std::make_unique<gl::UploadPass>(*this, name); +} + std::unique_ptr<gfx::RenderPass> CommandEncoder::createRenderPass(const char* name, const gfx::RenderPassDescriptor& descriptor) { return std::make_unique<gl::RenderPass>(*this, name, descriptor); diff --git a/src/mbgl/gl/command_encoder.hpp b/src/mbgl/gl/command_encoder.hpp index 31d67d13a6..f47aad4946 100644 --- a/src/mbgl/gl/command_encoder.hpp +++ b/src/mbgl/gl/command_encoder.hpp @@ -6,7 +6,6 @@ namespace mbgl { namespace gl { class Context; -class RenderPass; class CommandEncoder final : public gfx::CommandEncoder { public: @@ -15,8 +14,10 @@ public: ~CommandEncoder() override; + friend class UploadPass; friend class RenderPass; + std::unique_ptr<gfx::UploadPass> createUploadPass(const char* name) override; std::unique_ptr<gfx::RenderPass> createRenderPass(const char* name, const gfx::RenderPassDescriptor&) override; void present(gfx::Renderable&) override; diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index b6a7bcc44c..f1288dc7ed 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -1,8 +1,6 @@ #include <mbgl/gl/context.hpp> #include <mbgl/gl/enum.hpp> #include <mbgl/gl/renderer_backend.hpp> -#include <mbgl/gl/vertex_buffer_resource.hpp> -#include <mbgl/gl/index_buffer_resource.hpp> #include <mbgl/gl/texture_resource.hpp> #include <mbgl/gl/renderbuffer_resource.hpp> #include <mbgl/gl/draw_scope_resource.hpp> @@ -222,41 +220,6 @@ void Context::verifyProgramLinkage(ProgramID program_) { throw std::runtime_error("program failed to link"); } -std::unique_ptr<gfx::VertexBufferResource> -Context::createVertexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType usage) { - BufferID id = 0; - MBGL_CHECK_ERROR(glGenBuffers(1, &id)); - UniqueBuffer result { std::move(id), { this } }; - vertexBuffer = result; - MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, size, data, Enum<gfx::BufferUsageType>::to(usage))); - return std::make_unique<gl::VertexBufferResource>(std::move(result)); -} - -void Context::updateVertexBufferResource(gfx::VertexBufferResource& resource, const void* data, std::size_t size) { - vertexBuffer = static_cast<gl::VertexBufferResource&>(resource).buffer; - MBGL_CHECK_ERROR(glBufferSubData(GL_ARRAY_BUFFER, 0, size, data)); -} - -std::unique_ptr<gfx::IndexBufferResource> -Context::createIndexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType usage) { - BufferID id = 0; - MBGL_CHECK_ERROR(glGenBuffers(1, &id)); - UniqueBuffer result { std::move(id), { this } }; - bindVertexArray = 0; - globalVertexArrayState.indexBuffer = result; - MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, Enum<gfx::BufferUsageType>::to(usage))); - return std::make_unique<gl::IndexBufferResource>(std::move(result)); -} - -void Context::updateIndexBufferResource(gfx::IndexBufferResource& resource, const void* data, std::size_t size) { - // Be sure to unbind any existing vertex array object before binding the index buffer - // so that we don't mess up another VAO - bindVertexArray = 0; - globalVertexArrayState.indexBuffer = static_cast<gl::IndexBufferResource&>(resource).buffer; - MBGL_CHECK_ERROR(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, size, data)); -} - - UniqueTexture Context::createUniqueTexture() { if (pooledTextures.empty()) { pooledTextures.resize(TextureMax); @@ -339,6 +302,32 @@ UniqueFramebuffer Context::createFramebuffer() { return UniqueFramebuffer{ std::move(id), { this } }; } +std::unique_ptr<gfx::TextureResource> Context::createTextureResource( + const Size size, const gfx::TexturePixelType format, const gfx::TextureChannelDataType type) { + auto obj = createUniqueTexture(); + std::unique_ptr<gfx::TextureResource> resource = + std::make_unique<gl::TextureResource>(std::move(obj)); + + // Always use texture unit 0 for manipulating it. + activeTextureUnit = 0; + texture[0] = static_cast<gl::TextureResource&>(*resource).texture; + + // Creates an empty texture with the specified size and format. + 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), nullptr)); + + // 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 resource; +} + std::unique_ptr<gfx::RenderbufferResource> Context::createRenderbufferResource(const gfx::RenderbufferPixelType type, const Size size) { RenderbufferID id = 0; @@ -506,55 +495,6 @@ Context::createFramebuffer(const gfx::Texture& color, return { depth.getSize(), std::move(fbo) }; } -std::unique_ptr<gfx::TextureResource> -Context::createTextureResource(const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { - auto obj = createUniqueTexture(); - std::unique_ptr<gfx::TextureResource> resource = std::make_unique<gl::TextureResource>(std::move(obj)); - pixelStoreUnpack = { 1 }; - 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)); - 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 resource; -} - -void Context::updateTextureResource(gfx::TextureResource& resource, - const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { - // Always use texture unit 0 for manipulating it. - activeTextureUnit = 0; - texture[0] = static_cast<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::updateTextureResourceSub(gfx::TextureResource& resource, - const uint16_t xOffset, - const uint16_t yOffset, - const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { - // Always use texture unit 0 for manipulating it. - activeTextureUnit = 0; - texture[0] = static_cast<const gl::TextureResource&>(resource).texture; - MBGL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, - xOffset, yOffset, - size.width, size.height, - Enum<gfx::TexturePixelType>::to(format), - Enum<gfx::TextureChannelDataType>::to(type), data)); -} - std::unique_ptr<gfx::OffscreenTexture> Context::createOffscreenTexture(const Size size, const gfx::TextureChannelDataType type) { return std::make_unique<gl::OffscreenTexture>(*this, size, type); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index aa8d2c4c84..41e5b5f22d 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -8,6 +8,7 @@ #include <mbgl/gl/framebuffer.hpp> #include <mbgl/gl/vertex_array.hpp> #include <mbgl/gl/types.hpp> +#include <mbgl/gfx/texture.hpp> #include <mbgl/gfx/draw_mode.hpp> #include <mbgl/gfx/depth_mode.hpp> #include <mbgl/gfx/stencil_mode.hpp> @@ -42,6 +43,8 @@ public: Context(const Context&) = delete; Context& operator=(const Context& other) = delete; + std::unique_ptr<gfx::CommandEncoder> createCommandEncoder() override; + void initializeExtensions(const std::function<gl::ProcAddress(const char*)>&); void enableDebugging(); @@ -189,15 +192,6 @@ private: State<value::PointSize> pointSize; #endif // MBGL_USE_GLES2 - std::unique_ptr<gfx::VertexBufferResource> createVertexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; - void updateVertexBufferResource(gfx::VertexBufferResource&, const void* data, std::size_t size) override; - std::unique_ptr<gfx::IndexBufferResource> createIndexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; - void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; - - std::unique_ptr<gfx::TextureResource> createTextureResource(Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; - void updateTextureResource(gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; - void updateTextureResourceSub(gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; - std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture( Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; std::unique_ptr<gfx::OffscreenTexture> createOffscreenTexture( @@ -205,6 +199,9 @@ private: gfx::Renderbuffer<gfx::RenderbufferPixelType::Depth>&, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; + std::unique_ptr<gfx::TextureResource> + createTextureResource(Size, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + std::unique_ptr<gfx::RenderbufferResource> createRenderbufferResource(gfx::RenderbufferPixelType, Size size) override; std::unique_ptr<gfx::DrawScopeResource> createDrawScopeResource() override; @@ -218,8 +215,6 @@ private: VertexArray createVertexArray(); bool supportsVertexArrays() const; - std::unique_ptr<gfx::CommandEncoder> createCommandEncoder() override; - friend detail::ProgramDeleter; friend detail::ShaderDeleter; friend detail::BufferDeleter; diff --git a/src/mbgl/gl/object.cpp b/src/mbgl/gl/object.cpp index 2c5f1bca1f..ec2998a27d 100644 --- a/src/mbgl/gl/object.cpp +++ b/src/mbgl/gl/object.cpp @@ -18,8 +18,7 @@ void ShaderDeleter::operator()(ShaderID id) const { } void BufferDeleter::operator()(BufferID id) const { - assert(context); - context->abandonedBuffers.push_back(id); + context.abandonedBuffers.push_back(id); } void TextureDeleter::operator()(TextureID id) const { diff --git a/src/mbgl/gl/object.hpp b/src/mbgl/gl/object.hpp index 1408add65a..9598e0c59e 100644 --- a/src/mbgl/gl/object.hpp +++ b/src/mbgl/gl/object.hpp @@ -22,7 +22,7 @@ struct ShaderDeleter { }; struct BufferDeleter { - Context* context; + Context& context; void operator()(BufferID) const; }; diff --git a/src/mbgl/gl/offscreen_texture.cpp b/src/mbgl/gl/offscreen_texture.cpp index 0b06fedf46..5feef95edf 100644 --- a/src/mbgl/gl/offscreen_texture.cpp +++ b/src/mbgl/gl/offscreen_texture.cpp @@ -25,6 +25,7 @@ public: void bind() override { if (!framebuffer) { + assert(!texture); texture = context.createTexture(size, gfx::TexturePixelType::RGBA, type); if (depth) { framebuffer = context.createFramebuffer(*texture, *depth); diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp new file mode 100644 index 0000000000..358f1a7203 --- /dev/null +++ b/src/mbgl/gl/upload_pass.cpp @@ -0,0 +1,117 @@ +#include <mbgl/gl/upload_pass.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/enum.hpp> +#include <mbgl/gl/defines.hpp> +#include <mbgl/gl/command_encoder.hpp> +#include <mbgl/gl/vertex_buffer_resource.hpp> +#include <mbgl/gl/index_buffer_resource.hpp> +#include <mbgl/gl/texture_resource.hpp> + +namespace mbgl { +namespace gl { + +using namespace platform; + +UploadPass::UploadPass(gl::CommandEncoder& commandEncoder_, const char* name) + : commandEncoder(commandEncoder_), debugGroup(commandEncoder.createDebugGroup(name)) { +} + +std::unique_ptr<gfx::VertexBufferResource> UploadPass::createVertexBufferResource( + const void* data, std::size_t size, const gfx::BufferUsageType usage) { + BufferID id = 0; + MBGL_CHECK_ERROR(glGenBuffers(1, &id)); + UniqueBuffer result{ std::move(id), { commandEncoder.context } }; + commandEncoder.context.vertexBuffer = result; + MBGL_CHECK_ERROR( + glBufferData(GL_ARRAY_BUFFER, size, data, Enum<gfx::BufferUsageType>::to(usage))); + return std::make_unique<gl::VertexBufferResource>(std::move(result)); +} + +void UploadPass::updateVertexBufferResource(gfx::VertexBufferResource& resource, + const void* data, + std::size_t size) { + commandEncoder.context.vertexBuffer = static_cast<gl::VertexBufferResource&>(resource).buffer; + MBGL_CHECK_ERROR(glBufferSubData(GL_ARRAY_BUFFER, 0, size, data)); +} + +std::unique_ptr<gfx::IndexBufferResource> UploadPass::createIndexBufferResource( + const void* data, std::size_t size, const gfx::BufferUsageType usage) { + BufferID id = 0; + MBGL_CHECK_ERROR(glGenBuffers(1, &id)); + UniqueBuffer result{ std::move(id), { commandEncoder.context } }; + commandEncoder.context.bindVertexArray = 0; + commandEncoder.context.globalVertexArrayState.indexBuffer = result; + MBGL_CHECK_ERROR( + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, Enum<gfx::BufferUsageType>::to(usage))); + return std::make_unique<gl::IndexBufferResource>(std::move(result)); +} + +void UploadPass::updateIndexBufferResource(gfx::IndexBufferResource& resource, + const void* data, + std::size_t size) { + // Be sure to unbind any existing vertex array object before binding the index buffer + // so that we don't mess up another VAO + commandEncoder.context.bindVertexArray = 0; + commandEncoder.context.globalVertexArrayState.indexBuffer = + static_cast<gl::IndexBufferResource&>(resource).buffer; + MBGL_CHECK_ERROR(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, size, data)); +} + +std::unique_ptr<gfx::TextureResource> +UploadPass::createTextureResource(const Size size, + const void* data, + gfx::TexturePixelType format, + gfx::TextureChannelDataType type) { + auto obj = commandEncoder.context.createUniqueTexture(); + std::unique_ptr<gfx::TextureResource> resource = + std::make_unique<gl::TextureResource>(std::move(obj)); + commandEncoder.context.pixelStoreUnpack = { 1 }; + 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)); + 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 resource; +} + +void UploadPass::updateTextureResource(gfx::TextureResource& resource, + const Size size, + const void* data, + gfx::TexturePixelType format, + gfx::TextureChannelDataType type) { + // Always use texture unit 0 for manipulating it. + commandEncoder.context.activeTextureUnit = 0; + commandEncoder.context.texture[0] = static_cast<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 UploadPass::updateTextureResourceSub(gfx::TextureResource& resource, + const uint16_t xOffset, + const uint16_t yOffset, + const Size size, + const void* data, + gfx::TexturePixelType format, + gfx::TextureChannelDataType type) { + // Always use texture unit 0 for manipulating it. + commandEncoder.context.activeTextureUnit = 0; + commandEncoder.context.texture[0] = static_cast<const gl::TextureResource&>(resource).texture; + MBGL_CHECK_ERROR(glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, size.width, size.height, + Enum<gfx::TexturePixelType>::to(format), + Enum<gfx::TextureChannelDataType>::to(type), data)); +} + +void UploadPass::pushDebugGroup(const char* name) { + commandEncoder.pushDebugGroup(name); +} + +void UploadPass::popDebugGroup() { + commandEncoder.popDebugGroup(); +} + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/upload_pass.hpp b/src/mbgl/gl/upload_pass.hpp new file mode 100644 index 0000000000..8b4f71b88d --- /dev/null +++ b/src/mbgl/gl/upload_pass.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include <mbgl/gfx/upload_pass.hpp> + +namespace mbgl { +namespace gfx { + +class CommandEncoder; + +} // namespace gfx + +namespace gl { + +class CommandEncoder; +class Context; + +class UploadPass final : public gfx::UploadPass { +public: + UploadPass(gl::CommandEncoder&, const char* name); + +private: + void pushDebugGroup(const char* name) override; + void popDebugGroup() override; + +public: + std::unique_ptr<gfx::VertexBufferResource> createVertexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; + void updateVertexBufferResource(gfx::VertexBufferResource&, const void* data, std::size_t size) override; + std::unique_ptr<gfx::IndexBufferResource> createIndexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; + void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; + +public: + std::unique_ptr<gfx::TextureResource> createTextureResource(Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + void updateTextureResource(gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + void updateTextureResourceSub(gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; + +private: + gl::CommandEncoder& commandEncoder; + const gfx::DebugGroup<gfx::CommandEncoder> debugGroup; +}; + +} // namespace gl +} // namespace mbgl |