Merge pull request #10364 from huffman/fix/ktx-skybox-loading

Fix progressive loading of KTX skybox textures
This commit is contained in:
Clément Brisset 2017-05-05 14:11:03 -07:00 committed by GitHub
commit 479e810173
5 changed files with 47 additions and 9 deletions

View file

@ -174,7 +174,7 @@ namespace ktx {
}
std::unique_ptr<KTX> KTX::create(const StoragePointer& src) {
if (!src) {
if (!src || !(*src)) {
return nullptr;
}

View file

@ -421,7 +421,7 @@ void NetworkTexture::startRequestForNextMipLevel() {
_ktxResourceState = PENDING_MIP_REQUEST;
init();
init(false);
float priority = -(float)_originalKtxDescriptor->header.numberOfMipmapLevels + (float)_lowestKnownPopulatedMip;
setLoadPriority(this, priority);
_url.setFragment(QString::number(_lowestKnownPopulatedMip - 1));
@ -472,6 +472,10 @@ void NetworkTexture::startMipRangeRequest(uint16_t low, uint16_t high) {
void NetworkTexture::ktxHeaderRequestFinished() {
Q_ASSERT(_ktxResourceState == LOADING_INITIAL_DATA);
if (!_ktxHeaderRequest) {
return;
}
_ktxHeaderRequestFinished = true;
maybeHandleFinishedInitialLoad();
}
@ -479,6 +483,10 @@ void NetworkTexture::ktxHeaderRequestFinished() {
void NetworkTexture::ktxMipRequestFinished() {
Q_ASSERT(_ktxResourceState == LOADING_INITIAL_DATA || _ktxResourceState == REQUESTING_MIP);
if (!_ktxMipRequest) {
return;
}
if (_ktxResourceState == LOADING_INITIAL_DATA) {
_ktxHighMipRequestFinished = true;
maybeHandleFinishedInitialLoad();
@ -682,6 +690,27 @@ void NetworkTexture::loadContent(const QByteArray& content) {
QThreadPool::globalInstance()->start(new ImageReader(_self, _url, content, _maxNumPixels));
}
void NetworkTexture::refresh() {
if ((_ktxHeaderRequest || _ktxMipRequest) && !_loaded && !_failedToLoad) {
return;
}
if (_ktxHeaderRequest || _ktxMipRequest) {
if (_ktxHeaderRequest) {
_ktxHeaderRequest->disconnect(this);
_ktxHeaderRequest->deleteLater();
_ktxHeaderRequest = nullptr;
}
if (_ktxMipRequest) {
_ktxMipRequest->disconnect(this);
_ktxMipRequest->deleteLater();
_ktxMipRequest = nullptr;
}
TextureCache::requestCompleted(_self);
}
Resource::refresh();
}
ImageReader::ImageReader(const QWeakPointer<Resource>& resource, const QUrl& url, const QByteArray& data, int maxNumPixels) :
_resource(resource),
_url(url),

View file

@ -58,6 +58,8 @@ public:
gpu::TexturePointer getFallbackTexture() const;
void refresh() override;
signals:
void networkTextureCreated(const QWeakPointer<NetworkTexture>& self);

View file

@ -533,13 +533,13 @@ void Resource::ensureLoading() {
}
void Resource::setLoadPriority(const QPointer<QObject>& owner, float priority) {
if (!(_failedToLoad || _loaded)) {
if (!(_failedToLoad)) {
_loadPriorities.insert(owner, priority);
}
}
void Resource::setLoadPriorities(const QHash<QPointer<QObject>, float>& priorities) {
if (_failedToLoad || _loaded) {
if (_failedToLoad) {
return;
}
for (QHash<QPointer<QObject>, float>::const_iterator it = priorities.constBegin();
@ -549,7 +549,7 @@ void Resource::setLoadPriorities(const QHash<QPointer<QObject>, float>& prioriti
}
void Resource::clearLoadPriority(const QPointer<QObject>& owner) {
if (!(_failedToLoad || _loaded)) {
if (!(_failedToLoad)) {
_loadPriorities.remove(owner);
}
}
@ -612,10 +612,12 @@ void Resource::allReferencesCleared() {
}
}
void Resource::init() {
void Resource::init(bool resetLoaded) {
_startedLoading = false;
_failedToLoad = false;
_loaded = false;
if (resetLoaded) {
_loaded = false;
}
_attempts = 0;
_activeUrl = _url;

View file

@ -385,7 +385,7 @@ public:
float getProgress() const { return (_bytesTotal <= 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; }
/// Refreshes the resource.
void refresh();
virtual void refresh();
void setSelf(const QWeakPointer<Resource>& self) { _self = self; }
@ -425,7 +425,7 @@ protected slots:
void attemptRequest();
protected:
virtual void init();
virtual void init(bool resetLoaded = true);
/// Called by ResourceCache to begin loading this Resource.
/// This method can be overriden to provide custom request functionality. If this is done,
@ -454,9 +454,14 @@ protected:
QUrl _url;
QUrl _activeUrl;
ByteRange _requestByteRange;
// _loaded == true means we are in a loaded and usable state. It is possible that there may still be
// active requests/loading while in this state. Example: Progressive KTX downloads, where higher resolution
// mips are being download.
bool _startedLoading = false;
bool _failedToLoad = false;
bool _loaded = false;
QHash<QPointer<QObject>, float> _loadPriorities;
QWeakPointer<Resource> _self;
QPointer<ResourceCache> _cache;