mirror of
https://github.com/leozide/leocad
synced 2025-01-30 20:34:56 +01:00
Only upload textures from the main thread.
This commit is contained in:
parent
a57c6275c0
commit
880f8f9a47
5 changed files with 67 additions and 42 deletions
|
@ -1687,6 +1687,22 @@ void lcPiecesLibrary::ReleaseTexture(lcTexture* Texture)
|
|||
}
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::QueueTextureUpload(lcTexture* Texture)
|
||||
{
|
||||
QMutexLocker Lock(&mTextureMutex);
|
||||
mTextureUploads.push_back(Texture);
|
||||
}
|
||||
|
||||
void lcPiecesLibrary::UploadTextures()
|
||||
{
|
||||
QMutexLocker Lock(&mTextureMutex);
|
||||
|
||||
for (lcTexture* Texture : mTextureUploads)
|
||||
Texture->Upload();
|
||||
|
||||
mTextureUploads.clear();
|
||||
}
|
||||
|
||||
bool lcPiecesLibrary::LoadPrimitive(lcLibraryPrimitive* Primitive)
|
||||
{
|
||||
mLoadMutex.lock();
|
||||
|
|
|
@ -179,6 +179,8 @@ public:
|
|||
lcTexture* FindTexture(const char* TextureName, Project* CurrentProject, bool SearchProjectFolder);
|
||||
bool LoadTexture(lcTexture* Texture);
|
||||
void ReleaseTexture(lcTexture* Texture);
|
||||
void QueueTextureUpload(lcTexture* Texture);
|
||||
void UploadTextures();
|
||||
|
||||
bool PieceInCategory(PieceInfo* Info, const char* CategoryKeywords) const;
|
||||
void GetCategoryEntries(int CategoryIndex, bool GroupPieces, lcArray<PieceInfo*>& SinglePieces, lcArray<PieceInfo*>& GroupedPieces);
|
||||
|
@ -246,6 +248,9 @@ protected:
|
|||
QList<QFuture<void>> mLoadFutures;
|
||||
QList<PieceInfo*> mLoadQueue;
|
||||
|
||||
QMutex mTextureMutex;
|
||||
std::vector<lcTexture*> mTextureUploads;
|
||||
|
||||
QString mCachePath;
|
||||
qint64 mArchiveCheckSum[4];
|
||||
QString mLibraryFileName;
|
||||
|
|
|
@ -219,7 +219,9 @@ void lcScene::DrawRenderMeshes(lcContext* Context, int PrimitiveTypes, bool Enab
|
|||
|
||||
void lcScene::Draw(lcContext* Context) const
|
||||
{
|
||||
lcGetPiecesLibrary()->UpdateBuffers(Context); // TODO: find a better place for this update
|
||||
// TODO: find a better place for these updates
|
||||
lcGetPiecesLibrary()->UpdateBuffers(Context);
|
||||
lcGetPiecesLibrary()->UploadTextures();
|
||||
|
||||
Context->SetViewMatrix(mViewMatrix);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ lcTexture* lcLoadTexture(const QString& FileName, int Flags)
|
|||
|
||||
void lcReleaseTexture(lcTexture* Texture)
|
||||
{
|
||||
if (Texture && Texture->Release() == 0)
|
||||
if (Texture && !Texture->Release())
|
||||
delete Texture;
|
||||
}
|
||||
|
||||
|
@ -46,12 +46,12 @@ lcTexture::~lcTexture()
|
|||
void lcTexture::CreateGridTexture()
|
||||
{
|
||||
const int NumLevels = 9;
|
||||
Image GridImages[NumLevels];
|
||||
mImages.resize(NumLevels);
|
||||
quint8* Previous = nullptr;
|
||||
|
||||
for (int ImageLevel = 0; ImageLevel < NumLevels; ImageLevel++)
|
||||
{
|
||||
Image& GridImage = GridImages[ImageLevel];
|
||||
Image& GridImage = mImages[ImageLevel];
|
||||
const int GridSize = 256 >> ImageLevel;
|
||||
GridImage.Allocate(GridSize, GridSize, LC_PIXEL_FORMAT_A8);
|
||||
|
||||
|
@ -156,9 +156,10 @@ void lcTexture::CreateGridTexture()
|
|||
Previous = GridImage.mData;
|
||||
}
|
||||
|
||||
Load(GridImages, NumLevels, LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV | LC_TEXTURE_MIPMAPS | LC_TEXTURE_ANISOTROPIC);
|
||||
|
||||
mRefCount = 1;
|
||||
mFlags = LC_TEXTURE_WRAPU | LC_TEXTURE_WRAPV | LC_TEXTURE_MIPMAPS | LC_TEXTURE_ANISOTROPIC;
|
||||
|
||||
lcGetPiecesLibrary()->QueueTextureUpload(this);
|
||||
}
|
||||
|
||||
bool lcTexture::Load()
|
||||
|
@ -168,28 +169,28 @@ bool lcTexture::Load()
|
|||
|
||||
bool lcTexture::Load(const QString& FileName, int Flags)
|
||||
{
|
||||
Image image;
|
||||
mImages.resize(1);
|
||||
|
||||
if (!image.FileLoad(FileName))
|
||||
if (!mImages[0].FileLoad(FileName))
|
||||
return false;
|
||||
|
||||
return Load(image, Flags);
|
||||
return Load(Flags);
|
||||
}
|
||||
|
||||
bool lcTexture::Load(lcMemFile& File, int Flags)
|
||||
{
|
||||
Image image;
|
||||
mImages.resize(1);
|
||||
|
||||
if (!image.FileLoad(File))
|
||||
if (!mImages[0].FileLoad(File))
|
||||
return false;
|
||||
|
||||
return Load(image, Flags);
|
||||
return Load(Flags);
|
||||
}
|
||||
|
||||
bool lcTexture::Load(Image* images, int NumLevels, int Flags) // todo: this should be part of lcContext, it can be called from multiple threads
|
||||
void lcTexture::Upload()
|
||||
{
|
||||
mWidth = images[0].mWidth;
|
||||
mHeight = images[0].mHeight;
|
||||
mWidth = mImages[0].mWidth;
|
||||
mHeight = mImages[0].mHeight;
|
||||
|
||||
glGenTextures(1, &mTexture);
|
||||
|
||||
|
@ -199,13 +200,13 @@ bool lcTexture::Load(Image* images, int NumLevels, int Flags) // todo: this shou
|
|||
{ GL_NEAREST, GL_LINEAR, GL_LINEAR, GL_LINEAR, GL_LINEAR },
|
||||
};
|
||||
|
||||
int FilterFlags = Flags & LC_TEXTURE_FILTER_MASK;
|
||||
int FilterFlags = mFlags & LC_TEXTURE_FILTER_MASK;
|
||||
int FilterIndex = FilterFlags >> LC_TEXTURE_FILTER_SHIFT;
|
||||
int MipIndex = Flags & LC_TEXTURE_MIPMAPS ? 0 : 1;
|
||||
int MipIndex = mFlags & LC_TEXTURE_MIPMAPS ? 0 : 1;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (Flags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (Flags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (mFlags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (mFlags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filters[MipIndex][FilterIndex]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filters[1][FilterIndex]);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
@ -214,7 +215,7 @@ bool lcTexture::Load(Image* images, int NumLevels, int Flags) // todo: this shou
|
|||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, lcMin(4.0f, gMaxAnisotropy));
|
||||
|
||||
int Format;
|
||||
switch (images[0].mFormat)
|
||||
switch (mImages[0].mFormat)
|
||||
{
|
||||
default:
|
||||
case LC_PIXEL_FORMAT_INVALID:
|
||||
|
@ -234,15 +235,15 @@ bool lcTexture::Load(Image* images, int NumLevels, int Flags) // todo: this shou
|
|||
break;
|
||||
}
|
||||
|
||||
void* Data = images[0].mData;
|
||||
void* Data = mImages[0].mData;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, Format, mWidth, mHeight, 0, Format, GL_UNSIGNED_BYTE, Data);
|
||||
int MaxLevel = 0;
|
||||
|
||||
if (Flags & LC_TEXTURE_MIPMAPS)
|
||||
if (mFlags & LC_TEXTURE_MIPMAPS)
|
||||
{
|
||||
int Width = mWidth;
|
||||
int Height = mHeight;
|
||||
int Components = images[0].GetBPP();
|
||||
int Components = mImages[0].GetBPP();
|
||||
|
||||
for (int Level = 1; ((Width != 1) || (Height != 1)); Level++)
|
||||
{
|
||||
|
@ -251,7 +252,7 @@ bool lcTexture::Load(Image* images, int NumLevels, int Flags) // todo: this shou
|
|||
Width = lcMax(1, Width >> 1);
|
||||
Height = lcMax(1, Height >> 1);
|
||||
|
||||
if (NumLevels == 1)
|
||||
if (mImages.size() == 1)
|
||||
{
|
||||
GLubyte *Out, *In;
|
||||
|
||||
|
@ -263,7 +264,7 @@ bool lcTexture::Load(Image* images, int NumLevels, int Flags) // todo: this shou
|
|||
Out[c] = (In[c] + In[c + Components] + In[RowStride] + In[c + RowStride + Components]) / 4;
|
||||
}
|
||||
else
|
||||
Data = images[Level].mData;
|
||||
Data = mImages[Level].mData;
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, Level, Format, Width, Height, 0, Format, GL_UNSIGNED_BYTE, Data);
|
||||
MaxLevel++;
|
||||
|
@ -272,15 +273,16 @@ bool lcTexture::Load(Image* images, int NumLevels, int Flags) // todo: this shou
|
|||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MaxLevel);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lcTexture::Load(Image& image, int Flags)
|
||||
bool lcTexture::Load(int Flags)
|
||||
{
|
||||
image.ResizePow2();
|
||||
for (Image& Image : mImages)
|
||||
Image.ResizePow2();
|
||||
mFlags = Flags;
|
||||
|
||||
return Load(&image, 1, Flags);
|
||||
lcGetPiecesLibrary()->QueueTextureUpload(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void lcTexture::Unload()
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#define LC_TEXTURE_NAME_LEN 256
|
||||
|
||||
class Image;
|
||||
#include "image.h"
|
||||
|
||||
class lcTexture
|
||||
{
|
||||
|
@ -26,28 +26,25 @@ public:
|
|||
|
||||
bool Load(const QString& FileName, int Flags = 0);
|
||||
bool Load(lcMemFile& File, int Flags = 0);
|
||||
bool Load(Image& image, int Flags);
|
||||
bool Load(Image* images, int NumLevels, int Flags);
|
||||
void Upload();
|
||||
void Unload();
|
||||
|
||||
int AddRef()
|
||||
void AddRef()
|
||||
{
|
||||
mRefCount++;
|
||||
mRefCount.ref();
|
||||
|
||||
if (mRefCount == 1)
|
||||
Load();
|
||||
|
||||
return mRefCount;
|
||||
}
|
||||
|
||||
int Release()
|
||||
bool Release()
|
||||
{
|
||||
mRefCount--;
|
||||
bool InUse = mRefCount.deref();
|
||||
|
||||
if (!mRefCount)
|
||||
if (!InUse)
|
||||
Unload();
|
||||
|
||||
return mRefCount;
|
||||
return InUse;
|
||||
}
|
||||
|
||||
void SetTemporary(bool Temporary)
|
||||
|
@ -67,9 +64,12 @@ public:
|
|||
|
||||
protected:
|
||||
bool Load();
|
||||
bool Load(int Flags);
|
||||
|
||||
bool mTemporary;
|
||||
int mRefCount;
|
||||
QAtomicInt mRefCount;
|
||||
std::vector<Image> mImages;
|
||||
int mFlags;
|
||||
};
|
||||
|
||||
lcTexture* lcLoadTexture(const QString& FileName, int Flags);
|
||||
|
|
Loading…
Add table
Reference in a new issue