[Perf] (MG_Backend/DirectGLES): Directly sync texture objects instead of collecting first.

This commit is contained in:
BZLZHH
2026-02-02 18:28:17 +08:00
parent 8f55179493
commit 39a8e72ee9
2 changed files with 33 additions and 58 deletions
+5 -34
View File
@@ -87,8 +87,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
namespace BufferImpl { namespace BufferImpl {
void CreateAndSyncBufferObject(SharedPtr<MG_State::GLState::BufferObject>& bufferObject) { void CreateAndSyncBufferObject(SharedPtr<MG_State::GLState::BufferObject>& bufferObject) {
if (!(bufferObject->GetChangeBits() & BufferChangeBits::DirtyBit)) if (!(bufferObject->GetChangeBits() & BufferChangeBits::DirtyBit)) return;
return;
const auto& backendBufferIt = g_backendBufferObjects.find(bufferObject); const auto& backendBufferIt = g_backendBufferObjects.find(bufferObject);
SharedPtr<BackendBufferObject> backendBufferObject; SharedPtr<BackendBufferObject> backendBufferObject;
@@ -205,21 +204,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
// 1. textures bound to texture units (TODO: only sync ones that are used in current program) // 1. textures bound to texture units (TODO: only sync ones that are used in current program)
// 2. textures used in current FBO // 2. textures used in current FBO
// 3. textures bound to image units (TODO) // 3. textures bound to image units (TODO)
// constexpr SizeT TextureTargetCount = static_cast<SizeT>(TextureTarget::TextureTargetCount);
// std::bitset<TextureTargetCount> dirtyTextureTargetBits;
Vector<SharedPtr<MG_State::GLState::ITextureObject>> texturesToSync;
for (int index = 0; index < MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; ++index) { for (int index = 0; index < MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS; ++index) {
auto& unit = MG_State::pGLContext->GetTextureUnitObject(index); auto& unit = MG_State::pGLContext->GetTextureUnitObject(index);
for (const auto& bindingSlot : unit.GetAllBindingSlots()) { for (const auto& bindingSlot : unit.GetAllBindingSlots()) {
const auto& textureObject = bindingSlot.GetBoundObject(); auto textureObject = bindingSlot.GetBoundObject();
if (textureObject) { if (textureObject) {
const auto& end = texturesToSync.end(); SyncTextureObjectToBackend(textureObject);
if (std::find(texturesToSync.begin(), end, textureObject) == end) {
texturesToSync.push_back(textureObject);
// dirtyTextureTargetBits.set(static_cast<SizeT>(textureObject->GetTarget()));
}
} }
} }
} }
@@ -229,32 +220,12 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (currentFBO) { if (currentFBO) {
for (const auto& attachment : currentFBO->GetAllAttachments()) { for (const auto& attachment : currentFBO->GetAllAttachments()) {
if (!attachment.IsTexture()) continue; if (!attachment.IsTexture()) continue;
const auto& textureObject = attachment.GetTexture(); auto textureObject = attachment.GetTexture();
if (textureObject) { if (textureObject) {
const auto& end = texturesToSync.end(); SyncTextureObjectToBackend(textureObject);
if (std::find(texturesToSync.begin(), end, textureObject) == end) {
texturesToSync.push_back(textureObject);
// dirtyTextureTargetBits.set(static_cast<SizeT>(textureObject->GetTarget()));
}
} }
} }
} }
// BufferImpl::BackendBufferBindingProtector pixelUnpackProtector =
// BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER);
//
// Vector<BackendTextureBindingProtector> textureBindingProtectors;
// for (SizeT target = 0; target < TextureTargetCount; ++target) {
// if (dirtyTextureTargetBits[target]) {
// textureBindingProtectors.emplace_back(
// MG_Util::ConvertTextureTargetToGLEnum(static_cast<TextureTarget>(target)));
// }
// }
// Do real sync
for (auto& textureObject : texturesToSync) {
SyncTextureObjectToBackend(textureObject);
}
} }
} // namespace TextureImpl } // namespace TextureImpl
+28 -24
View File
@@ -382,8 +382,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str()); MG_Util::ConvertTextureInternalFormatToString(textureMipmapObject->GetFormat()).c_str());
if (needsRegeneration) { if (needsRegeneration) {
MGLOG_D("Texture state changed significantly or not initialized, regenerating texture with ID: %u", MGLOG_D(
m_backendTextureId); "Texture state changed significantly or not initialized, regenerating texture with ID: %u",
m_backendTextureId);
// Regenerate all mipmap levels // Regenerate all mipmap levels
GLenum glInternalFormat, glType, glFormat; GLenum glInternalFormat, glType, glFormat;
@@ -400,11 +401,11 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto* pData = (levelDirty && levelByteSize != 0) auto* pData = (levelDirty && levelByteSize != 0)
? textureMipmapObject->MapMipmapData(uploadTarget, level) ? textureMipmapObject->MapMipmapData(uploadTarget, level)
: nullptr; : nullptr;
MGLOG_D( MGLOG_D("%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p, "
"%s: target: %s: syncing mip %d: %dx%dx%d, byteSize = %d, pData = %p, levelDirty = %s", "levelDirty = %s",
__func__, MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(), level, __func__, MG_Util::ConvertTextureUploadTargetToString(uploadTarget).c_str(),
levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(), levelByteSize, pData, level, levelTexelSize.x(), levelTexelSize.y(), levelTexelSize.z(),
levelDirty ? "true" : "false"); levelByteSize, pData, levelDirty ? "true" : "false");
errorLopper.Clear(); errorLopper.Clear();
MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); MG_External::GLES::glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
@@ -415,14 +416,15 @@ namespace MobileGL::MG_Backend::DirectGLES {
case TextureTarget::TextureCubeMap: { case TextureTarget::TextureCubeMap: {
MG_External::GLES::glTexImage2D( MG_External::GLES::glTexImage2D(
glUploadTarget, static_cast<GLint>(level), glInternalFormat, glUploadTarget, static_cast<GLint>(level), glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()), static_cast<GLsizei>(levelTexelSize.x()),
0, glFormat, glType, pData); static_cast<GLsizei>(levelTexelSize.y()), 0, glFormat, glType, pData);
break; break;
} }
case TextureTarget::Texture3D: { case TextureTarget::Texture3D: {
MG_External::GLES::glTexImage3D( MG_External::GLES::glTexImage3D(
glUploadTarget, static_cast<GLint>(level), glInternalFormat, glUploadTarget, static_cast<GLint>(level), glInternalFormat,
static_cast<GLsizei>(levelTexelSize.x()), static_cast<GLsizei>(levelTexelSize.y()), static_cast<GLsizei>(levelTexelSize.x()),
static_cast<GLsizei>(levelTexelSize.y()),
static_cast<GLsizei>(levelTexelSize.z()), 0, glFormat, glType, pData); static_cast<GLsizei>(levelTexelSize.z()), 0, glFormat, glType, pData);
break; break;
} }
@@ -433,15 +435,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
} }
errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__, glUploadTarget, errorLopper.Loop([file = __FILE__, line = __LINE__, func = __func__, glUploadTarget,
glInternalFormat, glFormat, glType, pData](GLenum err) { glInternalFormat, glFormat, glType, pData](GLenum err) {
MGLOG_D("%s(%s:%d) ES error: %s. glTexImage*: target=%s, internalformat=%s, format=%s, " MGLOG_D(
"type=%s, pixels=%p", "%s(%s:%d) ES error: %s. glTexImage*: target=%s, internalformat=%s, format=%s, "
func, file, line, MG_Util::ConvertGLEnumToString(err).c_str(), "type=%s, pixels=%p",
MG_Util::ConvertGLEnumToString(glUploadTarget).c_str(), func, file, line, MG_Util::ConvertGLEnumToString(err).c_str(),
MG_Util::ConvertGLEnumToString(glInternalFormat).c_str(), MG_Util::ConvertGLEnumToString(glUploadTarget).c_str(),
MG_Util::ConvertGLEnumToString(glFormat).c_str(), MG_Util::ConvertGLEnumToString(glInternalFormat).c_str(),
MG_Util::ConvertGLEnumToString(glType).c_str(), pData); MG_Util::ConvertGLEnumToString(glFormat).c_str(),
MG_Util::ConvertGLEnumToString(glType).c_str(), pData);
}); });
MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level, m_backendTextureId); MGLOG_D("Regenerated mipmap level %d for texture with ID: %u", level,
m_backendTextureId);
textureMipmapObject->MarkStorageDirty(uploadTarget, level, false); textureMipmapObject->MarkStorageDirty(uploadTarget, level, false);
} }
} }
@@ -481,10 +485,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertGLEnumToString(err).c_str()); MG_Util::ConvertGLEnumToString(err).c_str());
}); });
auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level); auto texelSize = textureMipmapObject->GetMipmapTexelSize(uploadTarget, level);
MG_External::GLES::glTexSubImage2D(glUploadTarget, static_cast<GLint>(level), 0, 0, MG_External::GLES::glTexSubImage2D(
static_cast<GLsizei>(texelSize.x()), glUploadTarget, static_cast<GLint>(level), 0, 0,
static_cast<GLsizei>(texelSize.y()), glFormat, glType, static_cast<GLsizei>(texelSize.x()), static_cast<GLsizei>(texelSize.y()), glFormat,
textureMipmapObject->MapMipmapData(uploadTarget, level)); glType, textureMipmapObject->MapMipmapData(uploadTarget, level));
textureMipmapObject->MarkStorageDirty(uploadTarget, level, false); textureMipmapObject->MarkStorageDirty(uploadTarget, level, false);
} }
} }
@@ -522,8 +526,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto backendId = backendBufferObject->GetBackendBufferId(); auto backendId = backendBufferObject->GetBackendBufferId();
GLenum glInternalFormat, glType, glFormat; GLenum glInternalFormat, glType, glFormat;
TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat, &glFormat, TextureImpl::GenerateTextureFormatInfo(textureBufferObject->GetFormat(), &glInternalFormat,
&glType); &glFormat, &glType);
MG_External::GLES::glTexBuffer(GL_TEXTURE_BUFFER, glInternalFormat, backendId); MG_External::GLES::glTexBuffer(GL_TEXTURE_BUFFER, glInternalFormat, backendId);