Correct and revise OpenGL texture pooling (#2709)
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user