summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llaudio/llaudioengine_openal.cpp17
-rw-r--r--indra/llrender/llrendertarget.cpp32
-rw-r--r--indra/newview/llspeakingindicatormanager.cpp25
-rw-r--r--indra/newview/pipeline.cpp7
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();