summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/app_settings/settings.xml12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl1
-rwxr-xr-xindra/newview/llfloaterpreference.cpp5
-rw-r--r--indra/newview/llgroupmgr.cpp14
-rw-r--r--indra/newview/llgroupmgr.h5
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp13
-rw-r--r--indra/newview/llpanelgroupgeneral.h3
-rw-r--r--indra/newview/llpanelgrouproles.cpp41
-rw-r--r--indra/newview/llpanelgrouproles.h7
-rw-r--r--indra/newview/lltexturecache.cpp15
-rwxr-xr-xindra/newview/llviewerwindow.cpp55
-rw-r--r--indra/newview/pipeline.cpp80
-rw-r--r--indra/newview/pipeline.h19
13 files changed, 197 insertions, 73 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4fa1663907..7801edb155 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -14070,5 +14070,17 @@
<real>1.0</real>
</array>
</map>
+
+ <key>SimulateFBOFailure</key>
+ <map>
+ <key>Comment</key>
+ <string>[DEBUG] Make allocateScreenBuffer return false. Used to test error handling.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
index e02a7b405b..2cef8f2a5d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
@@ -2093,7 +2093,6 @@ uniform sampler2D diffuseMap;
uniform vec2 rcp_screen_res;
uniform vec4 rcp_frame_opt;
uniform vec4 rcp_frame_opt2;
-uniform vec2 screen_res;
VARYING vec2 vary_fragcoord;
VARYING vec2 vary_tc;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 5752f839ce..542e96cf16 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -750,7 +750,10 @@ void LLFloaterPreference::onClose(bool app_quitting)
{
gSavedSettings.setS32("LastPrefTab", getChild<LLTabContainer>("pref core")->getCurrentPanelIndex());
LLPanelLogin::setAlwaysRefresh(false);
- cancel();
+ if (!app_quitting)
+ {
+ cancel();
+ }
}
void LLFloaterPreference::onOpenHardwareSettings()
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 6916cf813a..81eb1d397e 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -238,6 +238,7 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) :
mPendingRoleMemberRequest(FALSE),
mAccessTime(0.0f)
{
+ mMemberVersion.generate();
}
void LLGroupMgrGroupData::setAccessed()
@@ -318,14 +319,14 @@ void LLGroupMgrGroupData::setRoleData(const LLUUID& role_id, LLRoleData role_dat
role_data.mChangeType = RC_UPDATE_DATA;
}
else
- {
+ {
role_data.mChangeType = RC_UPDATE_POWERS;
}
mRoleChanges[role_id] = role_data;
}
else
- {
+ {
llwarns << "Change being made to non-existant role " << role_id << llendl;
}
}
@@ -424,6 +425,7 @@ void LLGroupMgrGroupData::removeMemberData()
}
mMembers.clear();
mMemberDataComplete = FALSE;
+ mMemberVersion.generate();
}
void LLGroupMgrGroupData::removeRoleData()
@@ -945,6 +947,8 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)
}
}
+ group_datap->mMemberVersion.generate();
+
if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount)
{
group_datap->mMemberDataComplete = TRUE;
@@ -1771,8 +1775,6 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
bool start_message = true;
LLMessageSystem* msg = gMessageSystem;
-
-
LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id);
if (!group_datap) return;
@@ -1833,6 +1835,8 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id,
{
gAgent.sendReliableMessage();
}
+
+ group_datap->mMemberVersion.generate();
}
@@ -1990,6 +1994,8 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content)
group_datap->mMembers[member_id] = data;
}
+ group_datap->mMemberVersion.generate();
+
// Technically, we have this data, but to prevent completely overhauling
// this entire system (it would be nice, but I don't have the time),
// I'm going to be dumb and just call services I most likely don't need
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index 62b2978f21..d8c1ab7ef5 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -236,6 +236,8 @@ public:
F32 getAccessTime() const { return mAccessTime; }
void setAccessed();
+ const LLUUID& getMemberVersion() const { return mMemberVersion; }
+
public:
typedef std::map<LLUUID,LLGroupMemberData*> member_list_t;
typedef std::map<LLUUID,LLGroupRoleData*> role_list_t;
@@ -284,6 +286,9 @@ private:
BOOL mPendingRoleMemberRequest;
F32 mAccessTime;
+
+ // Generate a new ID every time mMembers
+ LLUUID mMemberVersion;
};
struct LLRoleAction
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 51b4d2ea65..993ffb7825 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -670,7 +670,6 @@ void LLPanelGroupGeneral::update(LLGroupChange gc)
{
mMemberProgress = gdatap->mMembers.begin();
mPendingMemberUpdate = TRUE;
- mUdpateSessionID.generate();
sSDTime = 0.0f;
sElementTime = 0.0f;
@@ -730,7 +729,7 @@ void LLPanelGroupGeneral::updateMembers()
// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
LLAvatarNameCache::get(mMemberProgress->first,
boost::bind(&LLPanelGroupGeneral::onNameCache,
- this, mUdpateSessionID, member, _1, _2));
+ this, gdatap->getMemberVersion(), member, _2));
}
}
@@ -768,11 +767,15 @@ void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
}
}
-void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name)
+void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
{
- if (!member
- || update_id != mUdpateSessionID)
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
+
+ if (!gdatap
+ || !gdatap->isMemberDataComplete()
+ || gdatap->getMemberVersion() != update_id)
{
+ // Stale data
return;
}
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index b179f78c56..1b4e8e2645 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -63,7 +63,7 @@ public:
virtual void setupCtrls (LLPanel* parent);
- void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name);
+ void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name);
private:
void reset();
@@ -90,7 +90,6 @@ private:
BOOL mChanged;
BOOL mFirstUse;
std::string mIncompleteMemberDataStr;
- LLUUID mUdpateSessionID;
// Group information (include any updates in updateChanged)
LLLineEditor *mGroupNameEditor;
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 5720168f81..ff106882f4 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -745,7 +745,6 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
mHasMatch(FALSE),
mNumOwnerAdditions(0)
{
- mUdpateSessionID = LLUUID::null;
}
LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
@@ -1427,13 +1426,20 @@ U64 LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges(const LLUUID& ag
return GP_NO_POWERS;
}
- LLGroupMemberData* member_data = gdatap->mMembers[agent_id];
- if ( !member_data )
+ LLGroupMgrGroupData::member_list_t::iterator iter = gdatap->mMembers.find(agent_id);
+ if ( iter == gdatap->mMembers.end() )
{
llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- No member data for member with UUID " << agent_id << llendl;
return GP_NO_POWERS;
}
+ LLGroupMemberData* member_data = (*iter).second;
+ if (!member_data)
+ {
+ llwarns << "LLPanelGroupMembersSubTab::getAgentPowersBasedOnRoleChanges() -- Null member data for member with UUID " << agent_id << llendl;
+ return GP_NO_POWERS;
+ }
+
//see if there are unsaved role changes for this agent
role_change_data_map_t* role_change_datap = NULL;
member_role_changes_map_t::iterator member = mMemberRoleChangeData.find(agent_id);
@@ -1548,10 +1554,6 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc)
mMemberProgress = gdatap->mMembers.begin();
mPendingMemberUpdate = TRUE;
mHasMatch = FALSE;
- // Generate unique ID for current updateMembers()- see onNameCache for details.
- // Using unique UUID is perhaps an overkill but this way we are perfectly safe
- // from coincidences.
- mUdpateSessionID.generate();
}
else
{
@@ -1579,14 +1581,14 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc)
}
}
-void LLPanelGroupMembersSubTab::addMemberToList(LLUUID id, LLGroupMemberData* data)
+void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data)
{
if (!data) return;
LLUIString donated = getString("donation_area");
donated.setArg("[AREA]", llformat("%d", data->getContribution()));
LLNameListCtrl::NameItem item_params;
- item_params.value = id;
+ item_params.value = data->getID();
item_params.columns.add().column("name").font.name("SANSSERIF_SMALL").style("NORMAL");
@@ -1600,17 +1602,12 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLUUID id, LLGroupMemberData* da
mHasMatch = TRUE;
}
-void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name)
+void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
{
- // Update ID is used to determine whether member whose id is passed
- // into onNameCache() was passed after current or previous user-initiated update.
- // This is needed to avoid probable duplication of members in list after changing filter
- // or adding of members of another group if gets for their names were called on
- // previous update. If this id is from get() called from older update,
- // we do nothing.
- if (mUdpateSessionID != update_id) return;
-
- if (!member)
+ LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
+ if (!gdatap
+ || gdatap->getMemberVersion() != update_id
+ || !member)
{
return;
}
@@ -1618,7 +1615,7 @@ void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemb
// trying to avoid unnecessary hash lookups
if (matchesSearchFilter(av_name.getLegacyName()))
{
- addMemberToList(id, member);
+ addMemberToList(member);
if(!mMembersList->getEnabled())
{
mMembersList->setEnabled(TRUE);
@@ -1672,14 +1669,14 @@ void LLPanelGroupMembersSubTab::updateMembers()
{
if (matchesSearchFilter(av_name.getLegacyName()))
{
- addMemberToList(mMemberProgress->first, mMemberProgress->second);
+ addMemberToList(mMemberProgress->second);
}
}
else
{
// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
- this, mUdpateSessionID, mMemberProgress->second, _1, _2));
+ this, gdatap->getMemberVersion(), mMemberProgress->second, _2));
}
}
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 8b454e020a..bead8bd85b 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -187,8 +187,8 @@ public:
virtual void setGroupID(const LLUUID& id);
- void addMemberToList(LLUUID id, LLGroupMemberData* data);
- void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLUUID& id, const LLAvatarName& av_name);
+ void addMemberToList(LLGroupMemberData* data);
+ void onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name);
protected:
typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t;
@@ -210,9 +210,6 @@ protected:
BOOL mPendingMemberUpdate;
BOOL mHasMatch;
- // This id is generated after each user initiated member list update(opening Roles or changing filter)
- LLUUID mUdpateSessionID;
-
member_role_changes_map_t mMemberRoleChangeData;
U32 mNumOwnerAdditions;
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index a61e2d5c86..2d463f0afa 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1861,7 +1861,12 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
mFastCachep->seek(APR_SET, offset);
- llassert_always(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) == TEXTURE_FAST_CACHE_ENTRY_OVERHEAD);
+ if(mFastCachep->read(head, TEXTURE_FAST_CACHE_ENTRY_OVERHEAD) != TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
+ {
+ //cache corrupted or under thread race condition
+ closeFastCache();
+ return NULL;
+ }
S32 image_size = head[0] * head[1] * head[2];
if(!image_size) //invalid
@@ -1872,7 +1877,13 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
discardlevel = head[3];
data = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), image_size);
- llassert_always(mFastCachep->read(data, image_size) == image_size);
+ if(mFastCachep->read(data, image_size) != image_size)
+ {
+ FREE_MEM(LLImageBase::getPrivatePool(), data);
+ closeFastCache();
+ return NULL;
+ }
+
closeFastCache();
}
LLPointer<LLImageRaw> raw = new LLImageRaw(data, head[0], head[1], head[2], true);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 44e6d70546..ffaf881521 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4236,14 +4236,48 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
image_height = llmin(image_height, window_height);
}
+ S32 original_width = 0;
+ S32 original_height = 0;
+ bool reset_deferred = false;
+
+ LLRenderTarget scratch_space;
+
F32 scale_factor = 1.0f ;
if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height))
{
- // if image cropping or need to enlarge the scene, compute a scale_factor
- F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
- snapshot_width = (S32)(ratio * image_width) ;
- snapshot_height = (S32)(ratio * image_height) ;
- scale_factor = llmax(1.0f, 1.0f / ratio) ;
+ if ((image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
+ {
+ if (scratch_space.allocate(image_width, image_height, GL_RGBA, true, true))
+ {
+ original_width = gPipeline.mDeferredScreen.getWidth();
+ original_height = gPipeline.mDeferredScreen.getHeight();
+
+ if (gPipeline.allocateScreenBuffer(image_width, image_height))
+ {
+ window_width = image_width;
+ window_height = image_height;
+ snapshot_width = image_width;
+ snapshot_height = image_height;
+ reset_deferred = true;
+ mWorldViewRectRaw.set(0, image_height, image_width, 0);
+ scratch_space.bindTarget();
+ }
+ else
+ {
+ scratch_space.release();
+ gPipeline.allocateScreenBuffer(original_width, original_height);
+ }
+ }
+ }
+
+ if (!reset_deferred)
+ {
+ // if image cropping or need to enlarge the scene, compute a scale_factor
+ F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
+ snapshot_width = (S32)(ratio * image_width) ;
+ snapshot_height = (S32)(ratio * image_height) ;
+ scale_factor = llmax(1.0f, 1.0f / ratio) ;
+ }
}
if (show_ui && scale_factor > 1.f)
@@ -4432,11 +4466,20 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
gPipeline.resetDrawOrders();
}
+ if (reset_deferred)
+ {
+ mWorldViewRectRaw = window_rect;
+ scratch_space.flush();
+ scratch_space.release();
+ gPipeline.allocateScreenBuffer(original_width, original_height);
+
+ }
+
if (high_res)
{
send_agent_resume();
}
-
+
return ret;
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ea2dc60b07..ab45bd3d3b 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -779,18 +779,57 @@ void LLPipeline::allocatePhysicsBuffer()
}
}
-void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
+bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
refreshCachedSettings();
- U32 samples = RenderFSAASamples;
+
+ bool save_settings = sRenderDeferred;
+ if (save_settings)
+ {
+ // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
+ gSavedSettings.setBOOL("RenderInitError", TRUE);
+ gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ }
+
+ eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
+
+ if (save_settings)
+ {
+ // don't disable shaders on next session
+ gSavedSettings.setBOOL("RenderInitError", FALSE);
+ gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ }
+
+ if (ret == FBO_FAILURE)
+ { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
+ //NOTE: if the session closes successfully after this call, deferred rendering will be
+ // disabled on future sessions
+ if (LLPipeline::sRenderDeferred)
+ {
+ gSavedSettings.setBOOL("RenderDeferred", FALSE);
+ LLPipeline::refreshCachedSettings();
+ }
+ }
+
+ return ret == FBO_SUCCESS_FULLRES;
+}
- //try to allocate screen buffers at requested resolution and samples
+
+LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
+{
+ // try to allocate screen buffers at requested resolution and samples
// - on failure, shrink number of samples and try again
// - if not multisampled, shrink resolution and try again (favor X resolution over Y)
// Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state
+ U32 samples = RenderFSAASamples;
+
+ eFBOStatus ret = FBO_SUCCESS_FULLRES;
if (!allocateScreenBuffer(resX, resY, samples))
{
+ //failed to allocate at requested specification, return false
+ ret = FBO_FAILURE;
+
releaseScreenBuffers();
//reduce number of samples
while (samples > 0)
@@ -798,7 +837,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
samples /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{ //success
- return;
+ return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
}
@@ -811,22 +850,23 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
resY /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{
- return;
+ return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
resX /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{
- return;
+ return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
}
llwarns << "Unable to allocate screen buffer at any resolution!" << llendl;
}
-}
+ return ret;
+}
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
@@ -854,10 +894,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (LLPipeline::sRenderDeferred)
{
- // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
- gSavedSettings.setBOOL("RenderInitError", TRUE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
-
S32 shadow_detail = RenderShadowDetail;
BOOL ssao = RenderDeferredSSAO;
@@ -869,7 +905,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (samples > 0)
{
- if (!mFXAABuffer.allocate(nhpo2(resX), nhpo2(resY), GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
+ if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
}
else
{
@@ -903,7 +939,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
}
- U32 width = nhpo2(U32(resX*scale))/2;
+ U32 width = (U32) (resX*scale);
U32 height = width;
if (shadow_detail > 1)
@@ -922,9 +958,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
}
- // don't disable shaders on next session
- gSavedSettings.setBOOL("RenderInitError", FALSE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
+ //HACK make screenbuffer allocations start failing after 30 seconds
+ if (gSavedSettings.getBOOL("SimulateFBOFailure"))
+ {
+ return false;
+ }
}
else
{
@@ -7117,11 +7155,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGlowProgram.unbind();
- if (LLRenderTarget::sUseFBO)
+ /*if (LLRenderTarget::sUseFBO)
{
LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
+ }*/
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
@@ -7997,10 +8035,6 @@ void LLPipeline::renderDeferredLighting()
gGL.popMatrix();
stop_glerror();
- //copy depth and stencil from deferred screen
- //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
- // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
-
mScreen.bindTarget();
// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
glClearColor(0,0,0,0);
@@ -8772,8 +8806,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
- LLRenderTarget::unbindTarget();
-
LLPipeline::sReflectionRender = FALSE;
if (!LLRenderTarget::sUseFBO)
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 7a0ca86231..36abeca295 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -119,8 +119,25 @@ public:
void createGLBuffers();
void createLUTBuffers();
- void allocateScreenBuffer(U32 resX, U32 resY);
+ //allocate the largest screen buffer possible up to resX, resY
+ //returns true if full size buffer allocated, false if some other size is allocated
+ bool allocateScreenBuffer(U32 resX, U32 resY);
+
+ typedef enum {
+ FBO_SUCCESS_FULLRES = 0,
+ FBO_SUCCESS_LOWRES,
+ FBO_FAILURE
+ } eFBOStatus;
+
+private:
+ //implementation of above, wrapped for easy error handling
+ eFBOStatus doAllocateScreenBuffer(U32 resX, U32 resY);
+public:
+
+ //attempt to allocate screen buffers at resX, resY
+ //returns true if allocation successful, false otherwise
bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);
+
void allocatePhysicsBuffer();
void resetVertexBuffers(LLDrawable* drawable);