diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 1bfe4f3dcc..dca5ac4b77 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -362,7 +362,8 @@ void OpenGLDisplayPlugin::customizeContext() { cursorData.texture->setSource("cursor texture"); auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); cursorData.texture->setUsage(usage.build()); - cursorData.texture->assignStoredMip(0, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.byteCount(), image.constBits()); + cursorData.texture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + cursorData.texture->assignStoredMip(0, image.byteCount(), image.constBits()); cursorData.texture->autoGenerateMips(-1); } } diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 24f4e429ef..c55d985a62 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -302,7 +302,8 @@ void HmdDisplayPlugin::internalPresent() { gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); _previewTexture->setSource("HMD Preview Texture"); _previewTexture->setUsage(gpu::Texture::Usage::Builder().withColor().build()); - _previewTexture->assignStoredMip(0, gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.byteCount(), image.constBits()); + _previewTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); + _previewTexture->assignStoredMip(0, image.byteCount(), image.constBits()); _previewTexture->autoGenerateMips(-1); } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index efbc6903b1..80649c4d64 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -71,7 +71,7 @@ GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& : GLTexture(backend, texture, allocate()), _storageStamp { texture.getStamp() }, _size(texture.evalTotalSize()) { incrementTextureGPUCount(); withPreservedTexture([&] { - GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat()); const Sampler& sampler = _gpuObject.getSampler(); auto numMips = _gpuObject.evalNumMips(); for (uint16_t mipLevel = 0; mipLevel < numMips; ++mipLevel) { @@ -83,7 +83,6 @@ GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) { auto mip = _gpuObject.accessStoredMipFace(mipLevel, face); mipData = mip->readData(); - texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mip->getFormat()); } glTexImage2D(target, mipLevel, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, texelFormat.type, mipData); (void)CHECK_GL_ERROR(); diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index 6dd1d6aea3..95837c16d9 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -142,7 +142,7 @@ void GL45Texture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, } auto size = _gpuObject.evalMipDimensions(sourceMip); auto mipData = _gpuObject.accessStoredMipFace(sourceMip, face); - GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), mipData->getFormat()); + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat()); copyMipFaceLinesFromTexture(targetMip, face, size, 0, texelFormat.format, texelFormat.type, mipData->readData()); } diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp index 8c93ed6a65..0e2053ad06 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp @@ -84,7 +84,7 @@ TransferJob::TransferJob(const GL45VariableAllocationTexture& parent, uint16_t s GLenum format; GLenum type; auto mipData = _parent._gpuObject.accessStoredMipFace(sourceMip, face); - GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), mipData->getFormat()); + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), _parent._gpuObject.getStoredMipFormat()); format = texelFormat.format; type = texelFormat.type; diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 281d768182..6afab476de 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -120,18 +120,6 @@ void Texture::setAllowedGPUMemoryUsage(Size size) { uint8 Texture::NUM_FACES_PER_TYPE[NUM_TYPES] = { 1, 1, 1, 6 }; -Texture::Pixels::Pixels(const Element& format, Size size, const Byte* bytes) : - _format(format), - _storage(new storage::MemoryStorage(size, bytes)) { - Texture::updateTextureCPUMemoryUsage(0, _storage->size()); -} - -Texture::Pixels::~Pixels() { - if (_storage) { - Texture::updateTextureCPUMemoryUsage(_storage->size(), 0); - } -} - void Texture::Storage::assignTexture(Texture* texture) { _texture = texture; if (_texture) { @@ -139,21 +127,12 @@ void Texture::Storage::assignTexture(Texture* texture) { } } -void Texture::Storage::reset() { +void Texture::MemoryStorage::reset() { _mips.clear(); bumpStamp(); } -Texture::PixelsPointer Texture::Storage::editMipFace(uint16 level, uint8 face) { - if (level < _mips.size()) { - assert(face < _mips[level].size()); - bumpStamp(); - return _mips[level][face]; - } - return PixelsPointer(); -} - -const Texture::PixelsPointer Texture::Storage::getMipFace(uint16 level, uint8 face) const { +const Texture::PixelsPointer Texture::MemoryStorage::getMipFace(uint16 level, uint8 face) const { if (level < _mips.size()) { assert(face < _mips[level].size()); return _mips[level][face]; @@ -161,12 +140,12 @@ const Texture::PixelsPointer Texture::Storage::getMipFace(uint16 level, uint8 fa return PixelsPointer(); } -bool Texture::Storage::isMipAvailable(uint16 level, uint8 face) const { +bool Texture::MemoryStorage::isMipAvailable(uint16 level, uint8 face) const { PixelsPointer mipFace = getMipFace(level, face); return (mipFace && mipFace->getSize()); } -bool Texture::Storage::allocateMip(uint16 level) { +bool Texture::MemoryStorage::allocateMip(uint16 level) { bool changed = false; if (level >= _mips.size()) { _mips.resize(level+1, std::vector(Texture::NUM_FACES_PER_TYPE[getType()])); @@ -176,7 +155,6 @@ bool Texture::Storage::allocateMip(uint16 level) { auto& mip = _mips[level]; for (auto& face : mip) { if (!face) { - face = std::make_shared(); changed = true; } } @@ -186,7 +164,7 @@ bool Texture::Storage::allocateMip(uint16 level) { return changed; } -bool Texture::Storage::assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes) { +void Texture::MemoryStorage::assignMipData(uint16 level, const storage::StoragePointer& storagePointer) { allocateMip(level); auto& mip = _mips[level]; @@ -195,33 +173,24 @@ bool Texture::Storage::assignMipData(uint16 level, const Element& format, Size s // The bytes assigned here are supposed to contain all the faces bytes of the mip. // For tex1D, 2D, 3D there is only one face // For Cube, we expect the 6 faces in the order X+, X-, Y+, Y-, Z+, Z- - auto sizePerFace = size / mip.size(); - auto faceBytes = bytes; - Size allocated = 0; + auto sizePerFace = storagePointer->size() / mip.size(); + size_t offset = 0; for (auto& face : mip) { - face.reset(new Pixels(format, size, bytes)); - allocated += size; - faceBytes += sizePerFace; + face = storagePointer->createView(sizePerFace, offset); + offset += sizePerFace; } bumpStamp(); - - return allocated == size; } -bool Texture::Storage::assignMipFaceData(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face) { - +void Texture::MemoryStorage::assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storagePointer) { allocateMip(level); auto& mip = _mips[level]; - Size allocated = 0; if (face < mip.size()) { - mip[face].reset(new Pixels(format, size, bytes)); - allocated += size; + mip[face] = storagePointer; bumpStamp(); } - - return allocated == size; } Texture* Texture::createExternal(const ExternalRecycler& recycler, const Sampler& sampler) { @@ -260,7 +229,7 @@ Texture* Texture::createCube(const Element& texelFormat, uint16 width, const Sam Texture* Texture::create(TextureUsageType usageType, Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler) { Texture* tex = new Texture(usageType); - tex->_storage.reset(new Storage()); + tex->_storage.reset(new MemoryStorage()); tex->_type = type; tex->_storage->assignTexture(tex); tex->_maxMip = 0; @@ -402,69 +371,83 @@ uint16 Texture::evalNumMips() const { return evalNumMips({ _width, _height, _depth }); } -bool Texture::assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes) { +void Texture::setStoredMipFormat(const Element& format) { + _storage->setFormat(format); +} + +const Element& Texture::getStoredMipFormat() const { + return _storage->getFormat(); +} + +void Texture::assignStoredMip(uint16 level, Size size, const Byte* bytes) { + storage::StoragePointer storage { new storage::MemoryStorage(size, bytes) }; + assignStoredMip(level, storage); +} + +void Texture::assignStoredMipFace(uint16 level, uint8 face, Size size, const Byte* bytes) { + storage::StoragePointer storage { new storage::MemoryStorage(size, bytes) }; + assignStoredMipFace(level, face, storage); +} + +void Texture::assignStoredMip(uint16 level, storage::StoragePointer& storage) { // Check that level accessed make sense if (level != 0) { if (_autoGenerateMips) { - return false; + return; } if (level >= evalNumMips()) { - return false; + return; } } // THen check that the mem texture passed make sense with its format - Size expectedSize = evalStoredMipSize(level, format); - if (size == expectedSize) { - _storage->assignMipData(level, format, size, bytes); + Size expectedSize = evalStoredMipSize(level, getStoredMipFormat()); + auto size = storage->size(); + auto bytes = storage->data(); + if (storage->size() == expectedSize) { + _storage->assignMipData(level, storage); _maxMip = std::max(_maxMip, level); _stamp++; - return true; } else if (size > expectedSize) { // NOTE: We are facing this case sometime because apparently QImage (from where we get the bits) is generating images // and alligning the line of pixels to 32 bits. // We should probably consider something a bit more smart to get the correct result but for now (UI elements) // it seems to work... - _storage->assignMipData(level, format, size, bytes); + _storage->assignMipData(level, storage); _maxMip = std::max(_maxMip, level); _stamp++; - return true; } - - return false; } - -bool Texture::assignStoredMipFace(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face) { +void Texture::assignStoredMipFace(uint16 level, uint8 face, storage::StoragePointer& storage) { // Check that level accessed make sense if (level != 0) { if (_autoGenerateMips) { - return false; + return; } if (level >= evalNumMips()) { - return false; + return; } } // THen check that the mem texture passed make sense with its format - Size expectedSize = evalStoredMipFaceSize(level, format); + Size expectedSize = evalStoredMipFaceSize(level, getStoredMipFormat()); + auto size = storage->size(); + auto bytes = storage->data(); if (size == expectedSize) { - _storage->assignMipFaceData(level, format, size, bytes, face); + _storage->assignMipFaceData(level, face, storage); _stamp++; - return true; } else if (size > expectedSize) { // NOTE: We are facing this case sometime because apparently QImage (from where we get the bits) is generating images // and alligning the line of pixels to 32 bits. // We should probably consider something a bit more smart to get the correct result but for now (UI elements) // it seems to work... - _storage->assignMipFaceData(level, format, size, bytes, face); + _storage->assignMipFaceData(level, face, storage); _stamp++; - return true; } - - return false; } + uint16 Texture::autoGenerateMips(uint16 maxMip) { bool changed = false; if (!_autoGenerateMips) { @@ -498,7 +481,7 @@ uint16 Texture::getStoredMipHeight(uint16 level) const { if (mip && mip->getSize()) { return evalMipHeight(level); } - return 0; + return 0; } uint16 Texture::getStoredMipDepth(uint16 level) const { @@ -770,8 +753,8 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector< for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) { PROFILE_RANGE(render_gpu, "ProcessFace"); - auto numComponents = cubeTexture.accessStoredMipFace(0,face)->getFormat().getScalarCount(); - auto data = cubeTexture.accessStoredMipFace(0,face)->readData(); + auto numComponents = cubeTexture.getStoredMipFormat().getScalarCount(); + auto data = cubeTexture.accessStoredMipFace(0,face)->data(); if (data == nullptr) { continue; } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 0a5afe78c3..84241442c5 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -226,30 +226,7 @@ public: bool operator!=(const Usage& usage) { return (_flags != usage._flags); } }; - - class Pixels { - public: - using StoragePointer = storage::StoragePointer; - - Pixels() {} - Pixels(const Pixels& pixels) = default; - Pixels(const Element& format, Size size, const Byte* bytes); - Pixels(const Element& format, StoragePointer& storage) : _format(format), _storage(storage.release()) {} - ~Pixels(); - - const Byte* readData() const { return _storage->data(); } - Size getSize() const { return _storage->size(); } - - const Element& getFormat() const { return _format; } - - - protected: - Element _format; - StoragePointer _storage; - - friend class Texture; - }; - typedef std::shared_ptr< Pixels > PixelsPointer; + using PixelsPointer = storage::StoragePointer; enum Type { TEX_1D = 0, @@ -272,35 +249,68 @@ public: NUM_CUBE_FACES, // Not a valid vace index }; + class Storage { public: Storage() {} virtual ~Storage() {} - virtual void reset(); - virtual PixelsPointer editMipFace(uint16 level, uint8 face = 0); - virtual const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const; - virtual bool allocateMip(uint16 level); - virtual bool assignMipData(uint16 level, const Element& format, Size size, const Byte* bytes); - virtual bool assignMipFaceData(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face); - virtual bool isMipAvailable(uint16 level, uint8 face = 0) const; + virtual void reset() = 0; + virtual const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const = 0; + 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; Texture::Type getType() const { return _type; } - + Stamp getStamp() const { return _stamp; } Stamp bumpStamp() { return ++_stamp; } - protected: - Stamp _stamp = 0; - Texture* _texture = nullptr; // Points to the parent texture (not owned) - Texture::Type _type = Texture::TEX_2D; // The type of texture is needed to know the number of faces to expect - std::vector> _mips; // an array of mips, each mip is an array of faces + void setFormat(const Element& format) { _format = format; } + const Element& getFormat() const { return _format; } + + private: + Stamp _stamp { 0 }; + Element _format; + Texture::Type _type { Texture::TEX_2D }; // The type of texture is needed to know the number of faces to expect + Texture* _texture { nullptr }; // Points to the parent texture (not owned) virtual void assignTexture(Texture* tex); // Texture storage is pointing to ONE corrresponding Texture. const Texture* getTexture() const { return _texture; } - friend class Texture; }; - + class MemoryStorage : public Storage { + public: + void reset() override; + const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override; + void assignMipData(uint16 level, const storage::StoragePointer& storage) override; + void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) override; + bool isMipAvailable(uint16 level, uint8 face = 0) const override; + + protected: + bool allocateMip(uint16 level); + std::vector> _mips; // an array of mips, each mip is an array of faces + }; + + class KtxStorage : public Storage { + public: + KtxStorage(ktx::KTXUniquePointer& ktxData); + const PixelsPointer getMipFace(uint16 level, uint8 face = 0) const override; + bool isMipAvailable(uint16 level, uint8 face = 0) const override; + + void assignMipData(uint16 level, const storage::StoragePointer& storage) override { + throw std::runtime_error("Invalid call"); + } + + void assignMipFaceData(uint16 level, uint8 face, const storage::StoragePointer& storage) override { + throw std::runtime_error("Invalid call"); + } + void reset() override { } + + protected: + ktx::KTXUniquePointer _ktxData; + friend class Texture; + }; + static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler()); static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler()); static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, const Sampler& sampler = Sampler()); @@ -444,13 +454,21 @@ public: // Managing Storage and mips + // Mip storage format is constant across all mips + void setStoredMipFormat(const Element& format); + const Element& getStoredMipFormat() const; + // Manually allocate the mips down until the specified maxMip // this is just allocating the sysmem version of it // in case autoGen is on, this doesn't allocate // Explicitely assign mip data for a certain level // If Bytes is NULL then simply allocate the space so mip sysmem can be accessed - bool assignStoredMip(uint16 level, const Element& format, Size size, const Byte* bytes); - bool assignStoredMipFace(uint16 level, const Element& format, Size size, const Byte* bytes, uint8 face); + + void assignStoredMip(uint16 level, Size size, const Byte* bytes); + void assignStoredMipFace(uint16 level, uint8 face, Size size, const Byte* bytes); + + void assignStoredMip(uint16 level, storage::StoragePointer& storage); + void assignStoredMipFace(uint16 level, uint8 face, storage::StoragePointer& storage); // Access the the sub mips bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0) const { return _storage->isMipAvailable(level, face); } diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 404aca77a4..13d4c2a464 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -116,9 +116,10 @@ Texture* Texture::unserialize(TextureUsageType usageType, const ktx::KTXUniquePo Sampler()); // Assing the mips availables + tex->setStoredMipFormat(mipFormat); uint16_t level = 0; for (auto& image : srcData->_images) { - tex->assignStoredMip(level, mipFormat, image._imageSize, image._bytes); + tex->assignStoredMip(level, image._imageSize, image._bytes); level++; } diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index 6a84fc960f..1f21e9e78d 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -108,7 +108,8 @@ const gpu::TexturePointer& TextureCache::getPermutationNormalTexture() { } _permutationNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), 256, 2)); - _permutationNormalTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(data), data); + _permutationNormalTexture->setStoredMipFormat(_permutationNormalTexture->getTexelFormat()); + _permutationNormalTexture->assignStoredMip(0, sizeof(data), data); } return _permutationNormalTexture; } @@ -122,7 +123,8 @@ const gpu::TexturePointer& TextureCache::getWhiteTexture() { if (!_whiteTexture) { _whiteTexture = gpu::TexturePointer(gpu::Texture::createStrict(gpu::Element::COLOR_RGBA_32, 1, 1)); _whiteTexture->setSource("TextureCache::_whiteTexture"); - _whiteTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_WHITE); + _whiteTexture->setStoredMipFormat(_whiteTexture->getTexelFormat()); + _whiteTexture->assignStoredMip(0, sizeof(OPAQUE_WHITE), OPAQUE_WHITE); } return _whiteTexture; } @@ -131,7 +133,8 @@ const gpu::TexturePointer& TextureCache::getGrayTexture() { if (!_grayTexture) { _grayTexture = gpu::TexturePointer(gpu::Texture::createStrict(gpu::Element::COLOR_RGBA_32, 1, 1)); _grayTexture->setSource("TextureCache::_grayTexture"); - _grayTexture->assignStoredMip(0, _grayTexture->getTexelFormat(), sizeof(OPAQUE_GRAY), OPAQUE_GRAY); + _grayTexture->setStoredMipFormat(_grayTexture->getTexelFormat()); + _grayTexture->assignStoredMip(0, sizeof(OPAQUE_GRAY), OPAQUE_GRAY); } return _grayTexture; } @@ -140,7 +143,8 @@ const gpu::TexturePointer& TextureCache::getBlueTexture() { if (!_blueTexture) { _blueTexture = gpu::TexturePointer(gpu::Texture::createStrict(gpu::Element::COLOR_RGBA_32, 1, 1)); _blueTexture->setSource("TextureCache::_blueTexture"); - _blueTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(OPAQUE_BLUE), OPAQUE_BLUE); + _blueTexture->setStoredMipFormat(_blueTexture->getTexelFormat()); + _blueTexture->assignStoredMip(0, sizeof(OPAQUE_BLUE), OPAQUE_BLUE); } return _blueTexture; } @@ -149,7 +153,8 @@ const gpu::TexturePointer& TextureCache::getBlackTexture() { if (!_blackTexture) { _blackTexture = gpu::TexturePointer(gpu::Texture::createStrict(gpu::Element::COLOR_RGBA_32, 1, 1)); _blackTexture->setSource("TextureCache::_blackTexture"); - _blackTexture->assignStoredMip(0, _blackTexture->getTexelFormat(), sizeof(OPAQUE_BLACK), OPAQUE_BLACK); + _blackTexture->setStoredMipFormat(_blackTexture->getTexelFormat()); + _blackTexture->assignStoredMip(0, sizeof(OPAQUE_BLACK), OPAQUE_BLACK); } return _blackTexture; } diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 3f10f66256..0a1eb705eb 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -96,7 +96,7 @@ gpu::Texture* cacheTexture(const std::string& name, gpu::Texture* srcTexture, bo // Prepare cache directory QString path("hifi_ktx/"); QFileInfo originalFileInfo(path); - QString docsLocation = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); + QString docsLocation = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); path = docsLocation + "/" + path; QFileInfo info(path); if (!info.absoluteDir().exists()) { @@ -262,7 +262,7 @@ const QImage& image, bool isLinear, bool doCompress) { #define CPU_MIPMAPS 1 -void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip, bool fastResize) { +void generateMips(gpu::Texture* texture, QImage& image, bool fastResize) { #if CPU_MIPMAPS PROFILE_RANGE(resource_parse, "generateMips"); auto numMips = texture->evalNumMips(); @@ -270,10 +270,10 @@ void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip, QSize mipSize(texture->evalMipWidth(level), texture->evalMipHeight(level)); if (fastResize) { image = image.scaled(mipSize); - texture->assignStoredMip(level, formatMip, image.byteCount(), image.constBits()); + texture->assignStoredMip(level, image.byteCount(), image.constBits()); } else { QImage mipImage = image.scaled(mipSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - texture->assignStoredMip(level, formatMip, mipImage.byteCount(), mipImage.constBits()); + texture->assignStoredMip(level, mipImage.byteCount(), mipImage.constBits()); } } #else @@ -281,14 +281,14 @@ void generateMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip, #endif } -void generateFaceMips(gpu::Texture* texture, QImage& image, gpu::Element formatMip, uint8 face) { +void generateFaceMips(gpu::Texture* texture, QImage& image, uint8 face) { #if CPU_MIPMAPS PROFILE_RANGE(resource_parse, "generateFaceMips"); auto numMips = texture->evalNumMips(); for (uint16 level = 1; level < numMips; ++level) { QSize mipSize(texture->evalMipWidth(level), texture->evalMipHeight(level)); QImage mipImage = image.scaled(mipSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - texture->assignStoredMipFace(level, formatMip, mipImage.byteCount(), mipImage.constBits(), face); + texture->assignStoredMipFace(level, face, mipImage.byteCount(), mipImage.constBits()); } #else texture->autoGenerateMips(-1); @@ -322,11 +322,11 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag } } theTexture->setUsage(usage.build()); - - theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); + theTexture->setStoredMipFormat(formatMip); + theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); if (generateMips) { - ::generateMips(theTexture, image, formatMip, false); + ::generateMips(theTexture, image, false); } theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture); @@ -373,8 +373,9 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); - theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); - generateMips(theTexture, image, formatMip, true); + theTexture->setStoredMipFormat(formatMip); + theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + generateMips(theTexture, image, true); theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture); } @@ -461,8 +462,9 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); - theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); - generateMips(theTexture, image, formatMip, true); + theTexture->setStoredMipFormat(formatMip); + theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + generateMips(theTexture, image, true); theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture); } @@ -496,8 +498,9 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcIma theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); - theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); - generateMips(theTexture, image, formatMip, true); + theTexture->setStoredMipFormat(formatMip); + theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + generateMips(theTexture, image, true); theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture); } @@ -535,8 +538,9 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& s theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); - theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); - generateMips(theTexture, image, formatMip, true); + theTexture->setStoredMipFormat(formatMip); + theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + generateMips(theTexture, image, true); theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture); } @@ -571,8 +575,9 @@ gpu::Texture* TextureUsage::createMetallicTextureFromImage(const QImage& srcImag theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); - theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); - generateMips(theTexture, image, formatMip, true); + theTexture->setStoredMipFormat(formatMip); + theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); + generateMips(theTexture, image, true); theTexture = cacheTexture(std::to_string((size_t) theTexture), theTexture); } @@ -886,11 +891,12 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm if (faces.size() == gpu::Texture::NUM_FACES_PER_TYPE[gpu::Texture::TEX_CUBE]) { theTexture = gpu::Texture::createCube(formatGPU, faces[0].width(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); theTexture->setSource(srcImageName); + theTexture->setStoredMipFormat(formatMip); int f = 0; for (auto& face : faces) { - theTexture->assignStoredMipFace(0, formatMip, face.byteCount(), face.constBits(), f); + theTexture->assignStoredMipFace(0, f, face.byteCount(), face.constBits()); if (generateMips) { - generateFaceMips(theTexture, face, formatMip, f); + generateFaceMips(theTexture, face, f); } f++; } diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 4f4ee12622..c405f6d6ae 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -209,7 +209,8 @@ void Font::read(QIODevice& in) { } _texture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR))); - _texture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits()); + _texture->setStoredMipFormat(formatMip); + _texture->assignStoredMip(0, image.byteCount(), image.constBits()); } void Font::setupGPU() { diff --git a/libraries/shared/src/shared/Storage.cpp b/libraries/shared/src/shared/Storage.cpp index d3f1f3c5d3..dacb840de7 100644 --- a/libraries/shared/src/shared/Storage.cpp +++ b/libraries/shared/src/shared/Storage.cpp @@ -14,10 +14,13 @@ using namespace storage; ViewStoragePointer Storage::createView(size_t viewSize, size_t offset) const { auto selfSize = size(); - if ((viewSize + offset) > selfSize) { - throw std::runtime_error("Unable to map file"); + if (0 == viewSize) { + viewSize = selfSize; } - return ViewStoragePointer(new ViewStorage(viewSize, data() + offset)); + if ((viewSize + offset) > selfSize) { + throw std::runtime_error("Invalid mapping range"); + } + return ViewStoragePointer(new ViewStorage(shared_from_this(), viewSize, data() + offset)); } MemoryStoragePointer Storage::toMemoryStorage() const { diff --git a/libraries/shared/src/shared/Storage.h b/libraries/shared/src/shared/Storage.h index 8096b631ed..4dbb2a03a5 100644 --- a/libraries/shared/src/shared/Storage.h +++ b/libraries/shared/src/shared/Storage.h @@ -18,22 +18,27 @@ namespace storage { class Storage; - using StoragePointer = std::unique_ptr; + using StoragePointer = std::shared_ptr; class MemoryStorage; - using MemoryStoragePointer = std::unique_ptr; + using MemoryStoragePointer = std::shared_ptr; class FileStorage; - using FileStoragePointer = std::unique_ptr; + using FileStoragePointer = std::shared_ptr; class ViewStorage; - using ViewStoragePointer = std::unique_ptr; + using ViewStoragePointer = std::shared_ptr; - class Storage { + class Storage : public std::enable_shared_from_this { public: virtual ~Storage() {} virtual const uint8_t* data() const = 0; virtual size_t size() const = 0; - ViewStoragePointer createView(size_t size, size_t offset = 0) const; + + ViewStoragePointer createView(size_t size = 0, size_t offset = 0) const; FileStoragePointer toFileStorage(const QString& filename) const; MemoryStoragePointer toMemoryStorage() const; + + // Aliases to prevent having to re-write a ton of code + inline size_t getSize() const { return size(); } + inline const uint8_t* readData() const { return data(); } }; class MemoryStorage : public Storage { @@ -63,10 +68,11 @@ namespace storage { class ViewStorage : public Storage { public: - ViewStorage(size_t size, const uint8_t* data) : _size(size), _data(data) {} + ViewStorage(const storage::StoragePointer& owner, size_t size, const uint8_t* data) : _owner(owner), _size(size), _data(data) {} const uint8_t* data() const override { return _data; } size_t size() const override { return _size; } private: + const storage::StoragePointer _owner; const size_t _size; const uint8_t* _data; }; diff --git a/tests/render-perf/CMakeLists.txt b/tests/render-perf/CMakeLists.txt index d4f90fdace..96cede9c43 100644 --- a/tests/render-perf/CMakeLists.txt +++ b/tests/render-perf/CMakeLists.txt @@ -10,7 +10,7 @@ setup_hifi_project(Quick Gui OpenGL) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/") # link in the shared libraries -link_hifi_libraries(shared octree gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics) +link_hifi_libraries(shared octree ktx gl gpu gpu-gl render model model-networking networking render-utils fbx entities entities-renderer animation audio avatars script-engine physics) package_libraries_for_deployment()