From fb062bb23e66af3d5a889b767aae380884b259e5 Mon Sep 17 00:00:00 2001 From: Mikko Pulkki Date: Tue, 15 Oct 2019 12:09:21 +0300 Subject: [render-test] Add resource usage tracking to gfx context --- include/mbgl/gfx/rendering_stats.hpp | 22 +++++++++++ next/CMakeLists.txt | 5 +++ .../default/src/mbgl/gfx/headless_frontend.cpp | 1 + src/core-files.json | 5 +++ src/mbgl/gfx/context.hpp | 7 +++- src/mbgl/gfx/rendering_stats.cpp | 12 ++++++ src/mbgl/gl/context.cpp | 30 +++++++++++++-- src/mbgl/gl/context.hpp | 4 ++ src/mbgl/gl/index_buffer_resource.cpp | 14 +++++++ src/mbgl/gl/index_buffer_resource.hpp | 5 ++- src/mbgl/gl/object.cpp | 2 + src/mbgl/gl/texture_resource.cpp | 45 ++++++++++++++++++++++ src/mbgl/gl/texture_resource.hpp | 7 +++- src/mbgl/gl/upload_pass.cpp | 12 ++++-- src/mbgl/gl/vertex_buffer_resource.cpp | 14 +++++++ src/mbgl/gl/vertex_buffer_resource.hpp | 5 ++- 16 files changed, 176 insertions(+), 14 deletions(-) create mode 100644 include/mbgl/gfx/rendering_stats.hpp create mode 100644 src/mbgl/gfx/rendering_stats.cpp create mode 100644 src/mbgl/gl/index_buffer_resource.cpp create mode 100644 src/mbgl/gl/texture_resource.cpp create mode 100644 src/mbgl/gl/vertex_buffer_resource.cpp diff --git a/include/mbgl/gfx/rendering_stats.hpp b/include/mbgl/gfx/rendering_stats.hpp new file mode 100644 index 0000000000..8fb01a5825 --- /dev/null +++ b/include/mbgl/gfx/rendering_stats.hpp @@ -0,0 +1,22 @@ +#pragma once + +namespace mbgl { +namespace gfx { + +struct RenderingStats { + RenderingStats() = default; + bool isZero() const; + + int numDrawCalls; + int numActiveTextures; + int numCreatedTextures; + int numBuffers; + int numFrameBuffers; + + int memTextures; + int memIndexBuffers; + int memVertexBuffers; +}; + +} // namespace gfx +} // namespace mbgl \ No newline at end of file diff --git a/next/CMakeLists.txt b/next/CMakeLists.txt index 524a86e189..924761ad85 100644 --- a/next/CMakeLists.txt +++ b/next/CMakeLists.txt @@ -70,6 +70,7 @@ add_library( ${MBGL_ROOT}/include/mbgl/gfx/backend_scope.hpp ${MBGL_ROOT}/include/mbgl/gfx/renderable.hpp ${MBGL_ROOT}/include/mbgl/gfx/renderer_backend.hpp + ${MBGL_ROOT}/include/mbgl/gfx/rendering_stats.hpp ${MBGL_ROOT}/include/mbgl/gl/renderable_resource.hpp ${MBGL_ROOT}/include/mbgl/gl/renderer_backend.hpp ${MBGL_ROOT}/include/mbgl/layermanager/background_layer_factory.hpp @@ -285,6 +286,7 @@ add_library( ${MBGL_ROOT}/src/mbgl/gfx/render_pass.hpp ${MBGL_ROOT}/src/mbgl/gfx/renderbuffer.hpp ${MBGL_ROOT}/src/mbgl/gfx/renderer_backend.cpp + ${MBGL_ROOT}/src/mbgl/gfx/rendering_stats.cpp ${MBGL_ROOT}/src/mbgl/gfx/stencil_mode.hpp ${MBGL_ROOT}/src/mbgl/gfx/texture.hpp ${MBGL_ROOT}/src/mbgl/gfx/types.hpp @@ -306,6 +308,7 @@ add_library( ${MBGL_ROOT}/src/mbgl/gl/enum.hpp ${MBGL_ROOT}/src/mbgl/gl/extension.hpp ${MBGL_ROOT}/src/mbgl/gl/framebuffer.hpp + ${MBGL_ROOT}/src/mbgl/gl/index_buffer_resource.cpp ${MBGL_ROOT}/src/mbgl/gl/index_buffer_resource.hpp ${MBGL_ROOT}/src/mbgl/gl/object.cpp ${MBGL_ROOT}/src/mbgl/gl/object.hpp @@ -319,6 +322,7 @@ add_library( ${MBGL_ROOT}/src/mbgl/gl/state.hpp ${MBGL_ROOT}/src/mbgl/gl/texture.cpp ${MBGL_ROOT}/src/mbgl/gl/texture.hpp + ${MBGL_ROOT}/src/mbgl/gl/texture_resource.cpp ${MBGL_ROOT}/src/mbgl/gl/texture_resource.hpp ${MBGL_ROOT}/src/mbgl/gl/types.hpp ${MBGL_ROOT}/src/mbgl/gl/uniform.cpp @@ -330,6 +334,7 @@ add_library( ${MBGL_ROOT}/src/mbgl/gl/vertex_array.cpp ${MBGL_ROOT}/src/mbgl/gl/vertex_array.hpp ${MBGL_ROOT}/src/mbgl/gl/vertex_array_extension.hpp + ${MBGL_ROOT}/src/mbgl/gl/vertex_buffer_resource.cpp ${MBGL_ROOT}/src/mbgl/gl/vertex_buffer_resource.hpp ${MBGL_ROOT}/src/mbgl/layermanager/background_layer_factory.cpp ${MBGL_ROOT}/src/mbgl/layermanager/circle_layer_factory.cpp diff --git a/platform/default/src/mbgl/gfx/headless_frontend.cpp b/platform/default/src/mbgl/gfx/headless_frontend.cpp index 87d09911a2..9e819f6653 100644 --- a/platform/default/src/mbgl/gfx/headless_frontend.cpp +++ b/platform/default/src/mbgl/gfx/headless_frontend.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/src/core-files.json b/src/core-files.json index e8795fbdd3..c25e8273d4 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -17,20 +17,24 @@ "src/mbgl/geometry/line_atlas.cpp", "src/mbgl/gfx/attribute.cpp", "src/mbgl/gfx/renderer_backend.cpp", + "src/mbgl/gfx/rendering_stats.cpp", "src/mbgl/gl/attribute.cpp", "src/mbgl/gl/command_encoder.cpp", "src/mbgl/gl/context.cpp", "src/mbgl/gl/debugging_extension.cpp", "src/mbgl/gl/enum.cpp", + "src/mbgl/gl/index_buffer_resource.cpp", "src/mbgl/gl/object.cpp", "src/mbgl/gl/offscreen_texture.cpp", "src/mbgl/gl/render_pass.cpp", "src/mbgl/gl/renderer_backend.cpp", "src/mbgl/gl/texture.cpp", + "src/mbgl/gl/texture_resource.cpp", "src/mbgl/gl/uniform.cpp", "src/mbgl/gl/upload_pass.cpp", "src/mbgl/gl/value.cpp", "src/mbgl/gl/vertex_array.cpp", + "src/mbgl/gl/vertex_buffer_resource.cpp", "src/mbgl/layermanager/background_layer_factory.cpp", "src/mbgl/layermanager/circle_layer_factory.cpp", "src/mbgl/layermanager/custom_layer_factory.cpp", @@ -331,6 +335,7 @@ "mbgl/gfx/backend_scope.hpp": "include/mbgl/gfx/backend_scope.hpp", "mbgl/gfx/renderable.hpp": "include/mbgl/gfx/renderable.hpp", "mbgl/gfx/renderer_backend.hpp": "include/mbgl/gfx/renderer_backend.hpp", + "mbgl/gfx/rendering_stats.hpp": "include/mbgl/gfx/rendering_stats.hpp", "mbgl/gl/renderable_resource.hpp": "include/mbgl/gl/renderable_resource.hpp", "mbgl/gl/renderer_backend.hpp": "include/mbgl/gl/renderer_backend.hpp", "mbgl/i18n/collator.hpp": "include/mbgl/i18n/collator.hpp", diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp index 2c7cb14899..fe0851be11 100644 --- a/src/mbgl/gfx/context.hpp +++ b/src/mbgl/gfx/context.hpp @@ -1,12 +1,13 @@ #pragma once #include -#include #include #include #include -#include +#include +#include #include +#include namespace mbgl { @@ -85,6 +86,8 @@ public: public: virtual std::unique_ptr createCommandEncoder() = 0; + virtual const RenderingStats& renderingStats() const = 0; + #if not defined(NDEBUG) public: virtual void visualizeStencilBuffer() = 0; diff --git a/src/mbgl/gfx/rendering_stats.cpp b/src/mbgl/gfx/rendering_stats.cpp new file mode 100644 index 0000000000..0a239ebd11 --- /dev/null +++ b/src/mbgl/gfx/rendering_stats.cpp @@ -0,0 +1,12 @@ +#include + +namespace mbgl { +namespace gfx { + +bool RenderingStats::isZero() const { + return numActiveTextures == 0 && numCreatedTextures == 0 && numBuffers == 0 && numFrameBuffers == 0 && + memTextures == 0 && memIndexBuffers == 0 && memVertexBuffers == 0; +} + +} // namespace gfx +} // namespace mbgl \ No newline at end of file diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index f81ac48ee5..e2bcc7fadc 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -54,13 +54,15 @@ Context::Context(RendererBackend& backend_) GLint value; MBGL_CHECK_ERROR(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value)); return value; - }()), backend(backend_) { -} + }()), + backend(backend_), + stats() {} Context::~Context() { if (cleanupOnDestruction) { reset(); } + assert(stats.isZero()); } void Context::initializeExtensions(const std::function& getProcAddress) { @@ -206,10 +208,12 @@ UniqueTexture Context::createUniqueTexture() { if (pooledTextures.empty()) { pooledTextures.resize(TextureMax); MBGL_CHECK_ERROR(glGenTextures(TextureMax, pooledTextures.data())); + stats.numCreatedTextures += TextureMax; } TextureID id = pooledTextures.back(); pooledTextures.pop_back(); + stats.numActiveTextures++; // NOLINTNEXTLINE(performance-move-const-arg) return UniqueTexture{std::move(id), {this}}; } @@ -238,6 +242,7 @@ VertexArray Context::createVertexArray() { UniqueFramebuffer Context::createFramebuffer() { FramebufferID id = 0; MBGL_CHECK_ERROR(glGenFramebuffers(1, &id)); + stats.numFrameBuffers++; // NOLINTNEXTLINE(performance-move-const-arg) return UniqueFramebuffer{ std::move(id), { this } }; } @@ -245,8 +250,10 @@ UniqueFramebuffer Context::createFramebuffer() { std::unique_ptr Context::createTextureResource( const Size size, const gfx::TexturePixelType format, const gfx::TextureChannelDataType type) { auto obj = createUniqueTexture(); + int textureByteSize = gl::TextureResource::getStorageSize(size, format, type); + stats.memTextures += textureByteSize; std::unique_ptr resource = - std::make_unique(std::move(obj)); + std::make_unique(std::move(obj), textureByteSize); // Always use texture unit 0 for manipulating it. activeTextureUnit = 0; @@ -517,6 +524,8 @@ void Context::clear(optional color, } MBGL_CHECK_ERROR(glClear(mask)); + + stats.numDrawCalls = 0; } void Context::setCullFaceMode(const gfx::CullFaceMode& mode) { @@ -583,6 +592,14 @@ std::unique_ptr Context::createCommandEncoder() { return std::make_unique(*this); } +gfx::RenderingStats& Context::renderingStats() { + return stats; +} + +const gfx::RenderingStats& Context::renderingStats() const { + return stats; +} + void Context::finish() { MBGL_CHECK_ERROR(glFinish()); } @@ -611,6 +628,8 @@ void Context::draw(const gfx::DrawMode& drawMode, static_cast(indexLength), GL_UNSIGNED_SHORT, reinterpret_cast(sizeof(uint16_t) * indexOffset))); + + stats.numDrawCalls++; } void Context::performCleanup() { @@ -647,6 +666,7 @@ void Context::performCleanup() { } } MBGL_CHECK_ERROR(glDeleteBuffers(int(abandonedBuffers.size()), abandonedBuffers.data())); + stats.numBuffers -= int(abandonedBuffers.size()); abandonedBuffers.clear(); } @@ -659,6 +679,8 @@ void Context::performCleanup() { } } MBGL_CHECK_ERROR(glDeleteTextures(int(abandonedTextures.size()), abandonedTextures.data())); + stats.numCreatedTextures -= int(abandonedTextures.size()); + assert(stats.numCreatedTextures >= 0); abandonedTextures.clear(); } @@ -682,6 +704,8 @@ void Context::performCleanup() { } MBGL_CHECK_ERROR( glDeleteFramebuffers(int(abandonedFramebuffers.size()), abandonedFramebuffers.data())); + stats.numFrameBuffers -= int(abandonedFramebuffers.size()); + assert(stats.numFrameBuffers >= 0); abandonedFramebuffers.clear(); } diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index edcdde1ec6..b0d043ff9f 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -43,6 +43,9 @@ public: std::unique_ptr createCommandEncoder() override; + gfx::RenderingStats& renderingStats(); + const gfx::RenderingStats& renderingStats() const override; + void initializeExtensions(const std::function&); void enableDebugging(); @@ -132,6 +135,7 @@ private: RendererBackend& backend; bool cleanupOnDestruction = true; + gfx::RenderingStats stats; std::unique_ptr debugging; std::unique_ptr vertexArray; diff --git a/src/mbgl/gl/index_buffer_resource.cpp b/src/mbgl/gl/index_buffer_resource.cpp new file mode 100644 index 0000000000..2ef178846b --- /dev/null +++ b/src/mbgl/gl/index_buffer_resource.cpp @@ -0,0 +1,14 @@ +#include +#include + +namespace mbgl { +namespace gl { + +IndexBufferResource::~IndexBufferResource() { + auto& stats = buffer.get_deleter().context.renderingStats(); + stats.memIndexBuffers -= byteSize; + assert(stats.memIndexBuffers >= 0); +} + +} // namespace gl +} // namespace mbgl \ No newline at end of file diff --git a/src/mbgl/gl/index_buffer_resource.hpp b/src/mbgl/gl/index_buffer_resource.hpp index 2da25fdb96..00c66be5b5 100644 --- a/src/mbgl/gl/index_buffer_resource.hpp +++ b/src/mbgl/gl/index_buffer_resource.hpp @@ -8,10 +8,11 @@ namespace gl { class IndexBufferResource : public gfx::IndexBufferResource { public: - IndexBufferResource(UniqueBuffer&& buffer_) : buffer(std::move(buffer_)) { - } + IndexBufferResource(UniqueBuffer&& buffer_, int byteSize_) : buffer(std::move(buffer_)), byteSize(byteSize_) {} + ~IndexBufferResource(); UniqueBuffer buffer; + int byteSize; }; } // namespace gl diff --git a/src/mbgl/gl/object.cpp b/src/mbgl/gl/object.cpp index ec2998a27d..c075aa8f13 100644 --- a/src/mbgl/gl/object.cpp +++ b/src/mbgl/gl/object.cpp @@ -28,6 +28,8 @@ void TextureDeleter::operator()(TextureID id) const { } else { context->pooledTextures.push_back(id); } + context->renderingStats().numActiveTextures--; + assert(context->renderingStats().numActiveTextures >= 0); } void VertexArrayDeleter::operator()(VertexArrayID id) const { diff --git a/src/mbgl/gl/texture_resource.cpp b/src/mbgl/gl/texture_resource.cpp new file mode 100644 index 0000000000..b9bf620eea --- /dev/null +++ b/src/mbgl/gl/texture_resource.cpp @@ -0,0 +1,45 @@ +#include +#include + +namespace mbgl { +namespace gl { + +static int channelCount(gfx::TexturePixelType format) { + switch (format) { + case gfx::TexturePixelType::Alpha: + case gfx::TexturePixelType::Depth: + case gfx::TexturePixelType::Luminance: + case gfx::TexturePixelType::Stencil: + return 1; + case gfx::TexturePixelType::RGBA: + return 4; + default: + assert(!"Unknown texture pixel type"); + return 0; + } +} + +static int channelStorageSize(gfx::TextureChannelDataType type) { + switch (type) { + case gfx::TextureChannelDataType::HalfFloat: + return 2; + case gfx::TextureChannelDataType::UnsignedByte: + return 1; + default: + assert(!"Unknown texture channel data type"); + return 0; + } +} + +TextureResource::~TextureResource() { + auto& stats = texture.get_deleter().context->renderingStats(); + stats.memTextures -= byteSize; + assert(stats.memTextures >= 0); +} + +int TextureResource::getStorageSize(const Size& size, gfx::TexturePixelType format, gfx::TextureChannelDataType type) { + return size.width * size.height * channelCount(format) * channelStorageSize(type); +} + +} // namespace gl +} // namespace mbgl \ No newline at end of file diff --git a/src/mbgl/gl/texture_resource.hpp b/src/mbgl/gl/texture_resource.hpp index ed742e75b7..494e5ae8a3 100644 --- a/src/mbgl/gl/texture_resource.hpp +++ b/src/mbgl/gl/texture_resource.hpp @@ -8,14 +8,17 @@ namespace gl { class TextureResource : public gfx::TextureResource { public: - TextureResource(UniqueTexture&& texture_) : texture(std::move(texture_)) { - } + TextureResource(UniqueTexture&& texture_, int byteSize_) : texture(std::move(texture_)), byteSize(byteSize_) {} + ~TextureResource(); + + static int getStorageSize(const Size& size, gfx::TexturePixelType format, gfx::TextureChannelDataType type); 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; + int byteSize; }; } // namespace gl diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp index 4312488fb4..962bc72239 100644 --- a/src/mbgl/gl/upload_pass.cpp +++ b/src/mbgl/gl/upload_pass.cpp @@ -20,12 +20,14 @@ std::unique_ptr UploadPass::createVertexBufferResourc const void* data, std::size_t size, const gfx::BufferUsageType usage) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); + commandEncoder.context.renderingStats().numBuffers++; + commandEncoder.context.renderingStats().memVertexBuffers += size; // NOLINTNEXTLINE(performance-move-const-arg) UniqueBuffer result{ std::move(id), { commandEncoder.context } }; commandEncoder.context.vertexBuffer = result; MBGL_CHECK_ERROR( glBufferData(GL_ARRAY_BUFFER, size, data, Enum::to(usage))); - return std::make_unique(std::move(result)); + return std::make_unique(std::move(result), size); } void UploadPass::updateVertexBufferResource(gfx::VertexBufferResource& resource, @@ -39,13 +41,15 @@ std::unique_ptr UploadPass::createIndexBufferResource( const void* data, std::size_t size, const gfx::BufferUsageType usage) { BufferID id = 0; MBGL_CHECK_ERROR(glGenBuffers(1, &id)); + commandEncoder.context.renderingStats().numBuffers++; + commandEncoder.context.renderingStats().memIndexBuffers += size; // NOLINTNEXTLINE(performance-move-const-arg) 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::to(usage))); - return std::make_unique(std::move(result)); + return std::make_unique(std::move(result), size); } void UploadPass::updateIndexBufferResource(gfx::IndexBufferResource& resource, @@ -65,8 +69,10 @@ UploadPass::createTextureResource(const Size size, gfx::TexturePixelType format, gfx::TextureChannelDataType type) { auto obj = commandEncoder.context.createUniqueTexture(); + int textureByteSize = gl::TextureResource::getStorageSize(size, format, type); + commandEncoder.context.renderingStats().memTextures += textureByteSize; std::unique_ptr resource = - std::make_unique(std::move(obj)); + std::make_unique(std::move(obj), textureByteSize); 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. diff --git a/src/mbgl/gl/vertex_buffer_resource.cpp b/src/mbgl/gl/vertex_buffer_resource.cpp new file mode 100644 index 0000000000..cddbdd43d0 --- /dev/null +++ b/src/mbgl/gl/vertex_buffer_resource.cpp @@ -0,0 +1,14 @@ +#include +#include + +namespace mbgl { +namespace gl { + +VertexBufferResource::~VertexBufferResource() { + auto& stats = buffer.get_deleter().context.renderingStats(); + stats.memVertexBuffers -= byteSize; + assert(stats.memVertexBuffers >= 0); +} + +} // namespace gl +} // namespace mbgl \ No newline at end of file diff --git a/src/mbgl/gl/vertex_buffer_resource.hpp b/src/mbgl/gl/vertex_buffer_resource.hpp index 95e5e75d45..f9c599c757 100644 --- a/src/mbgl/gl/vertex_buffer_resource.hpp +++ b/src/mbgl/gl/vertex_buffer_resource.hpp @@ -8,10 +8,11 @@ namespace gl { class VertexBufferResource : public gfx::VertexBufferResource { public: - VertexBufferResource(UniqueBuffer&& buffer_) : buffer(std::move(buffer_)) { - } + VertexBufferResource(UniqueBuffer&& buffer_, int byteSize_) : buffer(std::move(buffer_)), byteSize(byteSize_) {} + ~VertexBufferResource(); UniqueBuffer buffer; + int byteSize; }; } // namespace gl -- cgit v1.2.1