diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp index 1d1f92b297..008b658205 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp @@ -259,7 +259,9 @@ void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) { glActiveTexture(GL_TEXTURE0 + slot); glBindTexture(target, to); - (void) CHECK_GL_ERROR(); + if (CHECK_GL_ERROR()) { + qDebug() << "slot: " << slot << ", target: " << target << ", to: " << to; + } _resource._textures[slot] = resourceTexture; diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index ebde9d4d27..6a1e5ca699 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -411,6 +411,7 @@ const Element& Texture::getStoredMipFormat() const { } void Texture::assignStoredMip(uint16 level, Size size, const Byte* bytes) { + // TODO Skip the extra allocation here storage::StoragePointer storage = std::make_shared(size, bytes); assignStoredMip(level, storage); } diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 487d32f91d..1e6fe1115e 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -45,6 +45,7 @@ std::string GPUKTXPayload::KEY { "hifi.gpu" }; KtxStorage::KtxStorage(const std::string& filename) : _filename(filename) { { + // We are doing a lot of work here just to get descriptor data ktx::StoragePointer storage { new storage::FileStorage(_filename.c_str()) }; auto ktxPointer = ktx::KTX::create(storage); _ktxDescriptor.reset(new ktx::KTXDescriptor(ktxPointer->toDescriptor())); @@ -74,8 +75,9 @@ Size KtxStorage::getMipFaceSize(uint16 level, uint8 face) const { bool KtxStorage::isMipAvailable(uint16 level, uint8 face) const { + return true; auto numLevels = _ktxDescriptor->header.numberOfMipmapLevels; - auto minLevel = 7 > numLevels ? 0 : numLevels - 7; + auto minLevel = 7 > numLevels ? 0 : numLevels - 10; auto avail = level >= minLevel; qDebug() << "isMipAvailable: " << level << " " << face << avail << minLevel << " " << _ktxDescriptor->header.numberOfMipmapLevels; //return true; diff --git a/libraries/ktx/src/ktx/KTX.cpp b/libraries/ktx/src/ktx/KTX.cpp index 0580d9a8c3..1f22514226 100644 --- a/libraries/ktx/src/ktx/KTX.cpp +++ b/libraries/ktx/src/ktx/KTX.cpp @@ -211,6 +211,7 @@ Image ImageDescriptor::toImage(const ktx::StoragePointer& storage) const { FaceBytes faces; faces.resize(_faceOffsets.size()); for (size_t face = 0; face < _numFaces; ++face) { + // TODO Should we be storing pointers to unowned data? faces[face] = storage->data() + _faceOffsets[face]; } // Note, implicit cast of *this to const ImageHeader& diff --git a/libraries/ktx/src/ktx/KTX.h b/libraries/ktx/src/ktx/KTX.h index fb8927eca0..988c921ce9 100644 --- a/libraries/ktx/src/ktx/KTX.h +++ b/libraries/ktx/src/ktx/KTX.h @@ -384,7 +384,7 @@ namespace ktx { ImageDescriptors generateImageDescriptors() const; }; static const size_t KTX_HEADER_SIZE = 64; - static_assert(sizeof(Header) == KTX_HEADER_SIZE, "KTX Header size is static"); + static_assert(sizeof(Header) == KTX_HEADER_SIZE, "KTX Header size is static and should not change from the spec"); // Key Values struct KeyValue { @@ -497,6 +497,8 @@ namespace ktx { static size_t writeKeyValues(Byte* destBytes, size_t destByteSize, const KeyValues& keyValues); static Images writeImages(Byte* destBytes, size_t destByteSize, const Images& images); + void writeMipData(uint16_t level, const Byte* sourceBytes, size_t source_size); + // Parse a block of memory and create a KTX object from it static std::unique_ptr create(const StoragePointer& src); diff --git a/libraries/ktx/src/ktx/Writer.cpp b/libraries/ktx/src/ktx/Writer.cpp index e2803a2258..0d6cd737b6 100644 --- a/libraries/ktx/src/ktx/Writer.cpp +++ b/libraries/ktx/src/ktx/Writer.cpp @@ -235,4 +235,11 @@ namespace ktx { return destImages; } + void KTX::writeMipData(uint16_t level, const Byte* sourceBytes, size_t sourceSize) { + Q_ASSERT(level > 0); + Q_ASSERT(level < _images.size()); + Q_ASSERT(sourceSize == _images[level]._imageSize); + + //memcpy(reinterpret_cast(_images[level]._faceBytes[0]), sourceBytes, sourceSize); + } } diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index f4fe192a4a..706c62c8a1 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -545,7 +545,6 @@ void NetworkTexture::loadContent(const QByteArray& content) { texture = textureCache->cacheTextureByHash(filename, texture); } - setImage(texture, header->getPixelWidth(), header->getPixelHeight()); auto desc = memKtx->toDescriptor(); @@ -559,10 +558,24 @@ void NetworkTexture::loadContent(const QByteArray& content) { } _requestByteRange.fromInclusive = length - sizeOfTopMips; _requestByteRange.toExclusive = length; - attemptRequest(); + QMetaObject::invokeMethod(this, "attemptRequest", Qt::QueuedConnection); + + + //texture->setMinMip(desc.images.size() - 1); + setImage(texture, header->getPixelWidth(), header->getPixelHeight()); } else { qDebug() << "Got highest 6 mips"; + + ktx::StoragePointer storage { new storage::FileStorage(QString::fromStdString(_file->getFilepath())) }; + auto data = storage->mutableData(); + auto size = storage->getSize(); + //*data = 'H'; + memcpy(data + _requestByteRange.fromInclusive, content.data(), content.size()); + //getGPUTexture()->setMinMip(getGPUTexture()->getMinMip() - 6); + //auto ktxPointer = ktx::KTX::create(storage); + + //ktxPointer->writeMipData(level, data, size); } return; } diff --git a/libraries/networking/src/HTTPResourceRequest.cpp b/libraries/networking/src/HTTPResourceRequest.cpp index 1bb292a3ef..499708b12d 100644 --- a/libraries/networking/src/HTTPResourceRequest.cpp +++ b/libraries/networking/src/HTTPResourceRequest.cpp @@ -22,6 +22,7 @@ #include "NetworkLogging.h" HTTPResourceRequest::~HTTPResourceRequest() { + qDebug() << "Cleaning up:" << _url << " " << _byteRange.fromInclusive << "-" << _byteRange.toExclusive; if (_reply) { _reply->disconnect(this); _reply->deleteLater(); @@ -76,9 +77,12 @@ void HTTPResourceRequest::doSend() { connect(_reply, &QNetworkReply::downloadProgress, this, &HTTPResourceRequest::onDownloadProgress); setupTimer(); + qDebug() << "Sent: " << _url; } void HTTPResourceRequest::onRequestFinished() { + qDebug() << "On request finished: " << _url; + Q_ASSERT(_state == InProgress); Q_ASSERT(_reply); @@ -181,6 +185,7 @@ void HTTPResourceRequest::onRequestFinished() { } void HTTPResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { + qDebug() << "Progress: " << _url; Q_ASSERT(_state == InProgress); // We've received data, so reset the timer @@ -190,6 +195,7 @@ void HTTPResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesT } void HTTPResourceRequest::onTimeout() { + qDebug() << "Timeout: " << _url << ":" << _reply->isFinished(); Q_ASSERT(_state == InProgress); _reply->disconnect(this); _reply->abort(); diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index 62ea85bc86..038ee7fb53 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -698,6 +698,7 @@ void Resource::handleDownloadProgress(uint64_t bytesReceived, uint64_t bytesTota } void Resource::handleReplyFinished() { + qDebug() << "Got response for " << _activeUrl; Q_ASSERT_X(_request, "Resource::handleReplyFinished", "Request should not be null while in handleReplyFinished"); PROFILE_ASYNC_END(resource, "Resource:" + getType(), QString::number(_requestID), { diff --git a/libraries/shared/src/shared/Storage.cpp b/libraries/shared/src/shared/Storage.cpp index 8999caf1e8..0f2b696a66 100644 --- a/libraries/shared/src/shared/Storage.cpp +++ b/libraries/shared/src/shared/Storage.cpp @@ -69,7 +69,8 @@ StoragePointer FileStorage::create(const QString& filename, size_t size, const u // Represents a memory mapped file FileStorage::FileStorage(const QString& filename) : _file(filename) { - if (_file.open(QFile::ReadOnly)) { + if (_file.open(QFile::ReadWrite)) { + qDebug() << ">>> Opening mmapped file: " << filename; _mapped = _file.map(0, _file.size()); if (_mapped) { _valid = true; @@ -82,6 +83,7 @@ FileStorage::FileStorage(const QString& filename) : _file(filename) { } FileStorage::~FileStorage() { + qDebug() << ">>> Closing mmapped file: " << _file.fileName(); if (_mapped) { if (!_file.unmap(_mapped)) { throw std::runtime_error("Unable to unmap file"); diff --git a/libraries/shared/src/shared/Storage.h b/libraries/shared/src/shared/Storage.h index 46f45cfdc5..3983387c15 100644 --- a/libraries/shared/src/shared/Storage.h +++ b/libraries/shared/src/shared/Storage.h @@ -25,6 +25,7 @@ namespace storage { public: virtual ~Storage() {} virtual const uint8_t* data() const = 0; + virtual uint8_t* mutableData() = 0; virtual size_t size() const = 0; virtual operator bool() const { return true; } @@ -42,6 +43,7 @@ namespace storage { MemoryStorage(size_t size, const uint8_t* data = nullptr); const uint8_t* data() const override { return _data.data(); } uint8_t* data() { return _data.data(); } + uint8_t* mutableData() override { return 0; } size_t size() const override { return _data.size(); } operator bool() const override { return true; } private: @@ -58,6 +60,7 @@ namespace storage { FileStorage& operator=(const FileStorage& other) = delete; const uint8_t* data() const override { return _mapped; } + uint8_t* mutableData() override { return _mapped; } size_t size() const override { return _file.size(); } operator bool() const override { return _valid; } private: @@ -70,6 +73,7 @@ namespace storage { public: ViewStorage(const storage::StoragePointer& owner, size_t size, const uint8_t* data); const uint8_t* data() const override { return _data; } + uint8_t* mutableData() override { return 0; } size_t size() const override { return _size; } operator bool() const override { return *_owner; } private: