Correct and revise OpenGL texture pooling (#2709)

This commit is contained in:
alasram
2024-08-29 14:13:26 -07:00
committed by GitHub
parent 290bf927f5
commit b850c257a3
79 changed files with 817 additions and 247 deletions

View File

@@ -98,6 +98,8 @@ Context::Context(RendererBackend& backend_)
#if MLN_DRAWABLE_RENDERER
uboAllocator = std::make_unique<gl::UniformBufferAllocator>();
#endif
texturePool = std::make_unique<Texture2DPool>(this);
}
Context::~Context() noexcept {
@@ -105,6 +107,10 @@ Context::~Context() noexcept {
backend.getThreadPool().runRenderJobs(true /* closeQueue */);
reset();
// Delete all pooled resources while the context is still valid
texturePool.reset();
#if !defined(NDEBUG)
Log::Debug(Event::General, "Rendering Stats:\n" + stats.toString("\n"));
#endif
@@ -265,18 +271,14 @@ void Context::verifyProgramLinkage(ProgramID program_) {
throw std::runtime_error("program failed to link");
}
UniqueTexture Context::createUniqueTexture() {
UniqueTexture Context::createUniqueTexture(const Size& size,
gfx::TexturePixelType format,
gfx::TextureChannelDataType type) {
MLN_TRACE_FUNC();
if (pooledTextures.empty()) {
pooledTextures.resize(TextureMax);
MBGL_CHECK_ERROR(glGenTextures(TextureMax, pooledTextures.data()));
stats.numCreatedTextures += TextureMax;
}
assert(texturePool);
TextureID id = texturePool->alloc(size, format, type);
TextureID id = pooledTextures.back();
pooledTextures.pop_back();
stats.numActiveTextures++;
// NOLINTNEXTLINE(performance-move-const-arg)
return UniqueTexture{std::move(id), {this}};
}
@@ -306,27 +308,13 @@ std::unique_ptr<gfx::TextureResource> Context::createTextureResource(const Size
const gfx::TextureChannelDataType type) {
MLN_TRACE_FUNC();
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),
textureByteSize);
auto obj = createUniqueTexture(size, format, type);
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>::sizedFor(format, type),
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.
@@ -530,9 +518,10 @@ std::unique_ptr<gfx::DrawScopeResource> Context::createDrawScopeResource() {
void Context::reset() {
MLN_TRACE_FUNC();
std::copy(pooledTextures.begin(), pooledTextures.end(), std::back_inserter(abandonedTextures));
pooledTextures.resize(0);
performCleanup();
// Delete all unused pooled resources
texturePool->shrink();
}
#if MLN_DRAWABLE_RENDERER
@@ -883,10 +872,8 @@ void Context::performCleanup() {
binding.setDirty();
}
}
texturePool->release(id);
}
MBGL_CHECK_ERROR(glDeleteTextures(int(abandonedTextures.size()), abandonedTextures.data()));
stats.numCreatedTextures -= int(abandonedTextures.size());
assert(stats.numCreatedTextures >= 0);
abandonedTextures.clear();
}
@@ -923,6 +910,8 @@ void Context::reduceMemoryUsage() {
MLN_TRACE_FUNC_GL();
performCleanup();
assert(texturePool);
texturePool->shrink();
// Ensure that all pending actions are executed to ensure that they happen
// before the app goes to the background.
@@ -949,5 +938,10 @@ void Context::clearStencilBuffer(const int32_t bits) {
stats.stencilClears++;
}
Texture2DPool& Context::getTexturePool() {
assert(texturePool);
return *texturePool;
}
} // namespace gl
} // namespace mbgl