mirror of
https://github.com/leozide/leocad.git
synced 2026-10-26 22:10:32 +00:00
Texture lookup previously acquired references implicitly, and mesh sections and loader requests paired raw texture pointers with manual release paths. Separate borrowed lookup from scoped acquisition and explicit load requests/waits to match the piece data ownership API. Store lcTextureRef in mesh sections and loader requests, retain references on section copies, and reset worker-shared request handles on the UI thread before completion, cancellation, or shutdown. Keep reference primitives internal and use scoped acquisitions for merge validation. Remove redundant section initialization and synth-notification resets, and document the resulting ownership contracts. Validation: macOS Debug build, diff whitespace checks, and 30 offscreen lifecycle checks covering reference copies/moves, texture dependencies, cancellation, shutdown, merge conflicts, and existing piece ownership paths. Successful GPU upload/rendering is not covered by the offscreen checks.
136 lines
3.0 KiB
C++
136 lines
3.0 KiB
C++
#include "lc_global.h"
|
|
#include "lc_texturemanager.h"
|
|
#include "lc_file.h"
|
|
#include "lc_string.h"
|
|
|
|
lcTextureManager::~lcTextureManager()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void lcTextureManager::Clear()
|
|
{
|
|
QMutexLocker Lock(&mMutex);
|
|
|
|
for (lcTexture* Texture : mTextures)
|
|
delete Texture;
|
|
|
|
mTextures.clear();
|
|
}
|
|
|
|
void lcTextureManager::AddTextureReference(lcTexture* Texture)
|
|
{
|
|
QMutexLocker Lock(&mMutex);
|
|
|
|
Texture->AddRef();
|
|
}
|
|
|
|
lcTexture* lcTextureManager::FindTexture(const lcFileSource& Source)
|
|
{
|
|
QMutexLocker Lock(&mMutex);
|
|
|
|
for (lcTexture* Texture : mTextures)
|
|
if (Texture->mSource == Source)
|
|
return Texture;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
lcTexture* lcTextureManager::AcquireTexture(const char* TextureName, const lcFileSource& Source, const QString& ProjectPath)
|
|
{
|
|
if (!TextureName[0] || strlen(TextureName) >= LC_TEXTURE_NAME_LEN)
|
|
return nullptr;
|
|
|
|
if (!Source.EmbeddedData && Source.FilePath.isEmpty() && Source.ArchiveIndex == -1)
|
|
return nullptr;
|
|
|
|
QMutexLocker Lock(&mMutex);
|
|
|
|
for (lcTexture* Texture : mTextures)
|
|
{
|
|
if (Texture->mSource != Source)
|
|
continue;
|
|
|
|
Texture->AddRef();
|
|
|
|
return Texture;
|
|
}
|
|
|
|
lcTexture* Texture = new lcTexture(LC_TEXTURE_MIPMAPS);
|
|
|
|
lcstrcpy(Texture->mName, TextureName);
|
|
Texture->mSource = Source;
|
|
Texture->SetTemporary(bool(Source.EmbeddedData) || !ProjectPath.isEmpty());
|
|
Texture->AddRef();
|
|
|
|
mTextures.push_back(Texture);
|
|
|
|
return Texture;
|
|
}
|
|
|
|
lcTextureBuildResult lcTextureManager::BuildTextureData(lcFile& File)
|
|
{
|
|
lcTextureBuildResult Result = DecodeTextureData(File);
|
|
|
|
if (!Result.DecodedImage.isNull())
|
|
{
|
|
Result.DecodedImage = lcTexture::PrepareImage(std::move(Result.DecodedImage));
|
|
|
|
if (Result.DecodedImage.isNull())
|
|
Result.Error = lcTextureLoadError::DecodeFailed;
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
lcTextureBuildResult lcTextureManager::DecodeTextureData(lcFile& File)
|
|
{
|
|
lcTextureBuildResult Result;
|
|
|
|
bool Loaded = false;
|
|
|
|
if (lcMemFile* MemoryFile = dynamic_cast<lcMemFile*>(&File))
|
|
{
|
|
if (MemoryFile->mBuffer && MemoryFile->mPosition < MemoryFile->mFileSize)
|
|
{
|
|
const size_t Length = MemoryFile->mFileSize - MemoryFile->mPosition;
|
|
|
|
if (Length <= static_cast<size_t>(std::numeric_limits<int>::max()))
|
|
Loaded = Result.DecodedImage.loadFromData(MemoryFile->mBuffer + MemoryFile->mPosition, static_cast<int>(Length));
|
|
}
|
|
}
|
|
else if (lcDiskFile* DiskFile = dynamic_cast<lcDiskFile*>(&File))
|
|
{
|
|
QFile& Device = DiskFile->GetFile();
|
|
const qint64 Position = Device.pos();
|
|
|
|
if (Position >= 0)
|
|
{
|
|
Loaded = Result.DecodedImage.load(&Device, nullptr);
|
|
const bool Restored = Device.seek(Position);
|
|
Loaded = Loaded && Restored;
|
|
}
|
|
}
|
|
|
|
if (!Loaded || Result.DecodedImage.isNull())
|
|
{
|
|
Result.DecodedImage = QImage();
|
|
Result.Error = lcTextureLoadError::DecodeFailed;
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
void lcTextureManager::ReleaseTexture(lcTexture* Texture)
|
|
{
|
|
QMutexLocker Lock(&mMutex);
|
|
|
|
if (Texture->Release() == 0 && Texture->IsTemporary())
|
|
{
|
|
std::vector<lcTexture*>::iterator TextureIt = std::find(mTextures.begin(), mTextures.end(), Texture);
|
|
if (TextureIt != mTextures.end())
|
|
mTextures.erase(TextureIt);
|
|
delete Texture;
|
|
}
|
|
}
|