Trying a different tactic to avoid multiple concurrent file access

This commit is contained in:
Bradley Austin Davis 2017-03-27 16:17:09 -07:00
parent f764cd614b
commit 638364497d
10 changed files with 49 additions and 85 deletions

View file

@ -222,7 +222,6 @@ GL45StrictResourceTexture::GL45StrictResourceTexture(const std::weak_ptr<GLBacke
copyMipFaceFromTexture(sourceMip, targetMip, face);
}
}
_gpuObject.finishTransfer();
if (texture.isAutogenerateMips()) {
generateMips();
}

View file

@ -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) {

View file

@ -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();
}
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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) { }

View file

@ -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 {

View file

@ -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 {};
}

View file

@ -39,9 +39,6 @@ protected:
class KTXFile : public cache::File {
Q_OBJECT
public:
std::unique_ptr<ktx::KTX> getKTX() const;
protected:
friend class KTXCache;

View file

@ -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);
}
}
}