void GLES2Texture::notifyOnContextReset() { if (!mIsManual) { reload(); } else { preLoadImpl(); _createGLTexResource(); for(size_t i = 0; i < mSurfaceList.size(); i++) { static_cast<GLES2TextureBuffer*>(mSurfaceList[i].getPointer())->updateTextureId(mTextureID); } if (mLoader) { mLoader->loadResource(this); } postLoadImpl(); } }
//--------------------------------------------------------------------- void Resource::load(bool background) { // Early-out without lock (mitigate perf cost of ensuring loaded) // Don't load if: // 1. We're already loaded // 2. Another thread is loading right now // 3. We're marked for background loading and this is not the background // loading thread we're being called by if (mIsBackgroundLoaded && !background) return; // This next section is to deal with cases where 2 threads are fighting over // who gets to prepare / load - this will only usually happen if loading is escalated bool keepChecking = true; LoadingState old; while (keepChecking) { // quick check that avoids any synchronisation old = mLoadingState.get(); if ( old == LOADSTATE_PREPARING ) { while( mLoadingState.get() == LOADSTATE_PREPARING ) { OGRE_LOCK_AUTO_MUTEX } old = mLoadingState.get(); } if (old!=LOADSTATE_UNLOADED && old!=LOADSTATE_PREPARED && old!=LOADSTATE_LOADING) return; // atomically do slower check to make absolutely sure, // and set the load state to LOADING if (old==LOADSTATE_LOADING || !mLoadingState.cas(old,LOADSTATE_LOADING)) { while( mLoadingState.get() == LOADSTATE_LOADING ) { OGRE_LOCK_AUTO_MUTEX } LoadingState state = mLoadingState.get(); if( state == LOADSTATE_PREPARED || state == LOADSTATE_PREPARING ) { // another thread is preparing, loop around continue; } else if( state != LOADSTATE_LOADED ) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Another thread failed in resource operation", "Resource::load"); } return; } keepChecking = false; } // Scope lock for actual loading try { OGRE_LOCK_AUTO_MUTEX if (mIsManual) { preLoadImpl(); // Load from manual loader if (mLoader) { mLoader->loadResource(this); } else { // Warn that this resource is not reloadable LogManager::getSingleton().stream(LML_TRIVIAL) << "WARNING: " << mCreator->getResourceType() << " instance '" << mName << "' was defined as manually " << "loaded, but no manual loader was provided. This Resource " << "will be lost if it has to be reloaded."; } postLoadImpl(); } else { if (old==LOADSTATE_UNLOADED) prepareImpl(); preLoadImpl(); old = LOADSTATE_PREPARED; if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) { // Derive resource group changeGroupOwnership( ResourceGroupManager::getSingleton() .findGroupContainingResource(mName)); } loadImpl(); postLoadImpl(); } // Calculate resource size mSize = calculateSize(); } catch (...) { // Reset loading in-progress flag, in case failed for some reason. // We reset it to UNLOADED because the only other case is when // old == PREPARED in which case the loadImpl should wipe out // any prepared data since it might be invalid. mLoadingState.set(LOADSTATE_UNLOADED); // Re-throw throw; } mLoadingState.set(LOADSTATE_LOADED); _dirtyState(); // Notify manager if(mCreator) mCreator->_notifyResourceLoaded(this); // Fire (deferred) events if (mIsBackgroundLoaded) queueFireBackgroundLoadingComplete(); }
//----------------------------------------------------------------------- void Resource::load(bool background) { // Early-out without lock (mitigate perf cost of ensuring loaded) // Don't load if: // 1. We're already loaded // 2. Another thread is loading right now // 3. We're marked for background loading and this is not the background // loading thread we're being called by if (mLoadingState != LOADSTATE_UNLOADED || (mIsBackgroundLoaded && !background)) return; // Scope lock over load status { OGRE_LOCK_MUTEX(mLoadingStatusMutex) // Check again just in case status changed (since we didn't lock above) if (mLoadingState != LOADSTATE_UNLOADED || (mIsBackgroundLoaded && !background)) { // no loading to be done return; } mLoadingState = LOADSTATE_LOADING; } // Scope lock for actual loading try { OGRE_LOCK_AUTO_MUTEX preLoadImpl(); if (mIsManual) { // Load from manual loader if (mLoader) { mLoader->loadResource(this); } else { // Warn that this resource is not reloadable LogManager::getSingleton().logMessage( "WARNING: " + mCreator->getResourceType() + " instance '" + mName + "' was defined as manually " "loaded, but no manual loader was provided. This Resource " "will be lost if it has to be reloaded."); } } else { if (mGroup == ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME) { // Derive resource group changeGroupOwnership( ResourceGroupManager::getSingleton() .findGroupContainingResource(mName)); } loadImpl(); } // Calculate resource size mSize = calculateSize(); postLoadImpl(); } catch (...) { // Reset loading in-progress flag in case failed for some reason OGRE_LOCK_MUTEX(mLoadingStatusMutex) mLoadingState = LOADSTATE_UNLOADED; // Re-throw throw; } // Scope lock for loading progress { OGRE_LOCK_MUTEX(mLoadingStatusMutex) // Now loaded mLoadingState = LOADSTATE_LOADED; } // Notify manager if(mCreator) mCreator->_notifyResourceLoaded(this); // Fire (deferred) events if (mIsBackgroundLoaded) queueFireBackgroundLoadingComplete(); }