diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2019-05-13 17:13:31 -0700 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2019-05-15 11:57:43 -0700 |
commit | 3a6ff7710fcf201f82ddc2090488ef585bd8ab17 (patch) | |
tree | de380cbb7f5553282b081dce9202cbe9e502ebe5 /src/mbgl/gl/upload_pass.cpp | |
parent | bf0998697e0893d8a56421a139c7fc4855e89fa5 (diff) | |
download | qtlocation-mapboxgl-3a6ff7710fcf201f82ddc2090488ef585bd8ab17.tar.gz |
[core] add gfx::UploadPass, split startRender into prepare and upload
Diffstat (limited to 'src/mbgl/gl/upload_pass.cpp')
-rw-r--r-- | src/mbgl/gl/upload_pass.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
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 |