mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 02:14:26 +02:00
Trying a different tactic to avoid multiple concurrent file access
This commit is contained in:
parent
f764cd614b
commit
638364497d
10 changed files with 49 additions and 85 deletions
|
@ -222,7 +222,6 @@ GL45StrictResourceTexture::GL45StrictResourceTexture(const std::weak_ptr<GLBacke
|
|||
copyMipFaceFromTexture(sourceMip, targetMip, face);
|
||||
}
|
||||
}
|
||||
_gpuObject.finishTransfer();
|
||||
if (texture.isAutogenerateMips()) {
|
||||
generateMips();
|
||||
}
|
||||
|
|
|
@ -431,7 +431,6 @@ void GL45VariableAllocationTexture::executeNextTransfer(const TexturePointer& cu
|
|||
_currentTransferTexture = currentTexture;
|
||||
if (_pendingTransfers.front()->tryTransfer()) {
|
||||
_pendingTransfers.pop();
|
||||
_currentTransferTexture->finishTransfer();
|
||||
_currentTransferTexture.reset();
|
||||
}
|
||||
}
|
||||
|
@ -456,7 +455,7 @@ GL45ResourceTexture::GL45ResourceTexture(const std::weak_ptr<GLBackend>& backend
|
|||
_memoryPressureStateStale = true;
|
||||
copyMipsFromTexture();
|
||||
syncSampler();
|
||||
_gpuObject.finishTransfer();
|
||||
|
||||
}
|
||||
|
||||
void GL45ResourceTexture::allocateStorage(uint16 allocatedMip) {
|
||||
|
|
|
@ -482,43 +482,39 @@ uint16 Texture::autoGenerateMips(uint16 maxMip) {
|
|||
}
|
||||
|
||||
uint16 Texture::getStoredMipWidth(uint16 level) const {
|
||||
PixelsPointer mipFace = accessStoredMipFace(level);
|
||||
if (mipFace && mipFace->getSize()) {
|
||||
return evalMipWidth(level);
|
||||
if (!isStoredMipFaceAvailable(level)) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return evalMipWidth(level);
|
||||
}
|
||||
|
||||
uint16 Texture::getStoredMipHeight(uint16 level) const {
|
||||
PixelsPointer mip = accessStoredMipFace(level);
|
||||
if (mip && mip->getSize()) {
|
||||
return evalMipHeight(level);
|
||||
if (!isStoredMipFaceAvailable(level)) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return evalMipHeight(level);
|
||||
}
|
||||
|
||||
uint16 Texture::getStoredMipDepth(uint16 level) const {
|
||||
PixelsPointer mipFace = accessStoredMipFace(level);
|
||||
if (mipFace && mipFace->getSize()) {
|
||||
return evalMipDepth(level);
|
||||
if (!isStoredMipFaceAvailable(level)) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return evalMipDepth(level);
|
||||
}
|
||||
|
||||
uint32 Texture::getStoredMipNumTexels(uint16 level) const {
|
||||
PixelsPointer mipFace = accessStoredMipFace(level);
|
||||
if (mipFace && mipFace->getSize()) {
|
||||
return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level);
|
||||
if (!isStoredMipFaceAvailable(level)) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level);
|
||||
}
|
||||
|
||||
uint32 Texture::getStoredMipSize(uint16 level) const {
|
||||
PixelsPointer mipFace = accessStoredMipFace(level);
|
||||
if (mipFace && mipFace->getSize()) {
|
||||
return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize();
|
||||
if (!isStoredMipFaceAvailable(level)) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize();
|
||||
}
|
||||
|
||||
gpu::Resource::Size Texture::getStoredSize() const {
|
||||
|
@ -984,9 +980,3 @@ Texture::ExternalUpdates Texture::getUpdates() const {
|
|||
void Texture::setStorage(std::unique_ptr<Storage>& newStorage) {
|
||||
_storage.swap(newStorage);
|
||||
}
|
||||
|
||||
void Texture::finishTransfer() const {
|
||||
if (_storage) {
|
||||
_storage->releaseTempResources();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,7 +267,6 @@ public:
|
|||
virtual void assignMipData(uint16 level, const storage::StoragePointer& storage) = 0;
|
||||
virtual void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) = 0;
|
||||
virtual bool isMipAvailable(uint16 level, uint8 face = 0) const = 0;
|
||||
virtual void releaseTempResources() const {}
|
||||
Texture::Type getType() const { return _type; }
|
||||
|
||||
Stamp getStamp() const { return _stamp; }
|
||||
|
@ -316,12 +315,10 @@ public:
|
|||
throw std::runtime_error("Invalid call");
|
||||
}
|
||||
void reset() override { }
|
||||
void releaseTempResources() const override { _ktxData.release(); }
|
||||
|
||||
protected:
|
||||
std::string _filename;
|
||||
ktx::KTXDescriptorPointer _ktxDescriptor;
|
||||
mutable ktx::KTXUniquePointer _ktxData;
|
||||
friend class Texture;
|
||||
};
|
||||
|
||||
|
@ -526,11 +523,9 @@ public:
|
|||
|
||||
ExternalUpdates getUpdates() const;
|
||||
|
||||
void finishTransfer() const;
|
||||
|
||||
// Textures can be serialized directly to ktx data file, here is how
|
||||
static ktx::KTXUniquePointer serialize(const Texture& texture);
|
||||
static Texture* unserialize(const ktx::KTXUniquePointer& srcData, TextureUsageType usageType = TextureUsageType::RESOURCE, Usage usage = Usage(), const Sampler::Desc& sampler = Sampler::Desc());
|
||||
static Texture* unserialize(const std::string& ktxFile, TextureUsageType usageType = TextureUsageType::RESOURCE, Usage usage = Usage(), const Sampler::Desc& sampler = Sampler::Desc());
|
||||
static bool evalKTXFormat(const Element& mipFormat, const Element& texelFormat, ktx::Header& header);
|
||||
static bool evalTextureFormat(const ktx::Header& header, Element& mipFormat, Element& texelFormat);
|
||||
|
||||
|
|
|
@ -43,9 +43,11 @@ struct GPUKTXPayload {
|
|||
std::string GPUKTXPayload::KEY { "hifi.gpu" };
|
||||
|
||||
KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) {
|
||||
ktx::StoragePointer storage { new storage::FileStorage(_filename.c_str()) };
|
||||
auto ktxPointer = ktx::KTX::create(storage);
|
||||
_ktxDescriptor.reset(new ktx::KTXDescriptor(ktxPointer->toDescriptor()));
|
||||
{
|
||||
ktx::StoragePointer storage { new storage::FileStorage(_filename.c_str()) };
|
||||
auto ktxPointer = ktx::KTX::create(storage);
|
||||
_ktxDescriptor.reset(new ktx::KTXDescriptor(ktxPointer->toDescriptor()));
|
||||
}
|
||||
|
||||
// now that we know the ktx, let's get the header info to configure this Texture::Storage:
|
||||
Format mipFormat = Format::COLOR_BGRA_32;
|
||||
|
@ -56,11 +58,13 @@ KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) {
|
|||
}
|
||||
|
||||
PixelsPointer KtxStorage::getMipFace(uint16 level, uint8 face) const {
|
||||
if (!_ktxData) {
|
||||
ktx::StoragePointer storage { new storage::FileStorage(_filename.c_str()) };
|
||||
_ktxData = _ktxDescriptor->toKTX(storage);
|
||||
storage::StoragePointer result;
|
||||
auto faceOffset = _ktxDescriptor->getMipFaceTexelsOffset(level, face);
|
||||
auto faceSize = _ktxDescriptor->getMipFaceTexelsSize(level, face);
|
||||
if (faceSize != 0 && faceOffset != 0) {
|
||||
result = std::make_shared<storage::FileStorage>(_filename.c_str())->createView(faceSize, faceOffset)->toMemoryStorage();
|
||||
}
|
||||
return _ktxData->getMipFaceTexelsData(level, face);
|
||||
return result;
|
||||
}
|
||||
|
||||
Size KtxStorage::getMipFaceSize(uint16 level, uint8 face) const {
|
||||
|
@ -180,11 +184,9 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) {
|
|||
return ktxBuffer;
|
||||
}
|
||||
|
||||
Texture* Texture::unserialize(const ktx::KTXUniquePointer& srcData, TextureUsageType usageType, Usage usage, const Sampler::Desc& sampler) {
|
||||
if (!srcData) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto& header = srcData->getHeader();
|
||||
Texture* Texture::unserialize(const std::string& ktxfile, TextureUsageType usageType, Usage usage, const Sampler::Desc& sampler) {
|
||||
ktx::KTXDescriptor descriptor { ktx::KTX::create(ktx::StoragePointer { new storage::FileStorage(ktxfile.c_str()) })->toDescriptor() };
|
||||
const auto& header = descriptor.header;
|
||||
|
||||
Format mipFormat = Format::COLOR_BGRA_32;
|
||||
Format texelFormat = Format::COLOR_SRGBA_32;
|
||||
|
@ -212,7 +214,7 @@ Texture* Texture::unserialize(const ktx::KTXUniquePointer& srcData, TextureUsage
|
|||
|
||||
// If found, use the
|
||||
GPUKTXPayload gpuktxKeyValue;
|
||||
bool isGPUKTXPayload = GPUKTXPayload::findInKeyValues(srcData->_keyValues, gpuktxKeyValue);
|
||||
bool isGPUKTXPayload = GPUKTXPayload::findInKeyValues(descriptor.keyValues, gpuktxKeyValue);
|
||||
|
||||
auto tex = Texture::create( (isGPUKTXPayload ? gpuktxKeyValue._usageType : usageType),
|
||||
type,
|
||||
|
@ -228,14 +230,7 @@ Texture* Texture::unserialize(const ktx::KTXUniquePointer& srcData, TextureUsage
|
|||
|
||||
// Assing the mips availables
|
||||
tex->setStoredMipFormat(mipFormat);
|
||||
uint16_t level = 0;
|
||||
for (auto& image : srcData->_images) {
|
||||
for (uint32_t face = 0; face < image._numFaces; face++) {
|
||||
tex->assignStoredMipFace(level, face, image._faceSize, image._faceBytes[face]);
|
||||
}
|
||||
level++;
|
||||
}
|
||||
|
||||
tex->setKtxBacking(ktxfile);
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,6 +167,17 @@ size_t KTXDescriptor::getMipFaceTexelsSize(uint16_t mip, uint8_t face) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
size_t KTXDescriptor::getMipFaceTexelsOffset(uint16_t mip, uint8_t face) const {
|
||||
size_t result { 0 };
|
||||
if (mip < images.size()) {
|
||||
const auto& faces = images[mip];
|
||||
if (face < faces._numFaces) {
|
||||
result = faces._faceOffsets[face];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ImageDescriptor Image::toImageDescriptor(const Byte* baseAddress) const {
|
||||
FaceOffsets offsets;
|
||||
offsets.resize(_faceBytes.size());
|
||||
|
@ -196,14 +207,5 @@ KTXDescriptor KTX::toDescriptor() const {
|
|||
return { this->_header, this->_keyValues, newDescriptors };
|
||||
}
|
||||
|
||||
std::unique_ptr<KTX> KTXDescriptor::toKTX(const ktx::StoragePointer& storage) const {
|
||||
Images newImages;
|
||||
for (size_t i = 0; i < images.size(); ++i) {
|
||||
newImages.emplace_back(images[i].toImage(storage));
|
||||
}
|
||||
|
||||
return std::unique_ptr<KTX>(new KTX { storage, header, keyValues, newImages });
|
||||
}
|
||||
|
||||
KTX::KTX(const StoragePointer& storage, const Header& header, const KeyValues& keyValues, const Images& images)
|
||||
: _storage(storage), _header(header), _keyValues(keyValues), _images(images) { }
|
|
@ -461,7 +461,7 @@ namespace ktx {
|
|||
const KeyValues keyValues;
|
||||
const ImageDescriptors images;
|
||||
size_t getMipFaceTexelsSize(uint16_t mip = 0, uint8_t face = 0) const;
|
||||
std::unique_ptr<KTX> toKTX(const ktx::StoragePointer& storage) const;
|
||||
size_t getMipFaceTexelsOffset(uint16_t mip = 0, uint8_t face = 0) const;
|
||||
};
|
||||
|
||||
class KTX {
|
||||
|
|
|
@ -38,10 +38,3 @@ std::unique_ptr<File> KTXCache::createFile(Metadata&& metadata, const std::strin
|
|||
KTXFile::KTXFile(Metadata&& metadata, const std::string& filepath) :
|
||||
cache::File(std::move(metadata), filepath) {}
|
||||
|
||||
std::unique_ptr<ktx::KTX> KTXFile::getKTX() const {
|
||||
ktx::StoragePointer storage = std::make_shared<storage::FileStorage>(getFilepath().c_str());
|
||||
if (*storage) {
|
||||
return ktx::KTX::create(storage);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -39,9 +39,6 @@ protected:
|
|||
class KTXFile : public cache::File {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
std::unique_ptr<ktx::KTX> getKTX() const;
|
||||
|
||||
protected:
|
||||
friend class KTXCache;
|
||||
|
||||
|
|
|
@ -438,15 +438,9 @@ void NetworkTexture::loadContent(const QByteArray& content) {
|
|||
if (!texture) {
|
||||
KTXFilePointer ktxFile = textureCache->_ktxCache.getFile(hash);
|
||||
if (ktxFile) {
|
||||
// Ensure that the KTX deserialization worked
|
||||
auto ktx = ktxFile->getKTX();
|
||||
if (ktx) {
|
||||
texture.reset(gpu::Texture::unserialize(ktx));
|
||||
// Ensure that the texture population worked
|
||||
if (texture) {
|
||||
texture->setKtxBacking(ktxFile->getFilepath());
|
||||
texture = textureCache->cacheTextureByHash(hash, texture);
|
||||
}
|
||||
texture.reset(gpu::Texture::unserialize(ktxFile->getFilepath()));
|
||||
if (texture) {
|
||||
texture = textureCache->cacheTextureByHash(hash, texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue