[render-test] Add resource usage tracking to gfx context

This commit is contained in:
Mikko Pulkki
2019-10-15 12:09:21 +03:00
committed by Mikko Pulkki
parent c8576e089f
commit fb062bb23e
16 changed files with 176 additions and 14 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -1,5 +1,6 @@
#include <mbgl/gfx/backend_scope.hpp>
#include <mbgl/gfx/headless_frontend.hpp>
#include <mbgl/gfx/context.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/renderer/renderer.hpp>

View File

@@ -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",

View File

@@ -1,12 +1,13 @@
#pragma once
#include <mbgl/gfx/backend.hpp>
#include <mbgl/gfx/renderbuffer.hpp>
#include <mbgl/gfx/command_encoder.hpp>
#include <mbgl/gfx/draw_scope.hpp>
#include <mbgl/gfx/program.hpp>
#include <mbgl/gfx/types.hpp>
#include <mbgl/gfx/renderbuffer.hpp>
#include <mbgl/gfx/rendering_stats.hpp>
#include <mbgl/gfx/texture.hpp>
#include <mbgl/gfx/types.hpp>
namespace mbgl {
@@ -85,6 +86,8 @@ public:
public:
virtual std::unique_ptr<CommandEncoder> createCommandEncoder() = 0;
virtual const RenderingStats& renderingStats() const = 0;
#if not defined(NDEBUG)
public:
virtual void visualizeStencilBuffer() = 0;

View File

@@ -0,0 +1,12 @@
#include <mbgl/gfx/rendering_stats.hpp>
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

View File

@@ -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<gl::ProcAddress(const char*)>& 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<gfx::TextureResource> 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<gfx::TextureResource> resource =
std::make_unique<gl::TextureResource>(std::move(obj));
std::make_unique<gl::TextureResource>(std::move(obj), textureByteSize);
// Always use texture unit 0 for manipulating it.
activeTextureUnit = 0;
@@ -517,6 +524,8 @@ void Context::clear(optional<mbgl::Color> color,
}
MBGL_CHECK_ERROR(glClear(mask));
stats.numDrawCalls = 0;
}
void Context::setCullFaceMode(const gfx::CullFaceMode& mode) {
@@ -583,6 +592,14 @@ std::unique_ptr<gfx::CommandEncoder> Context::createCommandEncoder() {
return std::make_unique<gl::CommandEncoder>(*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<GLsizei>(indexLength),
GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid*>(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();
}

View File

@@ -43,6 +43,9 @@ public:
std::unique_ptr<gfx::CommandEncoder> createCommandEncoder() override;
gfx::RenderingStats& renderingStats();
const gfx::RenderingStats& renderingStats() const override;
void initializeExtensions(const std::function<gl::ProcAddress(const char*)>&);
void enableDebugging();
@@ -132,6 +135,7 @@ private:
RendererBackend& backend;
bool cleanupOnDestruction = true;
gfx::RenderingStats stats;
std::unique_ptr<extension::Debugging> debugging;
std::unique_ptr<extension::VertexArray> vertexArray;

View File

@@ -0,0 +1,14 @@
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/index_buffer_resource.hpp>
namespace mbgl {
namespace gl {
IndexBufferResource::~IndexBufferResource() {
auto& stats = buffer.get_deleter().context.renderingStats();
stats.memIndexBuffers -= byteSize;
assert(stats.memIndexBuffers >= 0);
}
} // namespace gl
} // namespace mbgl

View File

@@ -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

View File

@@ -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 {

View File

@@ -0,0 +1,45 @@
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/texture_resource.hpp>
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

View File

@@ -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

View File

@@ -20,12 +20,14 @@ std::unique_ptr<gfx::VertexBufferResource> 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<gfx::BufferUsageType>::to(usage)));
return std::make_unique<gl::VertexBufferResource>(std::move(result));
return std::make_unique<gl::VertexBufferResource>(std::move(result), size);
}
void UploadPass::updateVertexBufferResource(gfx::VertexBufferResource& resource,
@@ -39,13 +41,15 @@ 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));
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<gfx::BufferUsageType>::to(usage)));
return std::make_unique<gl::IndexBufferResource>(std::move(result));
return std::make_unique<gl::IndexBufferResource>(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<gfx::TextureResource> resource =
std::make_unique<gl::TextureResource>(std::move(obj));
std::make_unique<gl::TextureResource>(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.

View File

@@ -0,0 +1,14 @@
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/vertex_buffer_resource.hpp>
namespace mbgl {
namespace gl {
VertexBufferResource::~VertexBufferResource() {
auto& stats = buffer.get_deleter().context.renderingStats();
stats.memVertexBuffers -= byteSize;
assert(stats.memVertexBuffers >= 0);
}
} // namespace gl
} // namespace mbgl

View File

@@ -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