Make rendering stats thread safe [Core feature] (#4059)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Adrian Cojocaru <adrian.cojocaru92@yahoo.com> Co-authored-by: Bart Louwers <bart.louwers@gmail.com>
This commit is contained in:
@@ -13,6 +13,8 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -93,6 +95,16 @@ public:
|
||||
gfx::RenderingStats& renderingStats() { return stats; }
|
||||
const gfx::RenderingStats& renderingStats() const { return stats; }
|
||||
|
||||
void threadSafeAccessRenderingStats(const std::function<void(RenderingStats&)>& function) {
|
||||
std::scoped_lock lock(renderingStatsMutex);
|
||||
function(stats);
|
||||
}
|
||||
|
||||
RenderingStats threadSafeCopyRenderingStats() {
|
||||
std::shared_lock lock(renderingStatsMutex);
|
||||
return stats;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
virtual void visualizeStencilBuffer() = 0;
|
||||
virtual void visualizeDepthBuffer(float depthRangeSize) = 0;
|
||||
@@ -174,6 +186,7 @@ protected:
|
||||
virtual std::unique_ptr<RenderbufferResource> createRenderbufferResource(RenderbufferPixelType, Size) = 0;
|
||||
virtual std::unique_ptr<DrawScopeResource> createDrawScopeResource() = 0;
|
||||
|
||||
std::shared_mutex renderingStatsMutex;
|
||||
gfx::RenderingStats stats;
|
||||
ContextObserver* observer;
|
||||
};
|
||||
|
||||
@@ -184,9 +184,11 @@ void Texture2D::createMetalTexture() noexcept {
|
||||
|
||||
if (metalTexture) {
|
||||
textureDirty = false;
|
||||
context.renderingStats().numCreatedTextures++;
|
||||
context.renderingStats().numActiveTextures++;
|
||||
context.renderingStats().memTextures += getDataSize();
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numCreatedTextures++;
|
||||
stats.numActiveTextures++;
|
||||
stats.memTextures += getDataSize();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,8 +207,10 @@ void Texture2D::destroyMetalTexture() noexcept {
|
||||
}
|
||||
|
||||
metalTexture.reset();
|
||||
context.renderingStats().numActiveTextures--;
|
||||
context.renderingStats().memTextures -= getDataSize();
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numActiveTextures--;
|
||||
stats.memTextures -= getDataSize();
|
||||
});
|
||||
}
|
||||
|
||||
gfx::Texture2D& Texture2D::setUsage(MTL::TextureUsage usage_) noexcept {
|
||||
@@ -250,11 +254,11 @@ void Texture2D::bind(RenderPass& renderPass, int32_t location) noexcept {
|
||||
renderPass.setFragmentTexture(metalTexture, location);
|
||||
renderPass.setFragmentSamplerState(metalSamplerState, location);
|
||||
|
||||
context.renderingStats().numTextureBindings++;
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) { stats.numTextureBindings++; });
|
||||
}
|
||||
|
||||
void Texture2D::unbind(RenderPass&, int32_t /*location*/) noexcept {
|
||||
context.renderingStats().numTextureBindings--;
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) { stats.numTextureBindings--; });
|
||||
}
|
||||
|
||||
void Texture2D::upload(const void* pixelData, const Size& size_) noexcept {
|
||||
@@ -277,8 +281,10 @@ void Texture2D::uploadSubRegion(const void* pixelData, const Size& size_, uint16
|
||||
const MTL::Region region = MTL::Region::Make2D(xOffset, yOffset, size_.width, size_.height);
|
||||
const NS::UInteger bytesPerRow = size_.width * getPixelStride();
|
||||
metalTexture->replaceRegion(region, 0, pixelData, bytesPerRow);
|
||||
context.renderingStats().numTextureUpdates++;
|
||||
context.renderingStats().textureUpdateBytes += bytesPerRow * size_.height;
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numTextureUpdates++;
|
||||
stats.textureUpdateBytes += bytesPerRow * size_.height;
|
||||
});
|
||||
}
|
||||
|
||||
void Texture2D::upload() noexcept {
|
||||
|
||||
@@ -468,7 +468,7 @@ void Renderer::Impl::render(const RenderTree& renderTree, const std::shared_ptr<
|
||||
renderTreeParameters.loaded ? RendererObserver::RenderMode::Full : RendererObserver::RenderMode::Partial,
|
||||
renderTreeParameters.needsRepaint,
|
||||
renderTreeParameters.placementChanged,
|
||||
context.renderingStats());
|
||||
context.threadSafeCopyRenderingStats());
|
||||
|
||||
if (!renderTreeParameters.loaded) {
|
||||
renderState = RenderState::Partial;
|
||||
|
||||
@@ -105,12 +105,13 @@ BufferResource::BufferResource(
|
||||
}
|
||||
|
||||
if (isValid()) {
|
||||
auto& stats = context.renderingStats();
|
||||
stats.numBuffers++;
|
||||
stats.memBuffers += totalSize;
|
||||
stats.totalBuffers++;
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numBuffers++;
|
||||
stats.memBuffers += totalSize;
|
||||
stats.totalBuffers++;
|
||||
|
||||
stats.totalBufferObjs++;
|
||||
stats.totalBufferObjs++;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,13 +129,15 @@ BufferResource::BufferResource(BufferResource&& other) noexcept
|
||||
|
||||
BufferResource::~BufferResource() noexcept {
|
||||
if (isValid()) {
|
||||
context.renderingStats().numBuffers--;
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numBuffers--;
|
||||
|
||||
if (bufferWindowSize > 0) {
|
||||
context.renderingStats().memBuffers -= bufferWindowSize * context.getBackend().getMaxFrames();
|
||||
} else {
|
||||
context.renderingStats().memBuffers -= size;
|
||||
}
|
||||
if (bufferWindowSize > 0) {
|
||||
stats.memBuffers -= bufferWindowSize * context.getBackend().getMaxFrames();
|
||||
} else {
|
||||
stats.memBuffers -= size;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!bufferAllocation) return;
|
||||
@@ -149,8 +152,10 @@ BufferResource BufferResource::clone() const {
|
||||
BufferResource& BufferResource::operator=(BufferResource&& other) noexcept {
|
||||
assert(&context == &other.context);
|
||||
if (isValid()) {
|
||||
context.renderingStats().numBuffers--;
|
||||
context.renderingStats().memBuffers -= size;
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numBuffers--;
|
||||
stats.memBuffers -= size;
|
||||
});
|
||||
}
|
||||
|
||||
size = other.size;
|
||||
@@ -178,10 +183,11 @@ void BufferResource::update(const void* newData, std::size_t updateSize, std::si
|
||||
|
||||
std::memcpy(data, newData, updateSize);
|
||||
|
||||
auto& stats = context.renderingStats();
|
||||
stats.bufferUpdateBytes += updateSize;
|
||||
stats.bufferUpdates++;
|
||||
stats.bufferObjUpdates++;
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.bufferUpdateBytes += updateSize;
|
||||
stats.bufferUpdates++;
|
||||
stats.bufferObjUpdates++;
|
||||
});
|
||||
version++;
|
||||
|
||||
if (version == std::numeric_limits<VersionType>::max()) {
|
||||
|
||||
@@ -224,8 +224,10 @@ void Texture2D::uploadSubRegion(const void* pixelData,
|
||||
context.enqueueDeletion(std::move(function));
|
||||
}
|
||||
|
||||
context.renderingStats().numTextureUpdates++;
|
||||
context.renderingStats().textureUpdateBytes += bufferInfo.size;
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numTextureUpdates++;
|
||||
stats.textureUpdateBytes += bufferInfo.size;
|
||||
});
|
||||
}
|
||||
|
||||
vk::Format Texture2D::vulkanFormat(const gfx::TexturePixelType pixel, gfx::TextureChannelDataType channel) {
|
||||
@@ -385,9 +387,11 @@ void Texture2D::createTexture() {
|
||||
imageLayout = imageCreateInfo.initialLayout;
|
||||
}
|
||||
|
||||
context.renderingStats().numCreatedTextures++;
|
||||
context.renderingStats().numActiveTextures++;
|
||||
context.renderingStats().memTextures += getDataSize();
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numCreatedTextures++;
|
||||
stats.numActiveTextures++;
|
||||
stats.memTextures += getDataSize();
|
||||
});
|
||||
|
||||
textureDirty = false;
|
||||
lastModified = util::MonotonicTimer::now();
|
||||
@@ -431,8 +435,10 @@ void Texture2D::destroyTexture() {
|
||||
|
||||
imageLayout = vk::ImageLayout::eUndefined;
|
||||
|
||||
context.renderingStats().numActiveTextures--;
|
||||
context.renderingStats().memTextures -= Texture2D::getDataSize();
|
||||
context.threadSafeAccessRenderingStats([&](gfx::RenderingStats& stats) {
|
||||
stats.numActiveTextures--;
|
||||
stats.memTextures -= Texture2D::getDataSize();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user