Fix handling of failed ktx downloads

This commit is contained in:
Ryan Huffman 2017-04-19 13:16:53 -07:00 committed by Atlante45
parent 841d301dec
commit 472c888529
6 changed files with 46 additions and 15 deletions

View file

@ -114,7 +114,7 @@ protected:
//bool canPromoteNoAllocate() const { return _allocatedMip < _populatedMip; }
bool canPromote() const { return _allocatedMip > 0 || _populatedMip > 0; }
bool canDemote() const { return _allocatedMip < _maxAllocatedMip; }
bool hasPendingTransfers() const { return _populatedMip > _allocatedMip; }
bool hasPendingTransfers() const { return _pendingTransfers.size() > 0; }
void executeNextTransfer(const TexturePointer& currentTexture);
virtual bool canPopulate() const = 0;
virtual void populateTransferQueue() = 0;

View file

@ -92,13 +92,16 @@ size_t Header::evalPixelOrBlockSize() const {
}
}
qWarning() << "Unknown ktx format: " << glFormat << " " << glBaseInternalFormat << " " << glInternalFormat;
return 1;
return 0;
//throw std::runtime_error("Unknown format");
}
size_t Header::evalRowSize(uint32_t level) const {
auto pixWidth = evalPixelOrBlockWidth(level);
auto pixSize = evalPixelOrBlockSize();
if (pixSize == 0) {
return 0;
}
auto netSize = pixWidth * pixSize;
auto padding = evalPadding(netSize);
return netSize + padding;
@ -136,6 +139,9 @@ ImageDescriptors Header::generateImageDescriptors() const {
uint32_t imageOffset = 0;
for (uint32_t level = 0; level < numberOfMipmapLevels; ++level) {
auto imageSize = static_cast<uint32_t>(evalImageSize(level));
if (imageSize == 0) {
return ImageDescriptors();
}
ImageHeader header {
numberOfFaces == NUM_CUBEMAPFACES,
imageOffset,

View file

@ -298,6 +298,8 @@ namespace ktx {
struct ImageDescriptor;
using ImageDescriptors = std::vector<ImageDescriptor>;
bool checkIdentifier(const Byte* identifier);
// Header
struct Header {
static const size_t IDENTIFIER_LENGTH = 12;

View file

@ -399,14 +399,15 @@ void NetworkTexture::handleMipInterestLevel(int level) {
void NetworkTexture::startRequestForNextMipLevel() {
if (_lowestKnownPopulatedMip == 0) {
qWarning(networking) << "Requesting next mip level but all have been fulfilled: " << _url;
qWarning(networking) << "Requesting next mip level but all have been fulfilled: " << _lowestKnownPopulatedMip
<< " " << _textureSource->getGPUTexture()->minAvailableMipLevel() << " " << _url;
return;
}
if (_ktxResourceState == WAITING_FOR_MIP_REQUEST) {
_ktxResourceState = PENDING_MIP_REQUEST;
setLoadPriority(this, _lowestKnownPopulatedMip);
setLoadPriority(this, -_originalKtxDescriptor->header.numberOfMipmapLevels + _lowestKnownPopulatedMip);
init();
ResourceCache::attemptRequest(_self);
@ -449,8 +450,8 @@ void NetworkTexture::startMipRangeRequest(uint16_t low, uint16_t high) {
void NetworkTexture::ktxHeaderRequestFinished() {
Q_ASSERT(_ktxResourceState == LOADING_INITIAL_DATA);
_ktxHeaderRequestFinished = true;
maybeHandleFinishedInitialLoad();
_ktxHeaderRequestFinished = true;
maybeHandleFinishedInitialLoad();
}
void NetworkTexture::ktxMipRequestFinished() {
@ -459,7 +460,8 @@ void NetworkTexture::ktxMipRequestFinished() {
if (_ktxResourceState == LOADING_INITIAL_DATA) {
_ktxHighMipRequestFinished = true;
maybeHandleFinishedInitialLoad();
} else if (_ktxResourceState == REQUESTING_MIP) {
}
else if (_ktxResourceState == REQUESTING_MIP) {
Q_ASSERT(_ktxMipLevelRangeInFlight.first != NULL_MIP_LEVEL);
ResourceCache::requestCompleted(_self);
@ -472,15 +474,22 @@ void NetworkTexture::ktxMipRequestFinished() {
//qDebug() << "Writing mip for " << _url;
texture->assignStoredMip(_ktxMipLevelRangeInFlight.first,
_ktxMipRequest->getData().size(), reinterpret_cast<uint8_t*>(_ktxMipRequest->getData().data()));
} else {
}
else {
qWarning(networking) << "Trying to update mips but texture is null";
}
finishedLoading(true);
_ktxResourceState = WAITING_FOR_MIP_REQUEST;
} else {
_ktxResourceState = PENDING_MIP_REQUEST;
}
else {
finishedLoading(false);
handleFailedRequest(_ktxMipRequest->getResult());
if (handleFailedRequest(_ktxMipRequest->getResult())) {
_ktxResourceState = PENDING_MIP_REQUEST;
}
else {
qWarning() << "Failed to load mip: " << _url;
_ktxResourceState = FAILED_TO_LOAD;
}
}
_ktxMipRequest->deleteLater();
@ -489,7 +498,8 @@ void NetworkTexture::ktxMipRequestFinished() {
if (_ktxResourceState == WAITING_FOR_MIP_REQUEST && _lowestRequestedMipLevel < _lowestKnownPopulatedMip) {
startRequestForNextMipLevel();
}
} else {
}
else {
qWarning() << "Mip request finished in an unexpected state: " << _ktxResourceState;
}
}
@ -505,7 +515,8 @@ void NetworkTexture::maybeHandleFinishedInitialLoad() {
if (_ktxHeaderRequest->getResult() != ResourceRequest::Success || _ktxMipRequest->getResult() != ResourceRequest::Success) {
if (handleFailedRequest(_ktxMipRequest->getResult())) {
_ktxResourceState = PENDING_INITIAL_LOAD;
} else {
}
else {
_ktxResourceState = FAILED_TO_LOAD;
}
@ -533,6 +544,12 @@ void NetworkTexture::maybeHandleFinishedInitialLoad() {
qDebug() << "numberOfFaces:" << header->numberOfFaces;
qDebug() << "numberOfMipmapLevels:" << header->numberOfMipmapLevels;
if (!ktx::checkIdentifier(header->identifier)) {
qWarning() << "Cannot load " << _url << ", invalid header identifier";
_ktxResourceState = FAILED_TO_LOAD;
finishedLoading(false);
}
auto kvSize = header->bytesOfKeyValueData;
if (kvSize > ktxHeaderData.size() - ktx::KTX_HEADER_SIZE) {
qWarning() << "Cannot load " << _url << ", did not receive all kv data with initial request";
@ -544,6 +561,11 @@ void NetworkTexture::maybeHandleFinishedInitialLoad() {
auto keyValues = ktx::KTX::parseKeyValues(header->bytesOfKeyValueData, reinterpret_cast<const ktx::Byte*>(ktxHeaderData.data()) + ktx::KTX_HEADER_SIZE);
auto imageDescriptors = header->generateImageDescriptors();
if (imageDescriptors.size() == 0) {
qWarning(networking) << "Failed to process ktx file " << _url;
_ktxResourceState = FAILED_TO_LOAD;
finishedLoading(false);
}
_originalKtxDescriptor.reset(new ktx::KTXDescriptor(*header, keyValues, imageDescriptors));
// Create bare ktx in memory

View file

@ -544,7 +544,8 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
}
if (_fadeState == FADE_WAITING_TO_START) {
if (_model->isLoaded() && _model->getGeometry()->areTexturesLoaded()) {
//if (_model->isLoaded() && _model->getGeometry()->areTexturesLoaded()) {
if (_model->isLoaded()) {
if (EntityItem::getEntitiesShouldFadeFunction()()) {
_fadeStartTime = usecTimestampNow();
_fadeState = FADE_IN_PROGRESS;

View file

@ -3,7 +3,7 @@ AUTOSCRIBE_SHADER_LIB(gpu model render-utils)
# This is not a testcase -- just set it up as a regular hifi project
setup_hifi_project(Quick Gui OpenGL Script Widgets)
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Tests/manual-tests/")
link_hifi_libraries(networking gl gpu gpu-gl procedural shared fbx model model-networking animation script-engine render render-utils octree image)
link_hifi_libraries(networking gl gpu gpu-gl procedural shared fbx model model-networking animation script-engine render render-utils octree image ktx)
package_libraries_for_deployment()
target_nsight()