diff options
| -rw-r--r-- | indra/llaudio/llaudioengine_openal.cpp | 17 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 32 | ||||
| -rw-r--r-- | indra/newview/llspeakingindicatormanager.cpp | 25 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 7 |
4 files changed, 62 insertions, 19 deletions
diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index 4126c8ef80..b65e9c518f 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -500,6 +500,7 @@ bool LLAudioEngine_OpenAL::initWind() if((error=alGetError()) != AL_NO_ERROR) { LL_WARNS() << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<LL_ENDL; + mWindSource = AL_NONE; } mWindGen = new LLWindGen<WIND_SAMPLE_T>; @@ -564,6 +565,9 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) if(!mWindBuf) return; + if (mWindSource == AL_NONE) + return; + if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) { @@ -589,7 +593,7 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) // ok lets make a wind buffer now - ALint processed, queued, unprocessed; + ALint processed = 0, queued = 0, unprocessed = 0; alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed); alGetSourcei(mWindSource, AL_BUFFERS_QUEUED, &queued); unprocessed = queued - processed; @@ -601,7 +605,7 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) //LL_INFOS() << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << LL_ENDL; - while(processed--) // unqueue old buffers + while (processed > 0) // unqueue old buffers { ALuint buffer; ALenum error; @@ -610,12 +614,11 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) error = alGetError(); if(error != AL_NO_ERROR) { - LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << LL_ENDL; - } - else - { - alDeleteBuffers(1, &buffer); + LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers: " << error << LL_ENDL; + break; } + alDeleteBuffers(1, &buffer); + --processed; } unprocessed += mNumEmptyWindALBuffers; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index dcee340a71..0745397c3a 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -370,21 +370,39 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) bool LLRenderTarget::allocateDepth() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + if (mResX == 0 || mResY == 0) + { + LL_WARNS() << "Unable to allocate depth buffer for render target " << mName + << ": size " << mResX << "x" << mResY << LL_ENDL; + return false; + } + LLImageGL::generateTextures(1, &mDepth); gGL.getTexUnit(0)->bindManual(mUsage, mDepth); U32 internal_type = LLTexUnit::getInternalType(mUsage); - LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - - sBytesAllocated += mResX*mResY*4; - - if (glGetError() != GL_NO_ERROR) + // Apple's GL rejects the sized GL_DEPTH_COMPONENT24 internal format + // with GL_UNSIGNED_INT. The unsized format is the one it allocates. +#if LL_DARWIN + const U32 depth_internal = GL_DEPTH_COMPONENT; +#else + const U32 depth_internal = GL_DEPTH_COMPONENT24; +#endif + glGetError(); + LLImageGL::setManualImage(internal_type, 0, depth_internal, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false); + GLenum err = glGetError(); + if (err != GL_NO_ERROR) { - LL_WARNS() << "Unable to allocate depth buffer for render target " << mName << LL_ENDL; + LL_WARNS() << "Unable to allocate depth buffer for render target " << mName + << " (" << mResX << "x" << mResY << ") gl error " << err << LL_ENDL; return false; } + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + glGetError(); + + sBytesAllocated += mResX*mResY*4; + return true; } diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index aa3eaba21d..70d8d64ae0 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -147,6 +147,10 @@ void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_i LL_DEBUGS("SpeakingIndicator") << "Registering indicator: " << speaker_id << "|"<< speaking_indicator << ", session: " << session_id << LL_ENDL; + if (!speaking_indicator) + { + return; + } ensureInstanceDoesNotExist(speaking_indicator); @@ -167,15 +171,20 @@ void SpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker_i void SpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator) { LL_DEBUGS("SpeakingIndicator") << "Unregistering indicator: " << speaker_id << "|"<< speaking_indicator << LL_ENDL; - speaking_indicators_mmap_t::iterator it; - it = mSpeakingIndicators.find(speaker_id); - for (;it != mSpeakingIndicators.end(); ++it) + // The same control can be registered under more than one speaker id. + // Removing only the current id leaves a dangling pointer that crashes + // the next time that speaker's indicators are switched. See EXT-4782. + speaking_indicators_mmap_t::iterator it = mSpeakingIndicators.begin(); + while (it != mSpeakingIndicators.end()) { if (it->second == speaking_indicator) { LL_DEBUGS("SpeakingIndicator") << "Unregistered." << LL_ENDL; - mSpeakingIndicators.erase(it); - break; + it = mSpeakingIndicators.erase(it); + } + else + { + ++it; } } } @@ -253,6 +262,10 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea { was_found = true; LLSpeakingIndicator* indicator = (*it_indicator).second; + if (!indicator) + { + continue; + } was_switched_on = was_switched_on || switch_on; if (indicator) indicator->switchIndicator(switch_on); @@ -279,6 +292,8 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea void SpeakingIndicatorManager::ensureInstanceDoesNotExist(LLSpeakingIndicator* const speaking_indicator) { LL_DEBUGS("SpeakingIndicator") << "Searching for an registered indicator instance: " << speaking_indicator << LL_ENDL; + // The same LLOutputMonitorCtrl can be registered under several speaker ids. + // Every copy has to be removed before it is registered again. See EXT-4782. speaking_indicators_mmap_t::iterator it = mSpeakingIndicators.begin(); while (it != mSpeakingIndicators.end()) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index bccff55a2c..2b45892ff4 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8906,6 +8906,13 @@ void LLPipeline::renderDeferredLighting() LLRenderTarget *screen_target = &mRT->screen; LLRenderTarget* deferred_light_target = &mRT->deferredLight; + // A failed depth allocation leaves these targets with no textures. + // Binding them logs the empty-target warnings and then faults in the GL driver. + if (screen_target->getNumTextures() == 0) + { + return; + } + { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); LLViewerCamera *camera = LLViewerCamera::getInstance(); |
