summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/00-Common.cmake1
-rw-r--r--indra/linux_updater/linux_updater.cpp2
-rw-r--r--indra/llaudio/llaudiodecodemgr.cpp22
-rw-r--r--indra/llaudio/llaudioengine.cpp22
-rw-r--r--indra/llaudio/llaudioengine.h9
-rw-r--r--indra/llcharacter/llcharacter.cpp6
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp17
-rw-r--r--indra/llcommon/llsd.cpp1
-rw-r--r--indra/llcommon/llstrider.h10
-rw-r--r--indra/llmath/lloctree.h143
-rw-r--r--indra/llmath/llvolume.cpp8
-rw-r--r--indra/llmath/llvolume.h5
-rw-r--r--indra/llmath/llvolumeoctree.cpp6
-rw-r--r--indra/llmath/llvolumeoctree.h9
-rw-r--r--indra/llmessage/llcurl.cpp53
-rw-r--r--indra/llmessage/llcurl.h5
-rw-r--r--indra/llmessage/llsdmessagereader.cpp2
-rw-r--r--indra/llrender/llcubemap.cpp2
-rw-r--r--indra/llrender/llgl.cpp117
-rw-r--r--indra/llrender/llgl.h29
-rw-r--r--indra/llrender/llglheaders.h13
-rw-r--r--indra/llrender/llglslshader.cpp11
-rw-r--r--indra/llrender/llglslshader.h4
-rw-r--r--indra/llrender/llimagegl.cpp166
-rw-r--r--indra/llrender/llimagegl.h24
-rw-r--r--indra/llrender/llrender.cpp26
-rw-r--r--indra/llrender/llrendertarget.cpp51
-rw-r--r--indra/llrender/llrendertarget.h9
-rw-r--r--indra/llrender/llshadermgr.cpp3
-rw-r--r--indra/llrender/llshadermgr.h2
-rw-r--r--indra/llrender/llvertexbuffer.cpp311
-rw-r--r--indra/llrender/llvertexbuffer.h43
-rw-r--r--indra/llui/llmultifloater.cpp2
-rw-r--r--indra/llui/lltextbase.cpp37
-rw-r--r--indra/llui/lltextbox.cpp2
-rw-r--r--indra/llui/llui.cpp6
-rw-r--r--indra/llui/llviewmodel.h1
-rw-r--r--indra/llvfs/lldir.cpp7
-rw-r--r--indra/llwindow/llwindowwin32.cpp7
-rw-r--r--indra/mac_updater/mac_updater.cpp4
-rw-r--r--indra/newview/app_settings/settings.xml89
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl103
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/clipF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/clipV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/binormalV.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/colorV.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/normalV.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/positionV.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl35
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl122
-rw-r--r--indra/newview/featuretable.txt43
-rw-r--r--indra/newview/featuretable_linux.txt43
-rw-r--r--indra/newview/featuretable_mac.txt42
-rw-r--r--indra/newview/featuretable_xp.txt42
-rw-r--r--indra/newview/gpu_table.txt1
-rw-r--r--indra/newview/llappviewer.cpp25
-rwxr-xr-xindra/newview/llavataractions.cpp16
-rw-r--r--indra/newview/llchathistory.cpp9
-rw-r--r--indra/newview/lldrawable.cpp120
-rw-r--r--indra/newview/lldrawable.h13
-rw-r--r--indra/newview/lldrawpool.cpp44
-rw-r--r--indra/newview/lldrawpool.h4
-rw-r--r--indra/newview/lldrawpoolalpha.cpp10
-rw-r--r--indra/newview/lldrawpoolavatar.cpp82
-rw-r--r--indra/newview/lldrawpoolbump.cpp19
-rw-r--r--indra/newview/lldrawpoolterrain.cpp28
-rw-r--r--indra/newview/lldrawpoolterrain.h1
-rw-r--r--indra/newview/lldrawpooltree.cpp15
-rw-r--r--indra/newview/lldriverparam.cpp26
-rw-r--r--indra/newview/lldriverparam.h10
-rw-r--r--indra/newview/llface.cpp1252
-rw-r--r--indra/newview/llface.h13
-rw-r--r--indra/newview/llfavoritesbar.cpp4
-rw-r--r--indra/newview/llfavoritesbar.h2
-rw-r--r--indra/newview/llfeaturemanager.cpp13
-rw-r--r--indra/newview/llflexibleobject.cpp150
-rw-r--r--indra/newview/llflexibleobject.h7
-rw-r--r--indra/newview/llfloaterbuycontents.cpp4
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp34
-rw-r--r--indra/newview/llfloaterhardwaresettings.cpp14
-rw-r--r--indra/newview/llfloaterimagepreview.cpp10
-rw-r--r--indra/newview/llfloaterland.cpp18
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp6
-rw-r--r--indra/newview/llfloatermodelpreview.h1
-rw-r--r--indra/newview/llfolderview.cpp6
-rw-r--r--indra/newview/llfolderviewitem.cpp17
-rw-r--r--indra/newview/llgiveinventory.cpp68
-rw-r--r--indra/newview/llgiveinventory.h7
-rw-r--r--indra/newview/llimfloatercontainer.cpp1
-rw-r--r--indra/newview/llimview.cpp10
-rw-r--r--indra/newview/llinspectobject.cpp9
-rw-r--r--indra/newview/llinventoryfilter.cpp2
-rw-r--r--indra/newview/llinventorymodel.cpp5
-rw-r--r--indra/newview/llmaniptranslate.cpp34
-rwxr-xr-xindra/newview/llmeshrepository.cpp4
-rw-r--r--indra/newview/llnavigationbar.cpp9
-rw-r--r--indra/newview/llnavigationbar.h1
-rw-r--r--indra/newview/llnearbychatbar.cpp28
-rw-r--r--indra/newview/llnearbychatbar.h3
-rw-r--r--indra/newview/llpaneleditwearable.cpp1
-rw-r--r--indra/newview/llpanelface.cpp78
-rw-r--r--indra/newview/llpanelface.h9
-rw-r--r--indra/newview/llpanellandmedia.cpp1
-rw-r--r--indra/newview/llpanelobject.cpp1
-rw-r--r--indra/newview/llphysicsmotion.cpp77
-rw-r--r--indra/newview/llpolymesh.cpp191
-rw-r--r--indra/newview/llpolymesh.h52
-rw-r--r--indra/newview/llpolymorph.cpp165
-rw-r--r--indra/newview/llpolymorph.h18
-rw-r--r--indra/newview/llprogressview.cpp34
-rw-r--r--indra/newview/llprogressview.h7
-rw-r--r--indra/newview/llselectmgr.cpp82
-rw-r--r--indra/newview/llselectmgr.h9
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp2
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp4
-rw-r--r--indra/newview/llspatialpartition.cpp532
-rw-r--r--indra/newview/llspatialpartition.h95
-rw-r--r--indra/newview/llsurface.cpp8
-rw-r--r--indra/newview/llsurfacepatch.cpp14
-rw-r--r--indra/newview/lltexlayerparams.h20
-rw-r--r--indra/newview/lltextureatlas.cpp1
-rw-r--r--indra/newview/lltexturectrl.cpp68
-rw-r--r--indra/newview/lltexturectrl.h12
-rw-r--r--indra/newview/lltooldraganddrop.h14
-rw-r--r--indra/newview/lltoolmorph.cpp3
-rw-r--r--indra/newview/llviewercontrol.cpp2
-rw-r--r--indra/newview/llviewerdisplay.cpp63
-rw-r--r--indra/newview/llviewerjointattachment.cpp24
-rw-r--r--indra/newview/llviewermenu.cpp11
-rwxr-xr-xindra/newview/llviewermessage.cpp59
-rw-r--r--indra/newview/llviewerobject.cpp63
-rw-r--r--indra/newview/llviewerobject.h9
-rw-r--r--indra/newview/llviewerobjectlist.cpp102
-rw-r--r--indra/newview/llviewerobjectlist.h4
-rw-r--r--indra/newview/llviewerpartsim.cpp2
-rw-r--r--indra/newview/llviewerpartsim.h2
-rw-r--r--indra/newview/llviewerregion.cpp3
-rw-r--r--indra/newview/llviewershadermgr.cpp296
-rw-r--r--indra/newview/llviewershadermgr.h14
-rw-r--r--indra/newview/llviewerstats.cpp18
-rw-r--r--indra/newview/llviewertexture.cpp12
-rw-r--r--indra/newview/llviewertexture.h3
-rw-r--r--indra/newview/llviewertexturelist.cpp5
-rw-r--r--indra/newview/llviewervisualparam.h8
-rwxr-xr-xindra/newview/llviewerwindow.cpp61
-rw-r--r--indra/newview/llvoavatar.cpp68
-rw-r--r--indra/newview/llvoavatar.h4
-rw-r--r--indra/newview/llvoavatarself.cpp2
-rw-r--r--indra/newview/llvograss.cpp168
-rw-r--r--indra/newview/llvoground.cpp3
-rw-r--r--indra/newview/llvopartgroup.cpp276
-rw-r--r--indra/newview/llvopartgroup.h22
-rw-r--r--indra/newview/llvosurfacepatch.cpp64
-rw-r--r--indra/newview/llvotree.cpp17
-rw-r--r--indra/newview/llvovolume.cpp1005
-rw-r--r--indra/newview/llvovolume.h6
-rw-r--r--indra/newview/llvowater.cpp4
-rw-r--r--indra/newview/llworld.cpp15
-rw-r--r--indra/newview/pipeline.cpp646
-rw-r--r--indra/newview/pipeline.h17
-rw-r--r--indra/newview/skins/default/xui/de/menu_viewer.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_hardware_settings.xml22
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_report_abuse.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_ctrl.xml20
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml31
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_item_info.xml4
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml8
175 files changed, 6112 insertions, 2778 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 98eeed09b3..00baf626d2 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -69,6 +69,7 @@ if (WINDOWS)
/Oy-
/Zc:wchar_t-
/arch:SSE2
+ /fp:fast
)
# Are we using the crummy Visual Studio KDU build workaround?
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index eed00ac06e..9872c0ce27 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -751,7 +751,7 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))
{
app_state->image_dir = argv[i];
- app_state->image_dir_iter = new LLDirIterator(argv[i], "/*.jpg");
+ app_state->image_dir_iter = new LLDirIterator(argv[i], "*.jpg");
}
else if ((!strcmp(argv[i], "--dest")) && (++i < argc))
{
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index 7f747c2eca..6c97a64ed7 100644
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -571,7 +571,8 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
llwarns << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << llendl;
mCurrentDecodep->flushBadFile();
LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
- adp->setHasValidData(FALSE);
+ adp->setHasValidData(false);
+ adp->setHasCompletedDecode(true);
mCurrentDecodep = NULL;
done = TRUE;
}
@@ -586,11 +587,16 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
if (mCurrentDecodep->finishDecode())
{
// We finished!
- if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
+ LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
+ if (!adp)
{
- LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
- adp->setHasDecodedData(TRUE);
- adp->setHasValidData(TRUE);
+ llwarns << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << llendl;
+ }
+ else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
+ {
+ adp->setHasCompletedDecode(true);
+ adp->setHasDecodedData(true);
+ adp->setHasValidData(true);
// At this point, we could see if anyone needs this sound immediately, but
// I'm not sure that there's a reason to - we need to poll all of the playing
@@ -599,7 +605,8 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
}
else
{
- llinfos << "Vorbis decode failed!!!" << llendl;
+ adp->setHasCompletedDecode(true);
+ llinfos << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << llendl;
}
mCurrentDecodep = NULL;
}
@@ -667,16 +674,19 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
if (gAudiop->hasDecodedFile(uuid))
{
// Already have a decoded version, don't need to decode it.
+ //llinfos << "addDecodeRequest for " << uuid << " has decoded file already" << llendl;
return TRUE;
}
if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
{
// Just put it on the decode queue.
+ //llinfos << "addDecodeRequest for " << uuid << " has local asset file already" << llendl;
mImpl->mDecodeQueue.push(uuid);
return TRUE;
}
+ //llinfos << "addDecodeRequest for " << uuid << " no file available" << llendl;
return FALSE;
}
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 5fa28cb902..72c0091d17 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -1221,10 +1221,11 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
// Need to mark data as bad to avoid constant rerequests.
LLAudioData *adp = gAudiop->getAudioData(uuid);
if (adp)
- {
+ { // Make sure everything is cleared
adp->setHasValidData(false);
adp->setHasLocalData(false);
adp->setHasDecodedData(false);
+ adp->setHasCompletedDecode(true);
}
}
else
@@ -1237,6 +1238,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
}
else
{
+ // llinfos << "Got asset callback with good audio data for " << uuid << ", making decode request" << llendl;
adp->setHasValidData(true);
adp->setHasLocalData(true);
gAudioDecodeMgrp->addDecodeRequest(uuid);
@@ -1304,16 +1306,18 @@ void LLAudioSource::update()
if (!getCurrentBuffer())
{
- if (getCurrentData())
+ LLAudioData *adp = getCurrentData();
+ if (adp)
{
// Hack - try and load the sound. Will do this as a callback
// on decode later.
- if (getCurrentData()->load() && getCurrentData()->getBuffer())
+ if (adp->load() && adp->getBuffer())
{
- play(getCurrentData()->getID());
+ play(adp->getID());
}
- else
+ else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done
{
+ llwarns << "Marking LLAudioSource corrupted for " << adp->getID() << llendl;
mCorrupted = true ;
}
}
@@ -1731,6 +1735,7 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
mBufferp(NULL),
mHasLocalData(false),
mHasDecodedData(false),
+ mHasCompletedDecode(false),
mHasValidData(true)
{
if (uuid.isNull())
@@ -1742,12 +1747,13 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
if (gAudiop && gAudiop->hasDecodedFile(uuid))
{
// Already have a decoded version, don't need to decode it.
- mHasLocalData = true;
- mHasDecodedData = true;
+ setHasLocalData(true);
+ setHasDecodedData(true);
+ setHasCompletedDecode(true);
}
else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
{
- mHasLocalData = true;
+ setHasLocalData(true);
}
}
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index 28b69e1973..df1e4dc305 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -372,10 +372,12 @@ public:
bool hasLocalData() const { return mHasLocalData; }
bool hasDecodedData() const { return mHasDecodedData; }
+ bool hasCompletedDecode() const { return mHasCompletedDecode; }
bool hasValidData() const { return mHasValidData; }
void setHasLocalData(const bool hld) { mHasLocalData = hld; }
void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
+ void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; }
void setHasValidData(const bool hvd) { mHasValidData = hvd; }
friend class LLAudioEngine; // Severe laziness, bad.
@@ -383,9 +385,10 @@ public:
protected:
LLUUID mID;
LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
- bool mHasLocalData;
- bool mHasDecodedData;
- bool mHasValidData;
+ bool mHasLocalData; // Set true if the sound asset file is available locally
+ bool mHasDecodedData; // Set true if the sound file has been decoded
+ bool mHasCompletedDecode; // Set true when the sound is decoded
+ bool mHasValidData; // Set false if decoding failed, meaning the sound asset is bad
};
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index c9fb8534f1..0a6a8f9fa6 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -189,6 +189,7 @@ void LLCharacter::requestStopMotion( LLMotion* motion)
//-----------------------------------------------------------------------------
static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation");
static LLFastTimer::DeclareTimer FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim");
+static LLFastTimer::DeclareTimer FTM_UPDATE_MOTIONS("Update Motions");
void LLCharacter::updateMotions(e_update_t update_type)
{
@@ -206,7 +207,10 @@ void LLCharacter::updateMotions(e_update_t update_type)
mMotionController.unpauseAllMotions();
}
bool force_update = (update_type == FORCE_UPDATE);
- mMotionController.updateMotions(force_update);
+ {
+ LLFastTimer t(FTM_UPDATE_MOTIONS);
+ mMotionController.updateMotions(force_update);
+ }
}
}
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index bb892f4a7f..4f6351709e 100644
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -542,6 +542,8 @@ void LLMotionController::updateIdleActiveMotions()
//-----------------------------------------------------------------------------
// updateMotionsByType()
//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_MOTION_ON_UPDATE("Motion onUpdate");
+
void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_type)
{
BOOL update_result = TRUE;
@@ -699,7 +701,10 @@ void LLMotionController::updateMotionsByType(LLMotion::LLMotionBlendType anim_ty
}
// perform motion update
- update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
+ {
+ LLFastTimer t(FTM_MOTION_ON_UPDATE);
+ update_result = motionp->onUpdate(mAnimTime - motionp->mActivationTimestamp, last_joint_signature);
+ }
}
//**********************
@@ -810,7 +815,7 @@ void LLMotionController::updateMotions(bool force_update)
// Always cap the number of loaded motions
purgeExcessMotions();
-
+
// Update timing info for this time step.
if (!mPaused)
{
@@ -832,6 +837,7 @@ void LLMotionController::updateMotions(bool force_update)
}
updateLoadingMotions();
+
return;
}
@@ -850,7 +856,7 @@ void LLMotionController::updateMotions(bool force_update)
}
updateLoadingMotions();
-
+
resetJointSignatures();
if (mPaused && !force_update)
@@ -861,11 +867,12 @@ void LLMotionController::updateMotions(bool force_update)
{
// update additive motions
updateAdditiveMotions();
+
resetJointSignatures();
-
+
// update all regular motions
updateRegularMotions();
-
+
if (use_quantum)
{
mPoseBlender.blendAndCache(TRUE);
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index e295e3c621..8276ec836a 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -269,6 +269,7 @@ namespace
virtual LLSD::UUID asUUID() const { return LLUUID(mValue); }
virtual LLSD::Date asDate() const { return LLDate(mValue); }
virtual LLSD::URI asURI() const { return LLURI(mValue); }
+ virtual int size() const { return mValue.size(); }
};
LLSD::Integer ImplString::asInteger() const
diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h
index f4c43bac61..ed9284d2c5 100644
--- a/indra/llcommon/llstrider.h
+++ b/indra/llcommon/llstrider.h
@@ -44,6 +44,15 @@ public:
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
+ LLStrider<Object> operator+(const S32& index)
+ {
+ LLStrider<Object> ret;
+ ret.mBytep = mBytep + mSkip*index;
+ ret.mSkip = mSkip;
+
+ return ret;
+ }
+
void skip(const U32 index) { mBytep += mSkip*index;}
U32 getSkip() const { return mSkip; }
Object* get() { return mObjectp; }
@@ -51,6 +60,7 @@ public:
Object& operator *() { return *mObjectp; }
Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
+
Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
};
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 1b11e83b4a..6c768863a6 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -31,7 +31,6 @@
#include "v3math.h"
#include "llvector4a.h"
#include <vector>
-#include <set>
#define OCT_ERRS LL_WARNS("OctreeErrors")
@@ -79,11 +78,13 @@ public:
typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
- typedef typename std::set<LLPointer<T> > element_list;
- typedef typename element_list::iterator element_iter;
- typedef typename element_list::const_iterator const_element_iter;
+ typedef LLPointer<T>* element_list;
+ typedef LLPointer<T>* element_iter;
+ typedef const LLPointer<T>* const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
- typedef typename std::vector<LLOctreeNode<T>* > child_list;
+ typedef LLOctreeNode<T>** child_list;
+ typedef LLOctreeNode<T>** child_iter;
+
typedef LLTreeNode<T> BaseType;
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeListener<T> oct_listener;
@@ -105,6 +106,9 @@ public:
: mParent((oct_node*)parent),
mOctant(octant)
{
+ mData = NULL;
+ mDataEnd = NULL;
+
mCenter = center;
mSize = size;
@@ -123,6 +127,16 @@ public:
{
BaseType::destroyListeners();
+ for (U32 i = 0; i < mElementCount; ++i)
+ {
+ mData[i]->setBinIndex(-1);
+ mData[i] = NULL;
+ }
+
+ free(mData);
+ mData = NULL;
+ mDataEnd = NULL;
+
for (U32 i = 0; i < getChildCount(); i++)
{
delete getChild(i);
@@ -219,12 +233,17 @@ public:
}
void accept(oct_traveler* visitor) { visitor->visit(this); }
- virtual bool isLeaf() const { return mChild.empty(); }
+ virtual bool isLeaf() const { return mChildCount == 0; }
U32 getElementCount() const { return mElementCount; }
+ bool isEmpty() const { return mElementCount == 0; }
element_list& getData() { return mData; }
const element_list& getData() const { return mData; }
-
+ element_iter getDataBegin() { return mData; }
+ element_iter getDataEnd() { return mDataEnd; }
+ const_element_iter getDataBegin() const { return mData; }
+ const_element_iter getDataEnd() const { return mDataEnd; }
+
U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; }
const oct_node* getChild(U32 index) const { return mChild[index]; }
@@ -289,7 +308,7 @@ public:
virtual bool insert(T* data)
{
- if (data == NULL)
+ if (data == NULL || data->getBinIndex() != -1)
{
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl;
return false;
@@ -302,13 +321,16 @@ public:
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
- //if this is a redundant insertion, error out (should never happen)
- llassert(mData.find(data) == mData.end());
+ mElementCount++;
+ mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
- mData.insert(data);
- BaseType::insert(data);
+ //avoid unref on uninitialized memory
+ memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
- mElementCount = mData.size();
+ mData[mElementCount-1] = data;
+ mDataEnd = mData + mElementCount;
+ data->setBinIndex(mElementCount-1);
+ BaseType::insert(data);
return true;
}
else
@@ -342,10 +364,16 @@ public:
if( lt == 0x7 )
{
- mData.insert(data);
- BaseType::insert(data);
+ mElementCount++;
+ mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
+
+ //avoid unref on uninitialized memory
+ memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
- mElementCount = mData.size();
+ mData[mElementCount-1] = data;
+ mDataEnd = mData + mElementCount;
+ data->setBinIndex(mElementCount-1);
+ BaseType::insert(data);
return true;
}
@@ -394,23 +422,59 @@ public:
return false;
}
+ void _remove(T* data, S32 i)
+ { //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
+
+ mElementCount--;
+ data->setBinIndex(-1);
+
+ if (mElementCount > 0)
+ {
+ if (mElementCount != i)
+ {
+ mData[i] = mData[mElementCount]; //might unref data, do not access data after this point
+ mData[i]->setBinIndex(i);
+ }
+
+ mData[mElementCount] = NULL; //needed for unref
+ mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
+ mDataEnd = mData+mElementCount;
+ }
+ else
+ {
+ mData[0] = NULL; //needed for unref
+ free(mData);
+ mData = NULL;
+ mDataEnd = NULL;
+ }
+
+ notifyRemoval(data);
+ checkAlive();
+ }
+
bool remove(T* data)
{
- if (mData.find(data) != mData.end())
- { //we have data
- mData.erase(data);
- mElementCount = mData.size();
- notifyRemoval(data);
- checkAlive();
- return true;
- }
- else if (isInside(data))
+ S32 i = data->getBinIndex();
+
+ if (i >= 0 && i < mElementCount)
+ {
+ if (mData[i] == data)
+ { //found it
+ _remove(data, i);
+ llassert(data->getBinIndex() == -1);
+ return true;
+ }
+ }
+
+ if (isInside(data))
{
oct_node* dest = getNodeAt(data);
if (dest != this)
{
- return dest->remove(data);
+ bool ret = dest->remove(data);
+ llassert(data->getBinIndex() == -1);
+ return ret;
}
}
@@ -429,19 +493,20 @@ public:
//node is now root
llwarns << "!!! OCTREE REMOVING FACE BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl;
node->removeByAddress(data);
+ llassert(data->getBinIndex() == -1);
return true;
}
void removeByAddress(T* data)
{
- if (mData.find(data) != mData.end())
+ for (U32 i = 0; i < mElementCount; ++i)
{
- mData.erase(data);
- mElementCount = mData.size();
- notifyRemoval(data);
- llwarns << "FOUND!" << llendl;
- checkAlive();
- return;
+ if (mData[i] == data)
+ { //we have data
+ _remove(data, i);
+ llwarns << "FOUND!" << llendl;
+ return;
+ }
}
for (U32 i = 0; i < getChildCount(); i++)
@@ -453,8 +518,8 @@ public:
void clearChildren()
{
- mChild.clear();
mChildCount = 0;
+
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
}
@@ -516,7 +581,7 @@ public:
mChildMap[child->getOctant()] = mChildCount;
- mChild.push_back(child);
+ mChild[mChildCount] = child;
++mChildCount;
child->setParent(this);
@@ -543,9 +608,12 @@ public:
mChild[index]->destroy();
delete mChild[index];
}
- mChild.erase(mChild.begin() + index);
+
--mChildCount;
+ mChild[index] = mChild[mChildCount];
+
+
//rebuild child map
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
@@ -601,11 +669,12 @@ protected:
oct_node* mParent;
U8 mOctant;
- child_list mChild;
+ LLOctreeNode<T>* mChild[8];
U8 mChildMap[8];
U32 mChildCount;
element_list mData;
+ element_iter mDataEnd;
U32 mElementCount;
};
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index cc9744756f..06ac0aa1f6 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -328,16 +328,16 @@ public:
LLVector4a& min = node->mExtents[0];
LLVector4a& max = node->mExtents[1];
- if (!branch->getData().empty())
+ if (!branch->isEmpty())
{ //node has data, find AABB that binds data set
- const LLVolumeTriangle* tri = *(branch->getData().begin());
+ const LLVolumeTriangle* tri = *(branch->getDataBegin());
//initialize min/max to first available vertex
min = *(tri->mV[0]);
max = *(tri->mV[0]);
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
- branch->getData().begin(); iter != branch->getData().end(); ++iter)
+ branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
{ //for each triangle in node
//stretch by triangles in node
@@ -352,7 +352,7 @@ public:
max.setMax(max, *tri->mV[2]);
}
}
- else if (!branch->getChildren().empty())
+ else if (!branch->isLeaf())
{ //no data, but child nodes exist
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0);
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 76cf9de613..2e6f9e2f71 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -54,6 +54,7 @@ class LLVolumeTriangle;
#include "llstrider.h"
#include "v4coloru.h"
#include "llrefcount.h"
+#include "llpointer.h"
#include "llfile.h"
//============================================================================
@@ -919,6 +920,10 @@ public:
LLVector2* mTexCoords;
U16* mIndices;
+ //vertex buffer filled in by LLFace to cache this volume face geometry in vram
+ // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer)
+ mutable LLPointer<LLRefCount> mVertexBuffer;
+
std::vector<S32> mEdge;
//list of skin weights for rigged volumes
diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp
index b5a935c2b5..cc83cb7235 100644
--- a/indra/llmath/llvolumeoctree.cpp
+++ b/indra/llmath/llvolumeoctree.cpp
@@ -131,7 +131,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node)
{
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
- node->getData().begin(); iter != node->getData().end(); ++iter)
+ node->getDataBegin(); iter != node->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
@@ -236,8 +236,8 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
//children fit, check data
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin();
- iter != branch->getData().end(); ++iter)
+ for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ iter != branch->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h
index 688d91dc40..ed54fe0835 100644
--- a/indra/llmath/llvolumeoctree.h
+++ b/indra/llmath/llvolumeoctree.h
@@ -39,7 +39,7 @@ class LLVolumeTriangle : public LLRefCount
public:
LLVolumeTriangle()
{
-
+ mBinIndex = -1;
}
LLVolumeTriangle(const LLVolumeTriangle& rhs)
@@ -64,9 +64,16 @@ public:
U16 mIndex[3];
F32 mRadius;
+ mutable S32 mBinIndex;
+
virtual const LLVector4a& getPositionGroup() const;
virtual const F32& getBinRadius() const;
+
+ S32 getBinIndex() const { return mBinIndex; }
+ void setBinIndex(S32 idx) const { mBinIndex = idx; }
+
+
};
class LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index b93d429feb..5161ee6291 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -548,6 +548,7 @@ LLCurl::Multi::Multi(F32 idle_time_out)
mErrorCount(0),
mState(STATE_READY),
mDead(FALSE),
+ mValid(TRUE),
mMutexp(NULL),
mDeletionMutexp(NULL),
mEasyMutexp(NULL)
@@ -583,22 +584,33 @@ LLCurl::Multi::Multi(F32 idle_time_out)
LLCurl::Multi::~Multi()
{
- cleanup() ;
+ cleanup(true) ;
+
+ delete mDeletionMutexp ;
+ mDeletionMutexp = NULL ;
}
-void LLCurl::Multi::cleanup()
+void LLCurl::Multi::cleanup(bool deleted)
{
if(!mCurlMultiHandle)
{
return ; //nothing to clean.
}
+ llassert_always(deleted || !mValid) ;
+ LLMutexLock lock(mDeletionMutexp);
+
// Clean up active
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
iter != mEasyActiveList.end(); ++iter)
{
Easy* easy = *iter;
check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
+
+ if(deleted)
+ {
+ easy->mResponder = NULL ; //avoid triggering mResponder.
+ }
delete easy;
}
mEasyActiveList.clear();
@@ -610,11 +622,9 @@ void LLCurl::Multi::cleanup()
check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
mCurlMultiHandle = NULL ;
-
+
delete mMutexp ;
mMutexp = NULL ;
- delete mDeletionMutexp ;
- mDeletionMutexp = NULL ;
delete mEasyMutexp ;
mEasyMutexp = NULL ;
@@ -644,10 +654,20 @@ void LLCurl::Multi::unlock()
void LLCurl::Multi::markDead()
{
- LLMutexLock lock(mDeletionMutexp) ;
+ {
+ LLMutexLock lock(mDeletionMutexp) ;
- mDead = TRUE ;
- LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+ if(mCurlMultiHandle != NULL)
+ {
+ mDead = TRUE ;
+ LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
+
+ return;
+ }
+ }
+
+ //not valid, delete it.
+ delete this;
}
void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
@@ -741,10 +761,14 @@ bool LLCurl::Multi::doPerform()
setState(STATE_COMPLETED) ;
mIdleTimer.reset() ;
}
- else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
+ else if(!mValid && mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
{
dead = true ;
}
+ else if(mValid && mIdleTimer.getElapsedTimeF32() > mIdleTimeOut - 1.f) //idle for too long, mark it invalid.
+ {
+ mValid = FALSE ;
+ }
return dead ;
}
@@ -966,15 +990,8 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi)
return ;
}
- if(multi->isValid())
- {
multi->markDead() ;
}
- else
- {
- deleteMulti(multi) ;
- }
-}
//private
bool LLCurlThread::doMultiPerform(LLCurl::Multi* multi)
@@ -992,6 +1009,10 @@ void LLCurlThread::deleteMulti(LLCurl::Multi* multi)
void LLCurlThread::cleanupMulti(LLCurl::Multi* multi)
{
multi->cleanup() ;
+ if(multi->isDead()) //check if marked dead during cleaning up.
+ {
+ deleteMulti(multi) ;
+ }
}
//------------------------------------------------------------
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index fd664c0fa1..d6a7714d4c 100644
--- a/indra/llmessage/llcurl.h
+++ b/indra/llmessage/llcurl.h
@@ -304,7 +304,7 @@ public:
ePerformState getState() ;
bool isCompleted() ;
- bool isValid() {return mCurlMultiHandle != NULL ;}
+ bool isValid() {return mCurlMultiHandle != NULL && mValid;}
bool isDead() {return mDead;}
bool waitToComplete() ;
@@ -318,7 +318,7 @@ public:
private:
void easyFree(LLCurl::Easy*);
- void cleanup() ;
+ void cleanup(bool deleted = false) ;
CURLM* mCurlMultiHandle;
@@ -333,6 +333,7 @@ private:
ePerformState mState;
BOOL mDead ;
+ BOOL mValid ;
LLMutex* mMutexp ;
LLMutex* mDeletionMutexp ;
LLMutex* mEasyMutexp ;
diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp
index 3d8ca2ad9f..a6fccd2a56 100644
--- a/indra/llmessage/llsdmessagereader.cpp
+++ b/indra/llmessage/llsdmessagereader.cpp
@@ -276,7 +276,7 @@ S32 getElementSize(const LLSD& llsd)
case LLSD::TypeReal:
return sizeof(F64);
case LLSD::TypeString:
- return llsd.asString().size();
+ return llsd.size();
case LLSD::TypeUUID:
return sizeof(LLUUID);
case LLSD::TypeDate:
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 45a3b18179..362452d837 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -81,7 +81,7 @@ void LLCubeMap::initGL()
{
U32 texname = 0;
- LLImageGL::generateTextures(1, &texname);
+ LLImageGL::generateTextures(LLTexUnit::TT_CUBE_MAP, GL_RGB8, 1, &texname);
for (int i = 0; i < 6; i++)
{
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 197bc2b422..0b56b3889c 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -94,6 +94,10 @@ void APIENTRY gl_debug_callback(GLenum source,
llwarns << "Severity: " << std::hex << severity << llendl;
llwarns << "Message: " << message << llendl;
llwarns << "-----------------------" << llendl;
+ if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
+ {
+ llerrs << "Halting on GL Error" << llendl;
+ }
}
#endif
@@ -245,6 +249,12 @@ PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;
PFNGLSAMPLEMASKIPROC glSampleMaski = NULL;
+//transform feedback (4.0 core)
+PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback = NULL;
+PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback = NULL;
+PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings = NULL;
+PFNGLBINDBUFFERRANGEPROC glBindBufferRange = NULL;
+
//GL_ARB_debug_output
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
@@ -417,6 +427,7 @@ LLGLManager::LLGLManager() :
mHasDrawBuffers(FALSE),
mHasTextureRectangle(FALSE),
mHasTextureMultisample(FALSE),
+ mHasTransformFeedback(FALSE),
mMaxSampleMaskWords(0),
mMaxColorTextureSamples(0),
mMaxDepthTextureSamples(0),
@@ -554,7 +565,8 @@ bool LLGLManager::initGL()
parse_gl_version( &mDriverVersionMajor,
&mDriverVersionMinor,
&mDriverVersionRelease,
- &mDriverVersionVendorString );
+ &mDriverVersionVendorString,
+ &mGLVersionString);
mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
@@ -572,6 +584,15 @@ bool LLGLManager::initGL()
#endif
}
+ if (mGLVersion >= 2.1f && LLImageGL::sCompressTextures)
+ { //use texture compression
+ glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
+ }
+ else
+ { //GL version is < 3.0, always disable texture compression
+ LLImageGL::sCompressTextures = false;
+ }
+
// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
// from being recognized as ATI.
if (mGLVendor.substr(0,4) == "ATI ")
@@ -592,11 +613,8 @@ bool LLGLManager::initGL()
#endif // LL_WINDOWS
#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
- // release 7277 is a point at which we verify that ATI OpenGL
- // drivers get pretty stable with SL, ~Catalyst 8.2,
- // for both Win32 and Linux.
- if (mDriverVersionRelease < 7277 &&
- mDriverVersionRelease != 0) // 0 == Undetectable driver version - these get to pretend to be new ATI drivers, though that decision may be revisited.
+ // count any pre OpenGL 3.0 implementation as an old driver
+ if (mGLVersion < 3.f)
{
mATIOldDriver = TRUE;
}
@@ -735,6 +753,11 @@ bool LLGLManager::initGL()
}
#endif
+ if (mIsIntel && mGLVersion <= 3.f)
+ { //never try to use framebuffer objects on older intel drivers (crashy)
+ mHasFramebufferObject = FALSE;
+ }
+
if (mHasFramebufferObject)
{
glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
@@ -923,7 +946,6 @@ void LLGLManager::initExtensions()
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
- mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
glh_init_extensions("GL_ARB_texture_cube_map");
@@ -948,11 +970,14 @@ void LLGLManager::initExtensions()
ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
#endif
+ mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
+
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
+ mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE;
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
#endif
@@ -1192,7 +1217,14 @@ void LLGLManager::initExtensions()
glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) GLH_EXT_GET_PROC_ADDRESS("glTexImage3DMultisample");
glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
- }
+ }
+ if (mHasTransformFeedback)
+ {
+ glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glBeginTransformFeedback");
+ glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) GLH_EXT_GET_PROC_ADDRESS("glEndTransformFeedback");
+ glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) GLH_EXT_GET_PROC_ADDRESS("glTransformFeedbackVaryings");
+ glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) GLH_EXT_GET_PROC_ADDRESS("glBindBufferRange");
+ }
if (mHasDebugOutput)
{
glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
@@ -1897,7 +1929,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
glClientActiveTextureARB(GL_TEXTURE0_ARB);
gGL.getTexUnit(0)->activate();
- if (gGLManager.mHasVertexShader)
+ if (gGLManager.mHasVertexShader && LLGLSLShader::sNoFixedFunction)
{ //make sure vertex attribs are all disabled
GLint count;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &count);
@@ -1949,6 +1981,7 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
case GL_COLOR_MATERIAL:
case GL_FOG:
case GL_LINE_STIPPLE:
+ case GL_POLYGON_STIPPLE:
mState = 0;
break;
}
@@ -2037,7 +2070,7 @@ void LLGLManager::initGLStates()
////////////////////////////////////////////////////////////////////////////////
-void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )
+void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string )
{
// GL_VERSION returns a null-terminated string with the format:
// <major>.<minor>[.<release>] [<vendor specific>]
@@ -2053,6 +2086,8 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
return;
}
+ version_string->assign(version);
+
std::string ver_copy( version );
S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
S32 i = 0;
@@ -2414,3 +2449,65 @@ LLGLSquashToFarClip::~LLGLSquashToFarClip()
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
+
+
+LLGLSyncFence::LLGLSyncFence()
+{
+#ifdef GL_ARB_sync
+ mSync = 0;
+#endif
+}
+
+LLGLSyncFence::~LLGLSyncFence()
+{
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ glDeleteSync(mSync);
+ }
+#endif
+}
+
+void LLGLSyncFence::placeFence()
+{
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ glDeleteSync(mSync);
+ }
+ mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+#endif
+}
+
+bool LLGLSyncFence::isCompleted()
+{
+ bool ret = true;
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ GLenum status = glClientWaitSync(mSync, 0, 1);
+ if (status == GL_TIMEOUT_EXPIRED)
+ {
+ ret = false;
+ }
+ }
+#endif
+ return ret;
+}
+
+void LLGLSyncFence::wait()
+{
+#ifdef GL_ARB_sync
+ if (mSync)
+ {
+ while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
+ { //track the number of times we've waited here
+ static S32 waits = 0;
+ waits++;
+ }
+ }
+#endif
+}
+
+
+
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 5a33c98708..964495a3ab 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -104,6 +104,7 @@ public:
BOOL mHasDepthClamp;
BOOL mHasTextureRectangle;
BOOL mHasTextureMultisample;
+ BOOL mHasTransformFeedback;
S32 mMaxSampleMaskWords;
S32 mMaxColorTextureSamples;
S32 mMaxDepthTextureSamples;
@@ -141,6 +142,7 @@ public:
S32 mGLSLVersionMajor;
S32 mGLSLVersionMinor;
std::string mDriverVersionVendorString;
+ std::string mGLVersionString;
S32 mVRAM; // VRAM in MB
S32 mGLMaxVertexRange;
@@ -417,13 +419,38 @@ public:
virtual void updateGL() = 0;
};
+const U32 FENCE_WAIT_TIME_NANOSECONDS = 1000; //1 ms
+
+class LLGLFence
+{
+public:
+ virtual void placeFence() = 0;
+ virtual bool isCompleted() = 0;
+ virtual void wait() = 0;
+};
+
+class LLGLSyncFence : public LLGLFence
+{
+public:
+#ifdef GL_ARB_sync
+ GLsync mSync;
+#endif
+
+ LLGLSyncFence();
+ virtual ~LLGLSyncFence();
+
+ void placeFence();
+ bool isCompleted();
+ void wait();
+};
+
extern LLMatrix4 gGLObliqueProjectionInverse;
#include "llglstates.h"
void init_glstates();
-void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
+void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string );
extern BOOL gClothRipple;
extern BOOL gHeadlessClient;
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index d61ec707f0..a0727b8686 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -528,6 +528,13 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
+//transform feedback (4.0 core)
+extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
+extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
+extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
+extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+
+
#elif LL_WINDOWS
//----------------------------------------------------------------------------
// LL_WINDOWS
@@ -759,6 +766,12 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
+//transform feedback (4.0 core)
+extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback;
+extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback;
+extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings;
+extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange;
+
//GL_ARB_debug_output
extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 4b7e639aed..7cbf39096e 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -129,7 +129,9 @@ void LLGLSLShader::unload()
}
BOOL LLGLSLShader::createShader(vector<string> * attributes,
- vector<string> * uniforms)
+ vector<string> * uniforms,
+ U32 varying_count,
+ const char** varyings)
{
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
@@ -172,6 +174,13 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
}
+#ifdef GL_INTERLEAVED_ATTRIBS
+ if (varying_count > 0 && varyings)
+ {
+ glTransformFeedbackVaryings(mProgramObject, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
+ }
+#endif
+
// Map attributes and uniforms
if (success)
{
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 7873fe3c4e..5c68cb46eb 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -76,7 +76,9 @@ public:
void unload();
BOOL createShader(std::vector<std::string> * attributes,
- std::vector<std::string> * uniforms);
+ std::vector<std::string> * uniforms,
+ U32 varying_count = 0,
+ const char** varyings = NULL);
BOOL attachObject(std::string object);
void attachObject(GLhandleARB object);
void attachObjects(GLhandleARB* objects = NULL, S32 count = 0);
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 78591ddd38..fb03b3f956 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -42,6 +42,10 @@
//----------------------------------------------------------------------------
const F32 MIN_TEXTURE_LIFETIME = 10.f;
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i);
+
//statics
LLGLuint LLImageGL::sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS] = { 0 };
@@ -51,12 +55,14 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
S32 LLImageGL::sCurBoundTextureMemory = 0;
S32 LLImageGL::sCount = 0;
-std::list<U32> LLImageGL::sDeadTextureList;
+LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
+U32 LLImageGL::sCurTexName = 1;
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
F32 LLImageGL::sLastFrameTime = 0.f;
BOOL LLImageGL::sAllowReadBackRaw = FALSE ;
LLImageGL* LLImageGL::sDefaultGLTexture = NULL ;
+bool LLImageGL::sCompressTextures = false;
std::set<LLImageGL*> LLImageGL::sImageList;
@@ -279,9 +285,11 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat)
//----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_STATS("Image Stats");
// static
void LLImageGL::updateStats(F32 current_time)
{
+ LLFastTimer t(FTM_IMAGE_UPDATE_STATS);
sLastFrameTime = current_time;
sBoundTextureMemoryInBytes = sCurBoundTextureMemory;
sCurBoundTextureMemory = 0;
@@ -477,10 +485,13 @@ void LLImageGL::init(BOOL usemipmaps)
mDiscardLevelInAtlas = -1 ;
mTexelsInAtlas = 0 ;
mTexelsInGLTexture = 0 ;
+
+ mAllowCompression = true;
mTarget = GL_TEXTURE_2D;
mBindTarget = LLTexUnit::TT_TEXTURE;
mHasMipMaps = false;
+ mMipLevels = -1;
mIsResident = 0;
@@ -671,8 +682,24 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
is_compressed = true;
}
+
+
+ if (mUseMipMaps)
+ {
+ //set has mip maps to true before binding image so tex parameters get set properly
+ gGL.getTexUnit(0)->unbind(mBindTarget);
+ mHasMipMaps = true;
+ mTexOptionsDirty = true;
+ setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ }
+ else
+ {
+ mHasMipMaps = false;
+ }
+
llverify(gGL.getTexUnit(0)->bind(this));
+
if (mUseMipMaps)
{
if (data_hasmips)
@@ -685,6 +712,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
S32 w = getWidth(d);
S32 h = getHeight(d);
S32 gl_level = d-mCurrentDiscardLevel;
+
+ mMipLevels = llmax(mMipLevels, gl_level);
+
if (d > mCurrentDiscardLevel)
{
data_in -= dataFormatBytes(mFormatPrimary, w, h); // see above comment
@@ -705,7 +735,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in);
+ LLImageGL::setManualImage(mTarget, gl_level, mFormatInternal, w, h, mFormatPrimary, GL_UNSIGNED_BYTE, (GLvoid*)data_in, mAllowCompression);
if (gl_level == 0)
{
analyzeAlpha(data_in, w, h);
@@ -727,10 +757,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
if (mAutoGenMips)
{
- if (!gGLManager.mHasFramebufferObject)
- {
- glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
- }
stop_glerror();
{
// LLFastTimer t2(FTM_TEMP4);
@@ -744,10 +770,15 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
S32 w = getWidth(mCurrentDiscardLevel);
S32 h = getHeight(mCurrentDiscardLevel);
+ mMipLevels = wpo2(llmax(w, h));
+
+ //use legacy mipmap generation mode
+ glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
+
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
- data_in);
+ data_in, mAllowCompression);
analyzeAlpha(data_in, w, h);
stop_glerror();
@@ -759,16 +790,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
}
-
- if (gGLManager.mHasFramebufferObject)
- {
- glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget));
- }
}
else
{
// Create mips by hand
- // about 30% faster than autogen on ATI 9800, 50% slower on nVidia 4800
// ~4x faster than gluBuild2DMipmaps
S32 width = getWidth(mCurrentDiscardLevel);
S32 height = getHeight(mCurrentDiscardLevel);
@@ -778,6 +803,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
const U8* cur_mip_data = 0;
S32 prev_mip_size = 0;
S32 cur_mip_size = 0;
+
+ mMipLevels = nummips;
+
for (int m=0; m<nummips; m++)
{
if (m==0)
@@ -805,7 +833,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
- LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data);
+ LLImageGL::setManualImage(mTarget, m, mFormatInternal, w, h, mFormatPrimary, mFormatType, cur_mip_data, mAllowCompression);
if (m == 0)
{
analyzeAlpha(data_in, w, h);
@@ -842,10 +870,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl;
}
- mHasMipMaps = true;
}
else
{
+ mMipLevels = 0;
S32 w = getWidth();
S32 h = getHeight();
if (is_compressed)
@@ -863,7 +891,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
LLImageGL::setManualImage(mTarget, 0, mFormatInternal, w, h,
- mFormatPrimary, mFormatType, (GLvoid *)data_in);
+ mFormatPrimary, mFormatType, (GLvoid *)data_in, mAllowCompression);
analyzeAlpha(data_in, w, h);
updatePickMask(w, h, data_in);
@@ -877,7 +905,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
}
- mHasMipMaps = false;
}
stop_glerror();
mGLTextureCreated = true;
@@ -1090,27 +1117,69 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
}
// static
-void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
+void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
{
- glGenTextures(numTextures, (GLuint*)textures);
+ bool empty = true;
+
+ dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
+
+ if (iter != sDeadTextureList[type].end())
+ {
+ empty = iter->second.empty();
+ }
+
+ for (S32 i = 0; i < numTextures; ++i)
+ {
+ if (!empty)
+ {
+ textures[i] = iter->second.front();
+ iter->second.pop_front();
+ empty = iter->second.empty();
+ }
+ else
+ {
+ textures[i] = sCurTexName++;
+ }
+ }
}
// static
-void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
+void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate)
{
- for (S32 i = 0; i < numTextures; i++)
+ if (gGLManager.mInited)
{
- sDeadTextureList.push_back(textures[i]);
- }
+ if (format == 0 || type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
+ { //unknown internal format or unknown number of mip levels, not safe to reuse
+ glDeleteTextures(numTextures, textures);
+ }
+ else
+ {
+ for (S32 i = 0; i < numTextures; ++i)
+ { //remove texture from VRAM by setting its size to zero
+ for (S32 j = 0; j <= mip_levels; j++)
+ {
+ gGL.getTexUnit(0)->bindManual(type, textures[i]);
- if (immediate)
+ glTexImage2D(LLTexUnit::getInternalType(type), j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+
+ llassert(std::find(sDeadTextureList[type][format].begin(),
+ sDeadTextureList[type][format].end(), textures[i]) ==
+ sDeadTextureList[type][format].end());
+
+ sDeadTextureList[type][format].push_back(textures[i]);
+ }
+ }
+ }
+
+ /*if (immediate)
{
LLImageGL::deleteDeadTextures();
- }
+ }*/
}
// static
-void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
+void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
{
bool use_scratch = false;
U32* scratch = NULL;
@@ -1173,6 +1242,36 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
}
}
+ if (LLImageGL::sCompressTextures && allow_compression)
+ {
+ switch (intformat)
+ {
+ case GL_RGB:
+ case GL_RGB8:
+ intformat = GL_COMPRESSED_RGB;
+ break;
+ case GL_RGBA:
+ case GL_RGBA8:
+ intformat = GL_COMPRESSED_RGBA;
+ break;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE8:
+ intformat = GL_COMPRESSED_LUMINANCE;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE8_ALPHA8:
+ intformat = GL_COMPRESSED_LUMINANCE_ALPHA;
+ break;
+ case GL_ALPHA:
+ case GL_ALPHA8:
+ intformat = GL_COMPRESSED_ALPHA;
+ break;
+ default:
+ llwarns << "Could not compress format: " << std::hex << intformat << llendl;
+ break;
+ }
+ }
+
stop_glerror();
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
stop_glerror();
@@ -1201,10 +1300,11 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
- glDeleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;
}
- glGenTextures(1, (GLuint*)&mTexName);
+
+ LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
stop_glerror();
if (!mTexName)
{
@@ -1317,7 +1417,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
else
{
- LLImageGL::generateTextures(1, &mTexName);
+ LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
stop_glerror();
{
llverify(gGL.getTexUnit(0)->bind(this));
@@ -1367,7 +1467,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
decTextureCounter(mTextureMemory, mComponents, mCategory) ;
}
- LLImageGL::deleteTextures(1, &old_name);
+ LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name);
stop_glerror();
}
@@ -1500,7 +1600,7 @@ void LLImageGL::deleteDeadTextures()
{
bool reset = false;
- while (!sDeadTextureList.empty())
+ /*while (!sDeadTextureList.empty())
{
GLuint tex = sDeadTextureList.front();
sDeadTextureList.pop_front();
@@ -1522,7 +1622,7 @@ void LLImageGL::deleteDeadTextures()
glDeleteTextures(1, &tex);
stop_glerror();
- }
+ }*/
if (reset)
{
@@ -1544,7 +1644,7 @@ void LLImageGL::destroyGLTexture()
mTextureMemory = 0;
}
- LLImageGL::deleteTextures(1, &mTexName);
+ LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &mTexName);
mTexName = 0;
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mGLTextureCreated = FALSE ;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 2cfb15b0d9..0d5785d3bf 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -45,8 +45,16 @@ class LLImageGL : public LLRefCount
{
friend class LLTexUnit;
public:
- static std::list<U32> sDeadTextureList;
+ static U32 sCurTexName;
+ //previously used but now available texture names
+ // sDeadTextureList[<usage>][<internal format>]
+ typedef std::map<U32, std::list<U32> > dead_texturelist_t;
+ static dead_texturelist_t sDeadTextureList[LLTexUnit::TT_NONE];
+
+ // These 2 functions replace glGenTextures() and glDeleteTextures()
+ static void generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures);
+ static void deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate = false);
static void deleteDeadTextures();
// Size calculation
@@ -94,12 +102,9 @@ public:
void setSize(S32 width, S32 height, S32 ncomponents);
void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
+ void setAllowCompression(bool allow) { mAllowCompression = allow; }
- // These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D()
- // for tracking purposes and will be deprecated in the future
- static void generateTextures(S32 numTextures, U32 *textures);
- static void deleteTextures(S32 numTextures, U32 *textures, bool immediate = false);
- static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels);
+ static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression = true);
BOOL createGLTexture() ;
BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE,
@@ -209,11 +214,14 @@ private:
U32 mTexelsInAtlas ;
U32 mTexelsInGLTexture;
+ bool mAllowCompression;
+
protected:
LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps)
LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps)
bool mHasMipMaps;
-
+ S32 mMipLevels;
+
LLGLboolean mIsResident;
S8 mComponents;
@@ -246,7 +254,7 @@ public:
static BOOL sGlobalUseAnisotropic;
static LLImageGL* sDefaultGLTexture ;
static BOOL sAutomatedTest;
-
+ static bool sCompressTextures; //use GL texture compression
#if DEBUG_MISS
BOOL mMissed; // Missed on last bind?
BOOL getMissed() const { return mMissed; };
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index b0ddacbb05..b45ff1a6b7 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -416,12 +416,14 @@ void LLTexUnit::unbind(eTextureType type)
if (mIndex < 0) return;
+ //always flush and activate for consistency
+ // some code paths assume unbind always flushes and sets the active texture
+ gGL.flush();
+ activate();
+
// Disabled caching of binding state.
if (mCurrTexType == type)
{
- gGL.flush();
-
- activate();
mCurrTexture = 0;
if (LLGLSLShader::sNoFixedFunction && type == LLTexUnit::TT_TEXTURE)
{
@@ -472,11 +474,25 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio
}
else if (option >= TFO_BILINEAR)
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ if (mHasMipMaps)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
}
else
{
- glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ if (mHasMipMaps)
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ }
+ else
+ {
+ glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
}
if (gGLManager.mHasAnisotropic)
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index ef2a7395da..cc5c232380 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -55,7 +55,6 @@ bool LLRenderTarget::sUseFBO = false;
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
- mTex(0),
mFBO(0),
mDepth(0),
mStencil(0),
@@ -70,6 +69,42 @@ LLRenderTarget::~LLRenderTarget()
release();
}
+void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
+{
+ //for accounting, get the number of pixels added/subtracted
+ S32 pix_diff = (resx*resy)-(mResX*mResY);
+
+ mResX = resx;
+ mResY = resy;
+
+ for (U32 i = 0; i < mTex.size(); ++i)
+ { //resize color attachments
+ gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
+ sBytesAllocated += pix_diff*4;
+ }
+
+ if (mDepth)
+ { //resize depth attachment
+ if (mStencil)
+ {
+ //use render buffers where stencil buffers are in play
+ glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ }
+ else
+ {
+ 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);
+ }
+
+ sBytesAllocated += pix_diff*4;
+ }
+}
+
+
bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
{
stop_glerror();
@@ -135,7 +170,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
}
U32 tex;
- LLImageGL::generateTextures(1, &tex);
+ LLImageGL::generateTextures(mUsage, color_fmt, 1, &tex);
gGL.getTexUnit(0)->bindManual(mUsage, tex);
stop_glerror();
@@ -143,7 +178,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
{
clear_glerror();
- LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Could not allocate color buffer for render target." << llendl;
@@ -193,6 +228,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
}
mTex.push_back(tex);
+ mInternalFormat.push_back(color_fmt);
if (gDebugGL)
{ //bind and unbind to validate target
@@ -217,13 +253,13 @@ bool LLRenderTarget::allocateDepth()
}
else
{
- LLImageGL::generateTextures(1, &mDepth);
+ LLImageGL::generateTextures(mUsage, GL_DEPTH_COMPONENT24, 1, &mDepth);
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
stop_glerror();
clear_glerror();
- LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
+ 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);
}
@@ -294,7 +330,7 @@ void LLRenderTarget::release()
}
else
{
- LLImageGL::deleteTextures(1, &mDepth, true);
+ LLImageGL::deleteTextures(mUsage, 0, 0, 1, &mDepth, true);
stop_glerror();
}
mDepth = 0;
@@ -326,8 +362,9 @@ void LLRenderTarget::release()
if (mTex.size() > 0)
{
sBytesAllocated -= mResX*mResY*4*mTex.size();
- LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
+ LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);
mTex.clear();
+ mInternalFormat.clear();
}
mResX = mResY = 0;
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 2735ab21c5..e1a51304f1 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -57,8 +57,6 @@
*/
-class LLMultisampleBuffer;
-
class LLRenderTarget
{
public:
@@ -74,6 +72,12 @@ public:
//multiple calls will release previously allocated resources
bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = false, S32 samples = 0);
+ //resize existing attachments to use new resolution and color format
+ // CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
+ // DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
+ // DO use for render targets that resize often and aren't likely to ruin someone's day if they break
+ void resize(U32 resx, U32 resy, U32 color_fmt);
+
//add color buffer attachment
//limit of 4 color attachments per render target
bool addColorAttachment(U32 color_fmt);
@@ -142,6 +146,7 @@ protected:
U32 mResX;
U32 mResY;
std::vector<U32> mTex;
+ std::vector<U32> mInternalFormat;
U32 mFBO;
U32 mDepth;
bool mStencil;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 7d384450e6..bf917d4474 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1026,6 +1026,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("size");
mReservedUniforms.push_back("falloff");
+ mReservedUniforms.push_back("box_center");
+ mReservedUniforms.push_back("box_size");
+
mReservedUniforms.push_back("minLuminance");
mReservedUniforms.push_back("maxExtractAlpha");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index e28bda6de2..aa669925ee 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -97,6 +97,8 @@ public:
LIGHT_CENTER,
LIGHT_SIZE,
LIGHT_FALLOFF,
+ BOX_CENTER,
+ BOX_SIZE,
GLOW_MIN_LUMINANCE,
GLOW_MAX_EXTRACT_ALPHA,
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 8b5503229f..0092df6587 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -49,6 +49,37 @@ U32 nhpo2(U32 v)
return r;
}
+//which power of 2 is i?
+//assumes i is a power of 2 > 0
+U32 wpo2(U32 i)
+{
+ llassert(i > 0);
+ llassert(nhpo2(i) == i);
+
+ U32 r = 0;
+
+ while (i >>= 1) ++r;
+
+ return r;
+}
+
+
+const U32 LL_VBO_BLOCK_SIZE = 2048;
+const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024;
+
+U32 vbo_block_size(U32 size)
+{ //what block size will fit size?
+ U32 mod = size % LL_VBO_BLOCK_SIZE;
+ return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod);
+}
+
+U32 vbo_block_index(U32 size)
+{
+ return vbo_block_size(size)/LL_VBO_BLOCK_SIZE;
+}
+
+const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE);
+
//============================================================================
@@ -57,7 +88,16 @@ LLVBOPool LLVertexBuffer::sStreamVBOPool(GL_STREAM_DRAW_ARB, GL_ARRAY_BUFFER_ARB
LLVBOPool LLVertexBuffer::sDynamicVBOPool(GL_DYNAMIC_DRAW_ARB, GL_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sStreamIBOPool(GL_STREAM_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_BUFFER_ARB);
+
U32 LLVBOPool::sBytesPooled = 0;
+U32 LLVBOPool::sIndexBytesPooled = 0;
+U32 LLVBOPool::sCurGLName = 1;
+
+std::list<U32> LLVertexBuffer::sAvailableVAOName;
+U32 LLVertexBuffer::sCurVAOName = 1;
+
+U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
+U32 LLVertexBuffer::sIndexCount = 0;
LLPrivateMemoryPool* LLVertexBuffer::sPrivatePoolp = NULL;
U32 LLVertexBuffer::sBindCount = 0;
@@ -74,99 +114,88 @@ U32 LLVertexBuffer::sLastMask = 0;
bool LLVertexBuffer::sVBOActive = false;
bool LLVertexBuffer::sIBOActive = false;
U32 LLVertexBuffer::sAllocatedBytes = 0;
+U32 LLVertexBuffer::sVertexCount = 0;
bool LLVertexBuffer::sMapped = false;
bool LLVertexBuffer::sUseStreamDraw = true;
bool LLVertexBuffer::sUseVAO = false;
bool LLVertexBuffer::sPreferStreamDraw = false;
-const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms
-class LLGLSyncFence : public LLGLFence
+U32 LLVBOPool::genBuffer()
{
-public:
-#ifdef GL_ARB_sync
- GLsync mSync;
-#endif
-
- LLGLSyncFence()
- {
-#ifdef GL_ARB_sync
- mSync = 0;
-#endif
- }
+ U32 ret = 0;
- virtual ~LLGLSyncFence()
+ if (mGLNamePool.empty())
{
-#ifdef GL_ARB_sync
- if (mSync)
- {
- glDeleteSync(mSync);
- }
-#endif
+ ret = sCurGLName++;
}
-
- void placeFence()
+ else
{
-#ifdef GL_ARB_sync
- if (mSync)
- {
- glDeleteSync(mSync);
- }
- mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-#endif
+ ret = mGLNamePool.front();
+ mGLNamePool.pop_front();
}
- void wait()
- {
-#ifdef GL_ARB_sync
- if (mSync)
- {
- while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED)
- { //track the number of times we've waited here
- static S32 waits = 0;
- waits++;
- }
- }
-#endif
- }
+ return ret;
+}
+void LLVBOPool::deleteBuffer(U32 name)
+{
+ if (gGLManager.mInited)
+ {
+ LLVertexBuffer::unbind();
-};
+ glBindBufferARB(mType, name);
+ glBufferDataARB(mType, 0, NULL, mUsage);
+ llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
-//which power of 2 is i?
-//assumes i is a power of 2 > 0
-U32 wpo2(U32 i)
-{
- llassert(i > 0);
- llassert(nhpo2(i) == i);
+ mGLNamePool.push_back(name);
- U32 r = 0;
+ glBindBufferARB(mType, 0);
+ }
+}
- while (i >>= 1) ++r;
- return r;
+LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
+: mUsage(vboUsage), mType(vboType)
+{
+ mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
+ std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
-volatile U8* LLVBOPool::allocate(U32& name, U32 size)
+volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
- llassert(nhpo2(size) == size);
+ llassert(vbo_block_size(size) == size);
+
+ volatile U8* ret = NULL;
- U32 i = wpo2(size);
+ U32 i = vbo_block_index(size);
if (mFreeList.size() <= i)
{
mFreeList.resize(i+1);
}
- volatile U8* ret = NULL;
-
- if (mFreeList[i].empty())
+ if (mFreeList[i].empty() || for_seed)
{
//make a new buffer
- glGenBuffersARB(1, &name);
+ name = genBuffer();
+
glBindBufferARB(mType, name);
- LLVertexBuffer::sAllocatedBytes += size;
+
+ if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
+ { //record this miss
+ mMissCount[i]++;
+ }
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ LLVertexBuffer::sAllocatedBytes += size;
+ }
+ else
+ {
+ LLVertexBuffer::sAllocatedIndexBytes += size;
+ }
if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB)
{
@@ -179,13 +208,39 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
}
glBindBufferARB(mType, 0);
+
+ if (for_seed)
+ { //put into pool for future use
+ llassert(mFreeList.size() > i);
+
+ Record rec;
+ rec.mGLName = name;
+ rec.mClientData = ret;
+
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled += size;
+ }
+ else
+ {
+ sIndexBytesPooled += size;
+ }
+ mFreeList[i].push_back(rec);
+ }
}
else
{
name = mFreeList[i].front().mGLName;
ret = mFreeList[i].front().mClientData;
- sBytesPooled -= size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ }
mFreeList[i].pop_front();
}
@@ -195,30 +250,49 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
{
- llassert(nhpo2(size) == size);
-
- U32 i = wpo2(size);
+ llassert(vbo_block_size(size) == size);
- llassert(mFreeList.size() > i);
+ deleteBuffer(name);
+ ll_aligned_free_16((U8*) buffer);
- Record rec;
- rec.mGLName = name;
- rec.mClientData = buffer;
-
- if (buffer == NULL)
+ if (mType == GL_ARRAY_BUFFER_ARB)
{
- glDeleteBuffersARB(1, &rec.mGLName);
+ LLVertexBuffer::sAllocatedBytes -= size;
}
else
{
- sBytesPooled += size;
- mFreeList[i].push_back(rec);
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
+ }
+}
+
+void LLVBOPool::seedPool()
+{
+ U32 dummy_name = 0;
+
+ if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
+ {
+ mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
+ }
+
+ for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
+ {
+ if (mMissCount[i] > mFreeList[i].size())
+ {
+ U32 size = i*LL_VBO_BLOCK_SIZE;
+
+ S32 count = mMissCount[i] - mFreeList[i].size();
+ for (U32 j = 0; j < count; ++j)
+ {
+ allocate(dummy_name, size, true);
+ }
+ }
}
}
+
void LLVBOPool::cleanup()
{
- U32 size = 1;
+ U32 size = LL_VBO_BLOCK_SIZE;
for (U32 i = 0; i < mFreeList.size(); ++i)
{
@@ -228,8 +302,8 @@ void LLVBOPool::cleanup()
{
Record& r = l.front();
- glDeleteBuffersARB(1, &r.mGLName);
-
+ deleteBuffer(r.mGLName);
+
if (r.mClientData)
{
ll_aligned_free_16((void*) r.mClientData);
@@ -237,12 +311,23 @@ void LLVBOPool::cleanup()
l.pop_front();
- LLVertexBuffer::sAllocatedBytes -= size;
- sBytesPooled -= size;
+ if (mType == GL_ARRAY_BUFFER_ARB)
+ {
+ sBytesPooled -= size;
+ LLVertexBuffer::sAllocatedBytes -= size;
+ }
+ else
+ {
+ sIndexBytesPooled -= size;
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
+ }
}
- size *= 2;
+ size += LL_VBO_BLOCK_SIZE;
}
+
+ //reset miss counts
+ std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
@@ -276,6 +361,41 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
GL_LINE_LOOP,
};
+//static
+U32 LLVertexBuffer::getVAOName()
+{
+ U32 ret = 0;
+
+ if (!sAvailableVAOName.empty())
+ {
+ ret = sAvailableVAOName.front();
+ sAvailableVAOName.pop_front();
+ }
+ else
+ {
+#ifdef GL_ARB_vertex_array_object
+ glGenVertexArrays(1, &ret);
+#endif
+ }
+
+ return ret;
+}
+
+//static
+void LLVertexBuffer::releaseVAOName(U32 name)
+{
+ sAvailableVAOName.push_back(name);
+}
+
+
+//static
+void LLVertexBuffer::seedPools()
+{
+ sStreamVBOPool.seedPool();
+ sDynamicVBOPool.seedPool();
+ sStreamIBOPool.seedPool();
+ sDynamicIBOPool.seedPool();
+}
//static
void LLVertexBuffer::setupClientArrays(U32 data_mask)
@@ -885,7 +1005,7 @@ LLVertexBuffer::~LLVertexBuffer()
if (mGLArray)
{
#if GL_ARB_vertex_array_object
- glDeleteVertexArrays(1, &mGLArray);
+ releaseVAOName(mGLArray);
#endif
}
@@ -898,6 +1018,9 @@ LLVertexBuffer::~LLVertexBuffer()
mFence = NULL;
+ sVertexCount -= mNumVerts;
+ sIndexCount -= mNumIndices;
+
llassert_always(!mMappedData && !mMappedIndexData);
};
@@ -929,7 +1052,7 @@ void LLVertexBuffer::waitFence() const
void LLVertexBuffer::genBuffer(U32 size)
{
- mSize = nhpo2(size);
+ mSize = vbo_block_size(size);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -945,7 +1068,7 @@ void LLVertexBuffer::genBuffer(U32 size)
void LLVertexBuffer::genIndices(U32 size)
{
- mIndicesSize = nhpo2(size);
+ mIndicesSize = vbo_block_size(size);
if (mUsage == GL_STREAM_DRAW_ARB)
{
@@ -1108,10 +1231,10 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
llassert(nverts >= 0);
- if (nverts >= 65535)
+ if (nverts > 65536)
{
llwarns << "Vertex buffer overflow!" << llendl;
- nverts = 65535;
+ nverts = 65536;
}
U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts);
@@ -1121,7 +1244,9 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
createGLBuffer(needed_size);
}
+ sVertexCount -= mNumVerts;
mNumVerts = nverts;
+ sVertexCount += mNumVerts;
}
void LLVertexBuffer::updateNumIndices(S32 nindices)
@@ -1137,7 +1262,9 @@ void LLVertexBuffer::updateNumIndices(S32 nindices)
createGLIndices(needed_size);
}
+ sIndexCount -= mNumIndices;
mNumIndices = nindices;
+ sIndexCount += mNumIndices;
}
void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
@@ -1163,7 +1290,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
{
#if GL_ARB_vertex_array_object
- glGenVertexArrays(1, &mGLArray);
+ mGLArray = getVAOName();
#endif
setupVertexArray();
}
@@ -2033,6 +2160,16 @@ void LLVertexBuffer::flush()
}
}
+// bind for transform feedback (quick 'n dirty)
+void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count)
+{
+#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
+ U32 offset = mOffsets[type] + sTypeSize[type]*index;
+ U32 size= (sTypeSize[type]*count);
+ glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size);
+#endif
+}
+
// Set for rendering
void LLVertexBuffer::setBuffer(U32 data_mask)
{
@@ -2184,10 +2321,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
stop_glerror();
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
- /*if ((data_mask & mTypeMask) != data_mask)
+ if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
{
llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
- }*/
+ }
if (LLGLSLShader::sNoFixedFunction)
{
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index d859199663..11fa4ab6a0 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -55,24 +55,30 @@ class LLVBOPool
{
public:
static U32 sBytesPooled;
+ static U32 sIndexBytesPooled;
- LLVBOPool(U32 vboUsage, U32 vboType)
- : mUsage(vboUsage)
- , mType(vboType)
- {}
+ static U32 sCurGLName;
+ LLVBOPool(U32 vboUsage, U32 vboType);
+
const U32 mUsage;
const U32 mType;
//size MUST be a power of 2
- volatile U8* allocate(U32& name, U32 size);
+ volatile U8* allocate(U32& name, U32 size, bool for_seed = false);
//size MUST be the size provided to allocate that returned the given name
void release(U32 name, volatile U8* buffer, U32 size);
+ //batch allocate buffers to be provided to the application on demand
+ void seedPool();
+
//destroy all records in mFreeList
void cleanup();
+ U32 genBuffer();
+ void deleteBuffer(U32 name);
+
class Record
{
public:
@@ -80,17 +86,15 @@ public:
volatile U8* mClientData;
};
+ std::list<U32> mGLNamePool;
+
typedef std::list<Record> record_list_t;
std::vector<record_list_t> mFreeList;
-};
+ std::vector<U32> mMissCount;
-class LLGLFence
-{
-public:
- virtual void placeFence() = 0;
- virtual void wait() = 0;
};
+
//============================================================================
// base class
class LLPrivateMemoryPool;
@@ -124,13 +128,22 @@ public:
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
+ static std::list<U32> sAvailableVAOName;
+ static U32 sCurVAOName;
+
static bool sUseStreamDraw;
static bool sUseVAO;
static bool sPreferStreamDraw;
+ static void seedPools();
+
+ static U32 getVAOName();
+ static void releaseVAOName(U32 name);
+
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
+ static void pushPositions(U32 mode, const LLVector4a* pos, U32 count);
static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
@@ -207,7 +220,6 @@ protected:
void destroyGLIndices();
void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices);
- bool useVBOs() const;
void unmapBuffer();
public:
@@ -217,6 +229,8 @@ public:
volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
+ void bindForFeedback(U32 channel, U32 type, U32 index, U32 count);
+
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
void flush(); //flush pending data to GL memory
@@ -239,12 +253,14 @@ public:
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool getTextureIndexStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
+ bool useVBOs() const;
bool isEmpty() const { return mEmpty; }
bool isLocked() const { return mVertexLocked || mIndexLocked; }
S32 getNumVerts() const { return mNumVerts; }
@@ -332,6 +348,9 @@ public:
static bool sIBOActive;
static U32 sLastMask;
static U32 sAllocatedBytes;
+ static U32 sAllocatedIndexBytes;
+ static U32 sVertexCount;
+ static U32 sIndexCount;
static U32 sBindCount;
static U32 sSetCount;
};
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index f3a48835b1..aa5f577897 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -349,7 +349,7 @@ void LLMultiFloater::setVisible(BOOL visible)
BOOL LLMultiFloater::handleKeyHere(KEY key, MASK mask)
{
- if (key == 'W' && mask == (MASK_CONTROL|MASK_SHIFT))
+ if (key == 'W' && mask == MASK_CONTROL)
{
LLFloater* floater = getActiveFloater();
// is user closeable and is system closeable
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7aeeae298f..104481cbfc 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -280,12 +280,23 @@ bool LLTextBase::truncate()
if (getLength() >= S32(mMaxTextByteLength / 4))
{
// Have to check actual byte size
- LLWString text(getWText());
- S32 utf8_byte_size = wstring_utf8_length(text);
+ S32 utf8_byte_size = 0;
+ LLSD value = getViewModel()->getValue();
+ if (value.type() == LLSD::TypeString)
+ {
+ // save a copy for strings.
+ utf8_byte_size = value.size();
+ }
+ else
+ {
+ // non string LLSDs need explicit conversion to string
+ utf8_byte_size = value.asString().size();
+ }
+
if ( utf8_byte_size > mMaxTextByteLength )
{
// Truncate safely in UTF-8
- std::string temp_utf8_text = wstring_to_utf8str(text);
+ std::string temp_utf8_text = value.asString();
temp_utf8_text = utf8str_truncate( temp_utf8_text, mMaxTextByteLength );
LLWString text = utf8str_to_wstring( temp_utf8_text );
// remove extra bit of current string, to preserve formatting, etc.
@@ -592,8 +603,7 @@ void LLTextBase::drawText()
S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::segment_vec_t* segments )
{
- LLWString text(getWText());
- S32 old_len = text.length(); // length() returns character length
+ S32 old_len = getLength(); // length() returns character length
S32 insert_len = wstr.length();
pos = getEditableIndex(pos, true);
@@ -653,8 +663,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
}
}
- text.insert(pos, wstr);
- getViewModel()->setDisplay(text);
+ getViewModel()->getEditableDisplay().insert(pos, wstr);
if ( truncate() )
{
@@ -669,7 +678,6 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
{
- LLWString text(getWText());
segment_set_t::iterator seg_iter = getSegIterContaining(pos);
while(seg_iter != mSegments.end())
{
@@ -715,8 +723,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
++seg_iter;
}
- text.erase(pos, length);
- getViewModel()->setDisplay(text);
+ getViewModel()->getEditableDisplay().erase(pos, length);
// recreate default segment in case we erased everything
createDefaultSegment();
@@ -733,9 +740,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
{
return 0;
}
- LLWString text(getWText());
- text[pos] = wc;
- getViewModel()->setDisplay(text);
+ getViewModel()->getEditableDisplay()[pos] = wc;
onValueChange(pos, pos + 1);
needsReflow(pos);
@@ -1685,6 +1690,8 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name)
}
}
+static LLFastTimer::DeclareTimer FTM_PARSE_HTML("Parse HTML");
+
void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
{
LLStyle::Params style_params(input_params);
@@ -1693,6 +1700,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
S32 part = (S32)LLTextParser::WHOLE;
if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
{
+ LLFastTimer _(FTM_PARSE_HTML);
S32 start=0,end=0;
LLUrlMatch match;
std::string text = new_text;
@@ -1760,8 +1768,11 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
}
}
+static LLFastTimer::DeclareTimer FTM_APPEND_TEXT("Append Text");
+
void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params)
{
+ LLFastTimer _(FTM_APPEND_TEXT);
if (new_text.empty())
return;
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 6a905b7ec0..11cfa1d263 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -150,7 +150,7 @@ S32 LLTextBox::getTextPixelHeight()
LLSD LLTextBox::getValue() const
{
- return LLSD(getText());
+ return getViewModel()->getValue();
}
BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index b5e27616b7..87bf518aa1 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -831,7 +831,11 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL
gGL.flush();
glLineWidth(2.5f);
- glLineStipple(2, 0x3333 << shift);
+
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glLineStipple(2, 0x3333 << shift);
+ }
gGL.begin(LLRender::LINES);
{
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index 763af5d8a2..ef2e314799 100644
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -102,6 +102,7 @@ public:
// New functions
/// Get the stored value in string form
const LLWString& getDisplay() const { return mDisplay; }
+ LLWString& getEditableDisplay() { mDirty = true; mUpdateFromDisplay = true; return mDisplay; }
/**
* Set the display string directly (see LLTextEditor). What the user is
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index f3ac17d612..32d081d552 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -86,6 +86,13 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
std::string fullpath;
S32 result;
+ // File masks starting with "/" will match nothing, so we consider them invalid.
+ if (LLStringUtil::startsWith(mask, getDirDelimiter()))
+ {
+ llwarns << "Invalid file mask: " << mask << llendl;
+ llassert(!"Invalid file mask");
+ }
+
LLDirIterator iter(dirname, mask);
while (iter.next(filename))
{
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index bc85acbf45..6f0d90be06 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -367,6 +367,10 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
U32 fsaa_samples)
: LLWindow(callbacks, fullscreen, flags)
{
+
+ //MAINT-516 -- force a load of opengl32.dll just in case windows went sideways
+ LoadLibrary(L"opengl32.dll");
+
mFSAASamples = fsaa_samples;
mIconResource = gIconResource;
mOverrideAspectRatio = 0.f;
@@ -1477,7 +1481,8 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
}
else
{
- llinfos << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) << " context." << llendl;
+ llinfos << "Created OpenGL " << llformat("%d.%d", attribs[1], attribs[3]) <<
+ (LLRender::sGLCoreProfile ? " core" : " compatibility") << " context." << llendl;
done = true;
if (LLRender::sGLCoreProfile)
diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp
index 809f66cb1d..aa45c5d23f 100644
--- a/indra/mac_updater/mac_updater.cpp
+++ b/indra/mac_updater/mac_updater.cpp
@@ -1188,9 +1188,7 @@ void *updatethreadproc(void*)
llinfos << "Clearing cache..." << llendl;
- char mask[LL_MAX_PATH]; /* Flawfinder: ignore */
- snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str());
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
llinfos << "Clear complete." << llendl;
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 05c05b9393..b7b040f98b 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -148,7 +148,7 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>ApplyTextureImmediately</key>
+ <key>TextureLivePreview</key>
<map>
<key>Comment</key>
<string>Preview selections in texture picker immediately</string>
@@ -7263,7 +7263,7 @@
<key>WebContentWindowLimit</key>
<map>
<key>Comment</key>
- <string>Maximum number of web brower windows that can be open at once in the Web content floater (0 for no limit)</string>
+ <string>Maximum number of web browser windows that can be open at once in the Web content floater (0 for no limit)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -7631,6 +7631,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderCompressTextures</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable texture compression on OpenGL 3.0 and later implementations (EXPERIMENTAL, requires restart)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderPerformanceTest</key>
<map>
<key>Comment</key>
@@ -8071,6 +8082,18 @@
<real>0</real>
</map>
+ <key>RenderDepthPrePass</key>
+ <map>
+ <key>Comment</key>
+ <string>EXPERIMENTAL: Prime the depth buffer with simple prim geometry before rendering with textures.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
<key>RenderDepthOfField</key>
<map>
<key>Comment</key>
@@ -9123,28 +9146,19 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderUseShaderLOD</key>
- <map>
- <key>Comment</key>
- <string>Whether we want to have different shaders for LOD</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
- <key>RenderUseShaderNearParticles</key>
- <map>
- <key>Comment</key>
- <string>Whether we want to use shaders on near particles</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
+
+ <key>RenderAutoHideSurfaceAreaLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum surface area of a set of proximal objects inworld before automatically hiding geometry to prevent system overload.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
<key>RenderVBOEnable</key>
<map>
<key>Comment</key>
@@ -9159,7 +9173,7 @@
<key>RenderUseVAO</key>
<map>
<key>Comment</key>
- <string>Use GL Vertex Array Objects</string>
+ <string>[EXPERIMENTAL] Use GL Vertex Array Objects</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9167,7 +9181,19 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderVBOMappingDisable</key>
+ <key>RenderUseTransformFeedback</key>
+ <map>
+ <key>Comment</key>
+ <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+
+ <key>RenderVBOMappingDisable</key>
<map>
<key>Comment</key>
<string>Disable VBO glMapBufferARB</string>
@@ -12148,6 +12174,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderSynchronousOcclusion</key>
+ <map>
+ <key>Comment</key>
+ <string>Don't let occlusion queries get more than one frame behind (block until they complete).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderDelayVBUpdate</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
index cb87b754b4..1113a9845b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
@@ -31,6 +31,8 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+uniform float minimum_alpha;
+
uniform sampler2DRect depthMap;
uniform sampler2D diffuseMap;
@@ -70,9 +72,15 @@ void main()
vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
+ if (diff.a < minimum_alpha)
+ {
+ discard;
+ }
+
vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0);
vec4 color = diff * col;
+
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 75de47614c..bff87cb6aa 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -55,8 +55,6 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
uniform vec3 center;
uniform vec3 color;
@@ -143,7 +141,8 @@ void main()
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0, norm.z);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 19800a8b8e..f671d5b750 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -42,12 +42,13 @@ uniform sampler2DRect depthMap;
uniform vec3 env_mat[3];
uniform float sun_wash;
-uniform vec3 center;
uniform vec3 color;
uniform float falloff;
uniform float size;
VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
+
uniform vec2 screen_res;
uniform mat4 inv_proj;
@@ -74,7 +75,7 @@ void main()
frag.xy *= screen_res;
vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos;
+ vec3 lv = trans_center.xyz-pos;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
index cb14e6d4e8..9491421236 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
@@ -24,16 +24,22 @@
*/
uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
ATTRIBUTE vec3 position;
+uniform vec3 center;
+uniform float size;
+
VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec3 p = position*sqrt(size)+center;
+ vec4 pos = modelview_projection_matrix * vec4(p.xyz, 1.0);
vary_fragcoord = pos;
-
+ trans_center = (modelview_matrix*vec4(center.xyz, 1.0)).xyz;
gl_Position = pos;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
new file mode 100644
index 0000000000..6195e2f1ec
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -0,0 +1,44 @@
+/**
+ * @file shadowCubeV.glsl
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec4 post_pos;
+
+uniform vec3 box_center;
+uniform vec3 box_size;
+
+void main()
+{
+ //transform vertex
+ vec3 p = position*box_size+box_center;
+ vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
+
+ post_pos = pos;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index 7ed8ed3370..cca63872de 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -24,18 +24,21 @@
*/
-#extension GL_ARB_texture_rectangle : enable
-
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
+//class 1 -- no shadows
+
+#extension GL_ARB_texture_rectangle : enable
+
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
+uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
@@ -46,6 +49,7 @@ uniform vec3 proj_n;
uniform float proj_focus; //distance from plane to begin blurring
uniform float proj_lod; //(number of mips in proj map)
uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
uniform float proj_ambiance;
uniform float near_clip;
uniform float far_clip;
@@ -53,19 +57,66 @@ uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
-uniform vec3 center;
uniform vec3 color;
uniform float falloff;
uniform float size;
VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
+
uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float det = max(1.0-lod/(proj_lod*0.5), 0.0);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+
vec4 getPosition(vec2 pos_screen)
{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ float depth = texture2DRect(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@@ -84,16 +135,16 @@ void main()
frag.xy *= screen_res;
vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
+ vec3 lv = trans_center.xyz-pos.xyz;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
{
discard;
}
-
+
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = vec3((norm.xy-0.5)*2.0, norm.z);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -107,7 +158,11 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = falloff+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
lv = proj_origin-pos.xyz;
lv = normalize(lv);
@@ -125,32 +180,32 @@ void main()
proj_tc.y > 0.0)
{
float lit = 0.0;
+ float amb_da = proj_ambiance;
+
if (da > 0.0)
{
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
- vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
vec3 lcol = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex;
+ amb_da += (da*0.5)*proj_ambiance;
}
- float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
- vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
- //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
- float amb_da = proj_ambiance;
-
+ //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+
amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
+
amb_da *= dist_atten * noise;
-
+
amb_da = min(amb_da, 1.0-lit);
-
+
col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
@@ -168,18 +223,22 @@ void main()
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
- vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
if (stc.z > 0.0)
{
- stc.xy /= stc.z+proj_near;
-
+ stc.xy /= stc.w;
+
+ float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+
+ stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
+ vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/clipF.glsl b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
new file mode 100644
index 0000000000..ac2bc8703b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
@@ -0,0 +1,46 @@
+/**
+ * @file debugF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifdef DEFINE_GL_FRAGCOLOR
+out vec4 frag_color;
+#else
+#define frag_color gl_FragColor
+#endif
+
+uniform vec4 color;
+uniform vec4 clip_plane;
+
+VARYING vec3 vary_position;
+
+
+void main()
+{
+ if (dot(vary_position,clip_plane.xyz)+clip_plane.w < 0.0)
+ {
+ discard;
+ }
+
+ frag_color = color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/interface/clipV.glsl b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
new file mode 100644
index 0000000000..e376b25a71
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file debugV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_projection_matrix;
+uniform mat4 modelview_matrix;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec3 vary_position;
+
+void main()
+{
+ vary_position = (modelview_matrix*vec4(position.xyz,1.0)).xyz;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
new file mode 100644
index 0000000000..5c479d27a9
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file occlusionCubeV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_projection_matrix;
+
+ATTRIBUTE vec3 position;
+
+uniform vec3 box_center;
+uniform vec3 box_size;
+
+void main()
+{
+ vec3 p = position*box_size+box_center;
+ gl_Position = modelview_projection_matrix * vec4(p.xyz, 1.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
new file mode 100644
index 0000000000..44f1aa34a0
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file binormalV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+
+ATTRIBUTE vec3 binormal;
+
+VARYING vec4 binormal_out;
+
+void main()
+{
+ binormal_out = vec4(normal_matrix * binormal, 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/colorV.glsl b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl
new file mode 100644
index 0000000000..59c4a7d895
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/colorV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file colorV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform int color_in;
+
+ATTRIBUTE vec3 position;
+
+VARYING int color_out;
+
+void main()
+{
+ color_out = color_in;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/normalV.glsl b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl
new file mode 100644
index 0000000000..a213aa0ae8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/normalV.glsl
@@ -0,0 +1,36 @@
+/**
+ * @file normalV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat3 normal_matrix;
+
+ATTRIBUTE vec3 normal;
+
+VARYING vec4 normal_out;
+
+void main()
+{
+ normal_out = vec4(normalize(normal_matrix * normal), 0.0);
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl
new file mode 100644
index 0000000000..01eed18de4
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl
@@ -0,0 +1,40 @@
+/**
+ * @file positionV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_matrix;
+
+uniform int texture_index_in;
+
+ATTRIBUTE vec3 position;
+
+VARYING vec3 position_out;
+VARYING int texture_index_out;
+
+void main()
+{
+ texture_index_out = texture_index_in;
+ position_out = (modelview_matrix*vec4(position, 1.0)).xyz;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl
new file mode 100644
index 0000000000..0e074f3cec
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl
@@ -0,0 +1,35 @@
+/**
+ * @file texcoordV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+ATTRIBUTE vec2 texcoord0;
+
+VARYING vec2 texcoord_out;
+
+void main()
+{
+ texcoord_out = texcoord0;
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
index 931577359e..d6848c8dc1 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
@@ -31,6 +31,8 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+uniform float minimum_alpha;
+
uniform sampler2DRectShadow shadowMap0;
uniform sampler2DRectShadow shadowMap1;
uniform sampler2DRectShadow shadowMap2;
@@ -95,6 +97,13 @@ void main()
float shadow = 0.0;
vec4 pos = vec4(vary_position, 1.0);
+ vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
+
+ if (diff.a < minimum_alpha)
+ {
+ discard;
+ }
+
vec4 spos = pos;
if (spos.z > -shadow_clip.w)
@@ -162,8 +171,6 @@ void main()
shadow = 1.0;
}
- vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
-
vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, 1.0);
vec4 color = diff * col;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 99a277fbfc..ab077d9e02 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -31,8 +31,6 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-VARYING vec4 vertex_color;
-
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
@@ -49,6 +47,7 @@ uniform vec3 proj_n;
uniform float proj_focus; //distance from plane to begin blurring
uniform float proj_lod; //(number of mips in proj map)
uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
uniform float proj_ambiance;
uniform float near_clip;
uniform float far_clip;
@@ -58,16 +57,65 @@ uniform float sun_wash;
uniform int proj_shadow_idx;
uniform float shadow_fade;
-VARYING vec4 vary_light;
+uniform float size;
+uniform vec3 color;
+uniform float falloff;
+VARYING vec3 trans_center;
VARYING vec4 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float det = max(1.0-lod/(proj_lod*0.5), 0.0);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+
vec4 getPosition(vec2 pos_screen)
{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ float depth = texture2DRect(depthMap, pos_screen.xy).r;
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@@ -85,6 +133,15 @@ void main()
frag.xyz = frag.xyz*0.5+0.5;
frag.xy *= screen_res;
+ vec3 pos = getPosition(frag.xy).xyz;
+ vec3 lv = trans_center.xyz-pos.xyz;
+ float dist2 = dot(lv,lv);
+ dist2 /= size;
+ if (dist2 > 1.0)
+ {
+ discard;
+ }
+
float shadow = 1.0;
if (proj_shadow_idx >= 0)
@@ -96,15 +153,6 @@ void main()
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
}
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = vary_light.xyz-pos.xyz;
- float dist2 = dot(lv,lv);
- dist2 /= vary_light.w;
- if (dist2 > 1.0)
- {
- discard;
- }
-
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
@@ -119,8 +167,12 @@ void main()
proj_tc.xyz /= proj_tc.w;
- float fa = vertex_color.a+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ float fa = falloff+1.0;
+ float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
lv = proj_origin-pos.xyz;
lv = normalize(lv);
@@ -138,37 +190,33 @@ void main()
proj_tc.y > 0.0)
{
float lit = 0.0;
+ float amb_da = proj_ambiance;
+
if (da > 0.0)
{
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
- vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
- vec3 lcol = vertex_color.rgb * plcol.rgb * plcol.a;
+ vec3 lcol = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex*shadow;
- }
-
- float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
- vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
- //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
- float amb_da = proj_ambiance;
- if (da > 0.0)
- {
amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
}
+ //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+
amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
+
amb_da *= dist_atten * noise;
-
+
amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*vertex_color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
+
+ col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
@@ -185,19 +233,23 @@ void main()
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
- vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
if (stc.z > 0.0)
{
- stc.xy /= stc.z+proj_near;
-
+ stc.xy /= stc.w;
+
+ float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+
+ stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
- col += dist_atten*scol.rgb*vertex_color.rgb*scol.a*spec.rgb*shadow;
+ vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
+ col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
}
}
}
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 76bb2b0976..eeb632acaf 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -61,6 +61,7 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 1.0
+RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -72,6 +73,38 @@ RenderMaxTextureIndex 1 16
//
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarPhysicsLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderLocalLights 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTransparentWater 1 0
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 0
+WindLightUseAtmosShaders 1 0
+WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+RenderFSAASamples 1 0
+
+
+//
// Low Graphics Settings
//
list Low
@@ -94,7 +127,7 @@ RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 0
+VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
RenderDeferred 1 0
@@ -223,6 +256,12 @@ list Class3
RenderVBOEnable 1 1
//
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures 1 0
+
+//
// No Pixel Shaders available
//
list NoPixelShaders
@@ -302,6 +341,7 @@ RenderMaxTextureIndex 1 1
list Intel
RenderAnisotropic 1 0
RenderVBOEnable 1 0
+RenderFSAASamples 1 0
list GeForce2
RenderAnisotropic 1 0
@@ -480,6 +520,7 @@ Disregard128DefaultDrawDistance 1 0
list ATIOldDriver
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
+RenderVBOEnable 1 0
// ATI cards generally perform better when not using VBOs for streaming data
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 5e217e000a..3a0e7e3697 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -61,6 +61,7 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 1.0
+RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -69,6 +70,37 @@ RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
//
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarPhysicsLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderLocalLights 1 0
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTransparentWater 1 0
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 0.5
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 0
+WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+RenderFSAASamples 1 0
+
+//
// Low Graphics Settings
//
list Low
@@ -220,6 +252,12 @@ list Class3
RenderVBOEnable 1 1
//
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures 1 0
+
+//
// No Pixel Shaders available
//
list NoPixelShaders
@@ -291,10 +329,15 @@ RenderObjectBump 0 0
list OpenGLPre15
RenderVBOEnable 1 0
+list OpenGLPre30
+RenderDeferred 0 0
+RenderMaxTextureIndex 1 1
+
list Intel
RenderAnisotropic 1 0
// Avoid some Intel crashes on Linux
RenderCubeMap 0 0
+RenderFSAASamples 1 0
list GeForce2
RenderAnisotropic 1 0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 915a012a39..96362ff4bb 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -61,6 +61,7 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 0.5
+RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -71,6 +72,37 @@ RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
//
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarPhysicsLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderLocalLights 1 0
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTransparentWater 1 0
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 0.5
+VertexShaderEnable 1 0
+WindLightUseAtmosShaders 1 0
+WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+RenderFSAASamples 1 0
+
+//
// Low Graphics Settings
//
list Low
@@ -93,7 +125,7 @@ RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 0.5
-VertexShaderEnable 1 0
+VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
RenderDeferred 1 0
@@ -248,6 +280,12 @@ RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
//
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures 1 0
+
+//
// "Default" setups for safe, low, medium, high
//
list safe
@@ -286,6 +324,7 @@ RenderObjectBump 0 0
list OpenGLPre15
RenderVBOEnable 1 0
+
list TexUnit8orLess
RenderDeferredSSAO 0 0
@@ -295,6 +334,7 @@ RenderDeferredSSAO 1 0
list Intel
RenderAnisotropic 1 0
RenderLocalLights 1 0
+RenderFSAASamples 1 0
list GeForce2
RenderAnisotropic 1 0
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
index ae2cf910f2..a945f7a693 100644
--- a/indra/newview/featuretable_xp.txt
+++ b/indra/newview/featuretable_xp.txt
@@ -61,6 +61,7 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 1.0
+RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -71,6 +72,37 @@ RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
//
+// Low Graphics Settings (fixed function)
+//
+list LowFixedFunction
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarPhysicsLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderLocalLights 1 0
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTransparentWater 1 0
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 0.5
+VertexShaderEnable 1 0
+WindLightUseAtmosShaders 1 0
+WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+RenderFSAASamples 1 0
+
+//
// Low Graphics Settings
//
list Low
@@ -93,7 +125,7 @@ RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 0.5
-VertexShaderEnable 1 0
+VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
RenderDeferred 1 0
@@ -222,6 +254,12 @@ list Class3
RenderVBOEnable 1 1
//
+// VRAM > 512MB
+//
+list VRAMGT512
+RenderCompressTextures 1 0
+
+//
// No Pixel Shaders available
//
list NoPixelShaders
@@ -299,6 +337,7 @@ RenderMaxTextureIndex 1 1
list Intel
RenderAnisotropic 1 0
RenderVBOEnable 1 0
+RenderFSAASamples 1 0
list GeForce2
RenderAnisotropic 1 0
@@ -478,6 +517,7 @@ Disregard128DefaultDrawDistance 1 0
list ATIOldDriver
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
+RenderVBOEnable 1 0
// ATI cards generally perform better when not using VBOs for streaming data
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index 198e702459..777d54a5c3 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -205,6 +205,7 @@ ATI Radeon X800 .*ATI.*Radeon ?X8.* 2 1
ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1
ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1
ATI Rage 128 .*ATI.*Rage 128.* 0 1
+ATI R300 (9700) .*R300.* 1 1
ATI R350 (9800) .*R350.* 1 1
ATI R580 (X1900) .*R580.* 3 1
ATI RC410 (Xpress 200) .*RC410.* 0 0
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 1174d108d2..89994e505b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -528,6 +528,7 @@ static void settings_to_globals()
LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile");
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
+ LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
@@ -545,7 +546,7 @@ static void settings_to_globals()
gAgentPilot.setNumRuns(gSavedSettings.getS32("StatsNumRuns"));
gAgentPilot.setQuitAfterRuns(gSavedSettings.getBOOL("StatsQuitAfterRuns"));
gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle"));
-
+
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
@@ -1014,6 +1015,15 @@ bool LLAppViewer::init()
}
}
+#if LL_WINDOWS
+ if (gGLManager.mIsIntel &&
+ LLFeatureManager::getInstance()->getGPUClass() > 0 &&
+ gGLManager.mGLVersion <= 3.f)
+ {
+ LLNotificationsUtil::add("IntelOldDriver");
+ }
+#endif
+
// save the graphics card
gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
@@ -1123,6 +1133,8 @@ void LLAppViewer::checkMemory()
static LLFastTimer::DeclareTimer FTM_MESSAGES("System Messages");
static LLFastTimer::DeclareTimer FTM_SLEEP("Sleep");
+static LLFastTimer::DeclareTimer FTM_YIELD("Yield");
+
static LLFastTimer::DeclareTimer FTM_TEXTURE_CACHE("Texture Cache");
static LLFastTimer::DeclareTimer FTM_DECODE("Image Decode");
static LLFastTimer::DeclareTimer FTM_VFS("VFS Thread");
@@ -1308,6 +1320,7 @@ bool LLAppViewer::mainLoop()
// yield some time to the os based on command line option
if(mYieldTime >= 0)
{
+ LLFastTimer t(FTM_YIELD);
ms_sleep(mYieldTime);
}
@@ -1511,7 +1524,6 @@ bool LLAppViewer::cleanup()
if (! isError())
{
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
- logdir += gDirUtilp->getDirDelimiter();
gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp");
}
@@ -1760,8 +1772,7 @@ bool LLAppViewer::cleanup()
if (mPurgeOnExit)
{
llinfos << "Purging all cache files on exit" << llendflush;
- std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), "*.*");
}
removeMarkerFile(); // Any crashes from here on we'll just have to ignore
@@ -2995,8 +3006,7 @@ void LLAppViewer::cleanupSavedSettings()
void LLAppViewer::removeCacheFiles(const std::string& file_mask)
{
- std::string mask = gDirUtilp->getDirDelimiter() + file_mask;
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), file_mask);
}
void LLAppViewer::writeSystemInfo()
@@ -3855,8 +3865,7 @@ void LLAppViewer::purgeCache()
LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
- std::string mask = "*.*";
- gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), mask);
+ gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""), "*.*");
}
std::string LLAppViewer::getSecondLifeTitle() const
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index f618af9536..fdd4565e50 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -594,7 +594,7 @@ namespace action_give_inventory
}
S32 count = LLShareInfo::instance().mAvatarNames.size();
- bool shared = false;
+ bool shared = count && !inventory_selected_uuids.empty();
// iterate through avatars
for(S32 i = 0; i < count; ++i)
@@ -616,8 +616,10 @@ namespace action_give_inventory
LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
if (inv_cat)
{
- LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id);
- shared = true;
+ if (!LLGiveInventory::doGiveInventoryCategory(avatar_uuid, inv_cat, session_id, "ItemsShared"))
+ {
+ shared = false;
+ }
break;
}
LLViewerInventoryItem* inv_item = gInventory.getItem(*it);
@@ -632,8 +634,10 @@ namespace action_give_inventory
}
else
{
- LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id);
- shared = true;
+ if (!LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id))
+ {
+ shared = false;
+ }
}
}
if (noncopy_items.beginArray() != noncopy_items.endArray())
@@ -643,8 +647,10 @@ namespace action_give_inventory
LLSD payload;
payload["agent_id"] = avatar_uuid;
payload["items"] = noncopy_items;
+ payload["success_notification"] = "ItemsShared";
LLNotificationsUtil::add("CannotCopyWarning", substitutions, payload,
&LLGiveInventory::handleCopyProtectedItem);
+ shared = false;
break;
}
}
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index f530d10ddc..84e73e96fa 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -495,7 +495,7 @@ protected:
void showInfoCtrl()
{
- if (mAvatarID.isNull() || mFrom.empty() || SYSTEM_FROM == mFrom) return;
+ if (mAvatarID.isNull() || mFrom.empty() || CHAT_SOURCE_SYSTEM == mSourceType) return;
if (!sInfoCtrl)
{
@@ -689,8 +689,11 @@ void LLChatHistory::clear()
mLastFromID = LLUUID::null;
}
+static LLFastTimer::DeclareTimer FTM_APPEND_MESSAGE("Append Chat Message");
+
void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params)
{
+ LLFastTimer _(FTM_APPEND_MESSAGE);
bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean();
llassert(mEditor);
@@ -783,7 +786,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
timestamp_style.color(timestamp_color);
timestamp_style.readonly_color(timestamp_color);
}
- mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getText().size() != 0, timestamp_style);
+ mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getLength() != 0, timestamp_style);
if (utf8str_trim(chat.mFromName).size() != 0)
{
@@ -842,7 +845,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
else
{
view = getHeader(chat, style_params, args);
- if (mEditor->getText().size() == 0)
+ if (mEditor->getLength() == 0)
p.top_pad = 0;
else
p.top_pad = mTopHeaderPad;
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 21b21c152a..563b9b9cab 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -57,6 +57,8 @@ const F32 MIN_SHADOW_CASTER_RADIUS = 2.0f;
static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound");
+extern bool gShiftFrame;
+
////////////////////////
//
@@ -108,6 +110,8 @@ void LLDrawable::init()
mGeneration = -1;
mBinRadius = 1.f;
+ mBinIndex = -1;
+
mSpatialBridge = NULL;
}
@@ -450,7 +454,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
{
if (isState(ACTIVE))
{
- clearState(ACTIVE);
+ clearState(ACTIVE | ANIMATED_CHILD);
if (mParent.notNull() && mParent->isActive() && warning_enabled)
{
@@ -538,9 +542,9 @@ F32 LLDrawable::updateXform(BOOL undamped)
target_rot = new_rot;
target_scale = new_scale;
}
- else
+ else if (mVObjp->getAngularVelocity().isExactlyZero())
{
- // snap to final position
+ // snap to final position (only if no target omega is applied)
dist_squared = 0.0f;
if (getVOVolume() && !isRoot())
{ //child prim snapping to some position, needs a rebuild
@@ -549,15 +553,25 @@ F32 LLDrawable::updateXform(BOOL undamped)
}
}
- if ((mCurrentScale != target_scale) ||
- (!isRoot() &&
- (dist_squared >= MIN_INTERPOLATE_DISTANCE_SQUARED ||
- !mVObjp->getAngularVelocity().isExactlyZero() ||
- target_pos != mXform.getPosition() ||
- target_rot != mXform.getRotation())))
- { //child prim moving or scale change requires immediate rebuild
+ LLVector3 vec = mCurrentScale-target_scale;
+
+ if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)
+ { //scale change requires immediate rebuild
+ mCurrentScale = target_scale;
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
}
+ else if (!isRoot() &&
+ (!mVObjp->getAngularVelocity().isExactlyZero() ||
+ dist_squared > 0.f))
+ { //child prim moving relative to parent, tag as needing to be rendered atomically and rebuild
+ dist_squared = 1.f; //keep this object on the move list
+ if (!isState(LLDrawable::ANIMATED_CHILD))
+ {
+ setState(LLDrawable::ANIMATED_CHILD);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
+ mVObjp->dirtySpatialGroup();
+ }
+ }
else if (!getVOVolume() && !isAvatar())
{
movePartition();
@@ -568,9 +582,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
mXform.setRotation(target_rot);
mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
mXform.updateMatrix();
-
- mCurrentScale = target_scale;
-
+
if (mSpatialBridge)
{
gPipeline.markMoved(mSpatialBridge, FALSE);
@@ -596,7 +608,11 @@ void LLDrawable::moveUpdatePipeline(BOOL moved)
// Update the face centers.
for (S32 i = 0; i < getNumFaces(); i++)
{
- getFace(i)->updateCenterAgent();
+ LLFace* face = getFace(i);
+ if (face)
+ {
+ face->updateCenterAgent();
+ }
}
}
@@ -651,7 +667,6 @@ BOOL LLDrawable::updateMoveUndamped()
}
mVObjp->clearChanged(LLXform::MOVED);
-
return TRUE;
}
@@ -703,6 +718,11 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
return;
}
+ if (gShiftFrame)
+ {
+ return;
+ }
+
//switch LOD with the spatial group to avoid artifacts
//LLSpatialGroup* sg = getSpatialGroup();
@@ -727,7 +747,8 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
for (S32 i = 0; i < getNumFaces(); i++)
{
LLFace* facep = getFace(i);
- if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA)
+ if (facep &&
+ (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))
{
LLVector4a box;
box.setSub(facep->mExtents[1], facep->mExtents[0]);
@@ -811,14 +832,19 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
mXform.setPosition(mVObjp->getPositionAgent());
}
- mXform.setRotation(mVObjp->getRotation());
- mXform.setScale(1,1,1);
mXform.updateMatrix();
if (isStatic())
{
LLVOVolume* volume = getVOVolume();
- if (!volume)
+
+ bool rebuild = (!volume &&
+ getRenderType() != LLPipeline::RENDER_TYPE_TREE &&
+ getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN &&
+ getRenderType() != LLPipeline::RENDER_TYPE_SKY &&
+ getRenderType() != LLPipeline::RENDER_TYPE_GROUND);
+
+ if (rebuild)
{
gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
}
@@ -826,13 +852,16 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
for (S32 i = 0; i < getNumFaces(); i++)
{
LLFace *facep = getFace(i);
- facep->mCenterAgent += LLVector3(shift_vector.getF32ptr());
- facep->mExtents[0].add(shift_vector);
- facep->mExtents[1].add(shift_vector);
-
- if (!volume && facep->hasGeometry())
+ if (facep)
{
- facep->clearVertexBuffer();
+ facep->mCenterAgent += LLVector3(shift_vector.getF32ptr());
+ facep->mExtents[0].add(shift_vector);
+ facep->mExtents[1].add(shift_vector);
+
+ if (rebuild && facep->hasGeometry())
+ {
+ facep->clearVertexBuffer();
+ }
}
}
@@ -940,6 +969,12 @@ void LLDrawable::updateUVMinMax()
{
}
+LLSpatialGroup* LLDrawable::getSpatialGroup() const
+{
+ llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
+ return mSpatialGroupp;
+}
+
void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
{
/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
@@ -954,11 +989,16 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
for (S32 i = 0; i < getNumFaces(); ++i)
{
LLFace* facep = getFace(i);
- facep->clearVertexBuffer();
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
}
}
mSpatialGroupp = groupp;
+
+ llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
}
LLSpatialPartition* LLDrawable::getSpatialPartition()
@@ -1081,6 +1121,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
mDrawable = root;
root->setSpatialBridge(this);
+ mBinIndex = -1;
+
mRenderType = mDrawable->mRenderType;
mDrawableType = mDrawable->mRenderType;
@@ -1384,6 +1426,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
markDead();
return;
}
+
+ if (gShiftFrame)
+ {
+ return;
+ }
if (mDrawable->getVObj())
{
@@ -1462,7 +1509,13 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable::cleanupReferences();
if (mDrawable)
{
- mDrawable->setSpatialGroup(NULL);
+ LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->mOctreeNode->remove(mDrawable);
+ mDrawable->setSpatialGroup(NULL);
+ }
+
if (mDrawable->getVObj())
{
LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
@@ -1473,7 +1526,12 @@ void LLSpatialBridge::cleanupReferences()
LLDrawable* drawable = child->mDrawable;
if (drawable)
{
- drawable->setSpatialGroup(NULL);
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ if (group)
+ {
+ group->mOctreeNode->remove(drawable);
+ drawable->setSpatialGroup(NULL);
+ }
}
}
}
@@ -1529,10 +1587,10 @@ BOOL LLDrawable::isAnimating() const
return TRUE;
}
- if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
- {
+ /*if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
+ { //target omega
return TRUE;
- }
+ }*/
return FALSE;
}
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index e268640a21..bc4b301ebb 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -109,6 +109,9 @@ public:
F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); }
S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; }
F32 getBinRadius() const { return mBinRadius; }
+ S32 getBinIndex() const { return mBinIndex; }
+ void setBinIndex(S32 index) const { mBinIndex = index; }
+
void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }
LLXformMatrix* getXform() { return &mXform; }
@@ -194,7 +197,7 @@ public:
S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...
void setSpatialGroup(LLSpatialGroup *groupp);
- LLSpatialGroup *getSpatialGroup() const { return mSpatialGroupp; }
+ LLSpatialGroup *getSpatialGroup() const;
LLSpatialPartition* getSpatialPartition();
// Statics
@@ -277,6 +280,7 @@ public:
HAS_ALPHA = 0x04000000,
RIGGED = 0x08000000,
PARTITION_MOVE = 0x10000000,
+ ANIMATED_CHILD = 0x20000000,
} EDrawableFlags;
private: //aligned members
@@ -314,6 +318,7 @@ private:
mutable U32 mVisible;
F32 mRadius;
F32 mBinRadius;
+ mutable S32 mBinIndex;
S32 mGeneration;
LLVector3 mCurrentScale;
@@ -333,12 +338,14 @@ inline LLFace* LLDrawable::getFace(const S32 i) const
if ((U32) i >= mFaces.size())
{
- llerrs << "Invalid face index." << llendl;
+ llwarns << "Invalid face index." << llendl;
+ return NULL;
}
if (!mFaces[i])
{
- llerrs << "Null face found." << llendl;
+ llwarns << "Null face found." << llendl;
+ return NULL;
}
return mFaces[i];
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 35f8a85796..6c0be0a5c2 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -253,48 +253,6 @@ void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures
{
}
-// static
-S32 LLFacePool::drawLoop(face_array_t& face_list)
-{
- S32 res = 0;
- if (!face_list.empty())
- {
- for (std::vector<LLFace*>::iterator iter = face_list.begin();
- iter != face_list.end(); iter++)
- {
- LLFace *facep = *iter;
- res += facep->renderIndexed();
- }
- }
- return res;
-}
-
-// static
-S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
-{
- S32 res = 0;
- if (!face_list.empty())
- {
- for (std::vector<LLFace*>::iterator iter = face_list.begin();
- iter != face_list.end(); iter++)
- {
- LLFace *facep = *iter;
- gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE) ;
- gGL.getTexUnit(0)->activate();
- res += facep->renderIndexed();
- }
- }
- return res;
-}
-
-void LLFacePool::drawLoop()
-{
- if (!mDrawFace.empty())
- {
- drawLoop(mDrawFace);
- }
-}
-
void LLFacePool::enqueue(LLFace* facep)
{
mDrawFace.push_back(facep);
@@ -442,7 +400,7 @@ void LLRenderPass::renderTexture(U32 type, U32 mask)
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
- for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LLDrawInfo* pparams = *i;
if (pparams)
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 64774d06df..e0f2da41d7 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -186,10 +186,6 @@ public:
void buildEdges();
- static S32 drawLoop(face_array_t& face_list);
- static S32 drawLoopSetTex(face_array_t& face_list, S32 stage);
- void drawLoop();
-
void addFaceReference(LLFace *facep);
void removeFaceReference(LLFace *facep);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 5b62dbc560..313b310e1e 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -348,7 +348,7 @@ void LLDrawPoolAlpha::render(S32 pass)
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
- for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+ for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (group->mSpatialPartition->mRenderByGroup &&
@@ -385,7 +385,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
BOOL use_shaders = gPipeline.canUseVertexShaders();
- for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
+ for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
llassert(group);
@@ -405,6 +405,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
{
LLDrawInfo& params = **k;
+ if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
+ { //FIXME!
+ llwarns << "Missing required components, skipping render batch." << llendl;
+ continue;
+ }
+
LLRenderPass::applyModelMatrix(params);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 0103373fd2..730ad1a364 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -261,7 +261,9 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
sRenderingSkinned = TRUE;
gPipeline.bindDeferredShader(*sVertexProgram);
-
+
+ sVertexProgram->setMinimumAlpha(0.2f);
+
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
@@ -1034,9 +1036,13 @@ void LLDrawPoolAvatar::endDeferredSkinned()
gGL.getTexUnit(0)->activate();
}
+static LLFastTimer::DeclareTimer FTM_RENDER_AVATARS("renderAvatars");
+
void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
{
+ LLFastTimer t(FTM_RENDER_AVATARS);
+
if (pass == -1)
{
for (S32 i = 1; i < getNumPasses(); i++)
@@ -1193,15 +1199,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
if (pass >= 7 && pass < 9)
{
- LLGLEnable blend(GL_BLEND);
-
- gGL.setColorMask(true, true);
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
- LLRender::BF_ZERO,
- LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-
-
if (pass == 7)
{
renderRiggedAlpha(avatarp);
@@ -1217,20 +1214,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
if (pass == 9)
{
- LLGLEnable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
- gGL.flush();
-
- LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(-1.0f, -1.0f);
- gGL.setSceneBlendType(LLRender::BT_ADD);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- gGL.setColorMask(false, true);
-
renderRiggedGlow(avatarp);
- gGL.setColorMask(true, false);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
return;
}
@@ -1428,7 +1413,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
- if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())
+ if (avatar->isSelf() && !gAgent.needsRenderAvatar())
{
return;
}
@@ -1557,8 +1542,12 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
renderRigged(avatar, RIGGED_DEFERRED_BUMP);
}
+static LLFastTimer::DeclareTimer FTM_RIGGED_VBO("Rigged VBO");
+
void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
{
+ LLFastTimer t(FTM_RIGGED_VBO);
+
//update rigged vertex buffers
for (U32 type = 0; type < NUM_RIGGED_PASSES; ++type)
{
@@ -1630,17 +1619,56 @@ void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar)
void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar)
{
- renderRigged(avatar, RIGGED_ALPHA);
+ if (!mRiggedFace[RIGGED_ALPHA].empty())
+ {
+ LLGLEnable blend(GL_BLEND);
+
+ gGL.setColorMask(true, true);
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
+ LLRender::BF_ZERO,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+
+ renderRigged(avatar, RIGGED_ALPHA);
+ }
}
void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar)
{
- renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA);
+ if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty())
+ {
+ LLGLEnable blend(GL_BLEND);
+
+ gGL.setColorMask(true, true);
+ gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
+ LLRender::BF_ZERO,
+ LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
+
+ renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA);
+ }
}
void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar)
{
- renderRigged(avatar, RIGGED_GLOW, true);
+ if (!mRiggedFace[RIGGED_GLOW].empty())
+ {
+ LLGLEnable blend(GL_BLEND);
+ LLGLDisable test(GL_ALPHA_TEST);
+ gGL.flush();
+
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.0f, -1.0f);
+ gGL.setSceneBlendType(LLRender::BT_ADD);
+
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ gGL.setColorMask(false, true);
+
+ renderRigged(avatar, RIGGED_GLOW, true);
+
+ gGL.setColorMask(true, false);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ }
}
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index b58efe62ab..a264eae302 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -847,12 +847,12 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
LLFastTimer ftm(FTM_RENDER_BUMP);
U32 type = LLRenderPass::PASS_BUMP;
- LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type);
- LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type);
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
- for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
@@ -1341,8 +1341,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
// immediately assign bump to a global smart pointer in case some local smart pointer
// accidentally releases it.
LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE );
-
-
+
if (!LLPipeline::sRenderDeferred)
{
LLFastTimer t(FTM_BUMP_SOURCE_CREATE);
@@ -1351,6 +1350,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
}
else
{ //convert to normal map
+
+ //disable compression on normal maps to prevent errors below
+ bump->getGLTexture()->setAllowCompression(false);
+
{
LLFastTimer t(FTM_BUMP_SOURCE_CREATE);
bump->setExplicitFormat(GL_RGBA8, GL_ALPHA);
@@ -1445,10 +1448,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
void LLDrawPoolBump::renderBump(U32 type, U32 mask)
{
- LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type);
- LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type);
+ LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
+ LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index b95d8296fa..7fc78fb382 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -294,6 +294,34 @@ void LLDrawPoolTerrain::renderShadow(S32 pass)
//glCullFace(GL_BACK);
}
+
+void LLDrawPoolTerrain::drawLoop()
+{
+ if (!mDrawFace.empty())
+ {
+ for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+ iter != mDrawFace.end(); iter++)
+ {
+ LLFace *facep = *iter;
+
+ LLMatrix4* model_matrix = &(facep->getDrawable()->getRegion()->mRenderMatrix);
+
+ if (model_matrix != gGLLastMatrix)
+ {
+ gGLLastMatrix = model_matrix;
+ gGL.loadMatrix(gGLModelView);
+ if (model_matrix)
+ {
+ gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
+ }
+ gPipeline.mMatrixOpCount++;
+ }
+
+ facep->renderIndexed();
+ }
+ }
+}
+
void LLDrawPoolTerrain::renderFullShader()
{
// Hack! Get the region that this draw pool is rendering from!
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 283ed87f1a..2163d087e1 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -83,6 +83,7 @@ protected:
void renderFull2TU();
void renderFull4TU();
void renderFullShader();
+ void drawLoop();
};
#endif // LL_LLDRAWPOOLSIMPLE_H
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index 3165a3516c..83f04e45a8 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -37,6 +37,7 @@
#include "llviewershadermgr.h"
#include "llrender.h"
#include "llviewercontrol.h"
+#include "llviewerregion.h"
S32 LLDrawPoolTree::sDiffTex = 0;
static LLGLSLShader* shader = NULL;
@@ -104,8 +105,22 @@ void LLDrawPoolTree::render(S32 pass)
{
LLFace *face = *iter;
LLVertexBuffer* buff = face->getVertexBuffer();
+
if(buff)
{
+ LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix);
+
+ if (model_matrix != gGLLastMatrix)
+ {
+ gGLLastMatrix = model_matrix;
+ gGL.loadMatrix(gGLModelView);
+ if (model_matrix)
+ {
+ gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
+ }
+ gPipeline.mMatrixOpCount++;
+ }
+
buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0);
gPipeline.addTrianglesDrawn(buff->getNumIndices());
diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp
index 64eb11fc9b..885cae1737 100644
--- a/indra/newview/lldriverparam.cpp
+++ b/indra/newview/lldriverparam.cpp
@@ -155,6 +155,7 @@ LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
mAvatarp(avatarp),
mWearablep(NULL)
{
+ mDefaultVec.clear();
}
LLDriverParam::LLDriverParam(LLWearable *wearablep) :
@@ -162,6 +163,7 @@ LLDriverParam::LLDriverParam(LLWearable *wearablep) :
mAvatarp(NULL),
mWearablep(wearablep)
{
+ mDefaultVec.clear();
}
LLDriverParam::~LLDriverParam()
@@ -341,18 +343,19 @@ F32 LLDriverParam::getTotalDistortion()
return sum;
}
-const LLVector3 &LLDriverParam::getAvgDistortion()
+const LLVector4a &LLDriverParam::getAvgDistortion()
{
// It's not actually correct to take the average of averages, but it good enough here.
- LLVector3 sum;
+ LLVector4a sum;
+ sum.clear();
S32 count = 0;
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
LLDrivenEntry* driven = &(*iter);
- sum += driven->mParam->getAvgDistortion();
+ sum.add(driven->mParam->getAvgDistortion());
count++;
}
- sum /= (F32)count;
+ sum.mul( 1.f/(F32)count);
mDefaultVec = sum;
return mDefaultVec;
@@ -375,21 +378,22 @@ F32 LLDriverParam::getMaxDistortion()
}
-LLVector3 LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
+LLVector4a LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
{
- LLVector3 sum;
+ LLVector4a sum;
+ sum.clear();
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
LLDrivenEntry* driven = &(*iter);
- sum += driven->mParam->getVertexDistortion( index, poly_mesh );
+ sum.add(driven->mParam->getVertexDistortion( index, poly_mesh ));
}
return sum;
}
-const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
+const LLVector4a* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
{
mCurrentDistortionParam = NULL;
- const LLVector3* v = NULL;
+ const LLVector4a* v = NULL;
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
LLDrivenEntry* driven = &(*iter);
@@ -404,7 +408,7 @@ const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly
return v;
};
-const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
+const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
{
llassert( mCurrentDistortionParam );
if( !mCurrentDistortionParam )
@@ -432,7 +436,7 @@ const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_
}
// We're already in the middle of a param's distortions, so get the next one.
- const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh );
+ const LLVector4a* v = driven->mParam->getNextDistortion( index, poly_mesh );
if( (!v) && (iter != mDriven.end()) )
{
// This param is finished, so start the next param. It might not have any
diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h
index fb1b44458c..7a4d711d4e 100644
--- a/indra/newview/lldriverparam.h
+++ b/indra/newview/lldriverparam.h
@@ -105,18 +105,18 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion();
- /*virtual*/ const LLVector3& getAvgDistortion();
+ /*virtual*/ const LLVector4a& getAvgDistortion();
/*virtual*/ F32 getMaxDistortion();
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
protected:
F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
- LLVector3 mDefaultVec; // temp holder
+ LLVector4a mDefaultVec; // temp holder
typedef std::vector<LLDrivenEntry> entry_list_t;
entry_list_t mDriven;
LLViewerVisualParam* mCurrentDistortionParam;
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 4108d69e82..9acdee702b 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -44,11 +44,14 @@
#include "llsky.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
+#include "llvopartgroup.h"
#include "llvosky.h"
#include "llvovolume.h"
#include "pipeline.h"
#include "llviewerregion.h"
#include "llviewerwindow.h"
+#include "llviewershadermgr.h"
+
#define LL_MAX_INDICES_COUNT 1000000
@@ -56,7 +59,6 @@ BOOL LLFace::sSafeRenderSelect = TRUE; // FALSE
#define DOTVEC(a,b) (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2])
-
/*
For each vertex, given:
B - binormal
@@ -161,7 +163,10 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mGeomCount = 0;
mGeomIndex = 0;
mIndicesCount = 0;
- mIndicesIndex = 0;
+
+ //special value to indicate uninitialized position
+ mIndicesIndex = 0xFFFFFFFF;
+
mIndexInTex = 0;
mTexture = NULL;
mTEOffset = -1;
@@ -177,12 +182,6 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mFaceColor = LLColor4(1,0,0,1);
- mLastVertexBuffer = mVertexBuffer;
- mLastGeomCount = mGeomCount;
- mLastGeomIndex = mGeomIndex;
- mLastIndicesCount = mIndicesCount;
- mLastIndicesIndex = mIndicesIndex;
-
mImportanceToCamera = 0.f ;
mBoundingSphereRadius = 0.0f ;
@@ -203,6 +202,15 @@ void LLFace::destroy()
mTexture->removeFace(this) ;
}
+ if (mDrawablep.notNull() &&
+ (mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_PARTICLES ||
+ mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_HUD_PARTICLES) &&
+ mIndicesIndex != 0xFFFFFFFF)
+ {
+ LLVOPartGroup::freeVBSlot(getGeomIndex()/4);
+ mIndicesIndex = 0xFFFFFFFF;
+ }
+
if (mDrawPoolp)
{
if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
@@ -372,7 +380,6 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)
mGeomCount = num_vertices;
mIndicesCount = num_indices;
mVertexBuffer = NULL;
- mLastVertexBuffer = NULL;
}
llassert(verify());
@@ -765,12 +772,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
LLMatrix4a mat_normal;
mat_normal.loadu(mat_normal_in);
- //if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
- //{ //vertex buffer no longer valid
- // mVertexBuffer = NULL;
- // mLastVertexBuffer = NULL;
- //}
-
//VECTORIZE THIS
LLVector4a min,max;
@@ -1032,30 +1033,13 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
void LLFace::updateRebuildFlags()
{
- if (!mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
- {
- BOOL moved = TRUE;
- if (mLastVertexBuffer == mVertexBuffer &&
- !mVertexBuffer->isEmpty())
- { //this face really doesn't need to be regenerated, try real hard not to do so
- if (mLastGeomCount == mGeomCount &&
- mLastGeomIndex == mGeomIndex &&
- mLastIndicesCount == mIndicesCount &&
- mLastIndicesIndex == mIndicesIndex)
- { //data is in same location in vertex buffer
- moved = FALSE;
- }
- }
- mLastMoveTime = gFrameTimeSeconds;
-
- if (moved)
- {
- mDrawablep->setState(LLDrawable::REBUILD_VOLUME);
- }
+ if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME))
+ { //this rebuild is zero overhead (direct consequence of some change that affects this face)
+ mLastUpdateTime = gFrameTimeSeconds;
}
else
- {
- mLastUpdateTime = gFrameTimeSeconds;
+ { //this rebuild is overhead (side effect of some change that does not affect this face)
+ mLastMoveTime = gFrameTimeSeconds;
}
}
@@ -1094,6 +1078,73 @@ bool LLFace::canRenderAsMask()
}
+static LLFastTimer::DeclareTimer FTM_FACE_GEOM_VOLUME("Volume VB Cache");
+
+//static
+void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
+{
+ LLFastTimer t(FTM_FACE_GEOM_VOLUME);
+ U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL;
+
+ if (vf.mWeights)
+ {
+ mask |= LLVertexBuffer::MAP_WEIGHT4;
+ }
+
+ LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW_ARB);
+ vf.mVertexBuffer = buff;
+
+ buff->allocateBuffer(vf.mNumVertices, 0, true);
+
+ LLStrider<LLVector4a> f_vert;
+ LLStrider<LLVector3> f_binorm;
+ LLStrider<LLVector3> f_norm;
+ LLStrider<LLVector2> f_tc;
+
+ buff->getBinormalStrider(f_binorm);
+ buff->getVertexStrider(f_vert);
+ buff->getNormalStrider(f_norm);
+ buff->getTexCoord0Strider(f_tc);
+
+ for (U32 i = 0; i < vf.mNumVertices; ++i)
+ {
+ *f_vert++ = vf.mPositions[i];
+ (*f_binorm++).set(vf.mBinormals[i].getF32ptr());
+ *f_tc++ = vf.mTexCoords[i];
+ (*f_norm++).set(vf.mNormals[i].getF32ptr());
+ }
+
+ if (vf.mWeights)
+ {
+ LLStrider<LLVector4> f_wght;
+ buff->getWeight4Strider(f_wght);
+ for (U32 i = 0; i < vf.mNumVertices; ++i)
+ {
+ (*f_wght++).set(vf.mWeights[i].getF32ptr());
+ }
+ }
+
+ buff->flush();
+}
+
+//helper function for pushing primitives for transform shaders and cleaning up
+//uninitialized data on the tail, plus tracking number of expected primitives
+void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
+{
+ if (source_count > 0 && dest_count >= source_count) //protect against possible U32 wrapping
+ {
+ //push source primitives
+ buff->drawArrays(LLRender::POINTS, 0, source_count);
+ U32 tail = dest_count-source_count;
+ for (U32 i = 0; i < tail; ++i)
+ { //copy last source primitive into each element in tail
+ buff->drawArrays(LLRender::POINTS, source_count-1, 1);
+ }
+ gPipeline.mTransformFeedbackPrimitives += dest_count;
+ }
+}
+
static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_POSITION("Position");
static LLFastTimer::DeclareTimer FTM_FACE_GEOM_NORMAL("Normal");
@@ -1111,7 +1162,6 @@ static LLFastTimer::DeclareTimer FTM_FACE_TEX_DEFAULT("Default");
static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK("Quick");
static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_NO_XFORM("No Xform");
static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_XFORM("Xform");
-
static LLFastTimer::DeclareTimer FTM_FACE_TEX_QUICK_PLANAR("Quick Planar");
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
@@ -1139,21 +1189,25 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices())
{
- llwarns << "Index buffer overflow!" << llendl;
- llwarns << "Indices Count: " << mIndicesCount
- << " VF Num Indices: " << num_indices
- << " Indices Index: " << mIndicesIndex
- << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl;
- llwarns << "Last Indices Count: " << mLastIndicesCount
- << " Last Indices Index: " << mLastIndicesIndex
- << " Face Index: " << f
- << " Pool Type: " << mPoolType << llendl;
+ if (gDebugGL)
+ {
+ llwarns << "Index buffer overflow!" << llendl;
+ llwarns << "Indices Count: " << mIndicesCount
+ << " VF Num Indices: " << num_indices
+ << " Indices Index: " << mIndicesIndex
+ << " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl;
+ llwarns << " Face Index: " << f
+ << " Pool Type: " << mPoolType << llendl;
+ }
return FALSE;
}
if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts())
{
- llwarns << "Vertex buffer overflow!" << llendl;
+ if (gDebugGL)
+ {
+ llwarns << "Vertex buffer overflow!" << llendl;
+ }
return FALSE;
}
}
@@ -1284,17 +1338,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLMatrix4a mat_normal;
mat_normal.loadu(mat_norm_in);
- //if it's not fullbright and has no normals, bake sunlight based on face normal
- //bool bake_sunlight = !getTextureEntry()->getFullbright() &&
- // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
-
F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
-
+ bool do_xform = false;
if (rebuild_tcoord)
{
- LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
- bool do_xform;
-
if (tep)
{
r = tep->getRotation();
@@ -1323,599 +1370,759 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
do_xform = false;
}
+ }
+
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
+ if (use_transform_feedback &&
+ gTransformPositionProgram.mProgramObject && //transform shaders are loaded
+ mVertexBuffer->useVBOs() && //target buffer is in VRAM
+ !rebuild_weights && //TODO: add support for weights
+ !volume.isUnique()) //source volume is NOT flexi
+ { //use transform feedback to pack vertex buffer
+
+ LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
+
+ if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
+ {
+ mVObjp->getVolume()->genBinormals(f);
+ LLFace::cacheFaceInVRAM(vf);
+ buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
+ }
+
+ LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ gGL.pushMatrix();
+ gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix);
+
+ if (rebuild_pos)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_POSITION);
+ gTransformPositionProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
+
+ U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+
+ S32 val = 0;
+ U8* vp = (U8*) &val;
+ vp[0] = index;
+ vp[1] = 0;
+ vp[2] = 0;
+ vp[3] = 0;
+
+ gTransformPositionProgram.uniform1i("texture_index_in", val);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+
+ glEndTransformFeedback();
+ }
+
+ if (rebuild_color)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_COLOR);
+ gTransformColorProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
+
+ S32 val = *((S32*) color.mV);
+
+ gTransformColorProgram.uniform1i("color_in", val);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
+
+ if (rebuild_emissive)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
+ gTransformColorProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
+
+ U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+
+ S32 glow32 = glow |
+ (glow << 8) |
+ (glow << 16) |
+ (glow << 24);
+
+ gTransformColorProgram.uniform1i("color_in", glow32);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
+
+ if (rebuild_normal)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_NORMAL);
+ gTransformNormalProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
- //bump setup
- LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
- LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
- LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_NORMAL);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
- LLQuaternion bump_quat;
- if (mDrawablep->isActive())
+ if (rebuild_binormal)
{
- bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
+ LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
+ gTransformBinormalProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount);
+
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_BINORMAL);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
}
-
- if (bump_code)
+
+ if (rebuild_tcoord)
{
- mVObjp->getVolume()->genBinormals(f);
- F32 offset_multiple;
- switch( bump_code )
- {
- case BE_NO_BUMP:
- offset_multiple = 0.f;
- break;
- case BE_BRIGHTNESS:
- case BE_DARKNESS:
- if( mTexture.notNull() && mTexture->hasGLTexture())
- {
- // Offset by approximately one texel
- S32 cur_discard = mTexture->getDiscardLevel();
- S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
- max_size <<= cur_discard;
- const F32 ARTIFICIAL_OFFSET = 2.f;
- offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
- }
- else
- {
- offset_multiple = 1.f/256;
- }
- break;
+ LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
+ gTransformTexCoordProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
+
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
- default: // Standard bumpmap textures. Assumed to be 256x256
- offset_multiple = 1.f / 256;
- break;
- }
+ bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- F32 s_scale = 1.f;
- F32 t_scale = 1.f;
- if( tep )
+ if (do_bump)
{
- tep->getScale( &s_scale, &t_scale );
- }
- // Use the nudged south when coming from above sun angle, such
- // that emboss mapping always shows up on the upward faces of cubes when
- // it's noon (since a lot of builders build with the sun forced to noon).
- LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir;
- LLVector3 moon_ray = gSky.getMoonDirection();
- LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
-
- bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
- bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
}
- U8 texgen = getTextureEntry()->getTexGen();
- if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- { //planar texgen needs binormals
- mVObjp->getVolume()->genBinormals(f);
+ glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
+
+ gGL.popMatrix();
+
+ if (cur_shader)
+ {
+ cur_shader->bind();
}
+ }
+ else
+#endif
+ {
+ //if it's not fullbright and has no normals, bake sunlight based on face normal
+ //bool bake_sunlight = !getTextureEntry()->getFullbright() &&
+ // !mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL);
- U8 tex_mode = 0;
-
- if (isState(TEXTURE_ANIM))
+ if (rebuild_tcoord)
{
- LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
- tex_mode = vobj->mTexAnimMode;
+ LLFastTimer t(FTM_FACE_GEOM_TEXTURE);
+
+ //bump setup
+ LLVector4a binormal_dir( -sin_ang, cos_ang, 0.f );
+ LLVector4a bump_s_primary_light_ray(0.f, 0.f, 0.f);
+ LLVector4a bump_t_primary_light_ray(0.f, 0.f, 0.f);
- if (!tex_mode)
+ LLQuaternion bump_quat;
+ if (mDrawablep->isActive())
{
- clearState(TEXTURE_ANIM);
+ bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
}
- else
+
+ if (bump_code)
{
- os = ot = 0.f;
- r = 0.f;
- cos_ang = 1.f;
- sin_ang = 0.f;
- ms = mt = 1.f;
+ mVObjp->getVolume()->genBinormals(f);
+ F32 offset_multiple;
+ switch( bump_code )
+ {
+ case BE_NO_BUMP:
+ offset_multiple = 0.f;
+ break;
+ case BE_BRIGHTNESS:
+ case BE_DARKNESS:
+ if( mTexture.notNull() && mTexture->hasGLTexture())
+ {
+ // Offset by approximately one texel
+ S32 cur_discard = mTexture->getDiscardLevel();
+ S32 max_size = llmax( mTexture->getWidth(), mTexture->getHeight() );
+ max_size <<= cur_discard;
+ const F32 ARTIFICIAL_OFFSET = 2.f;
+ offset_multiple = ARTIFICIAL_OFFSET / (F32)max_size;
+ }
+ else
+ {
+ offset_multiple = 1.f/256;
+ }
+ break;
- do_xform = false;
+ default: // Standard bumpmap textures. Assumed to be 256x256
+ offset_multiple = 1.f / 256;
+ break;
+ }
+
+ F32 s_scale = 1.f;
+ F32 t_scale = 1.f;
+ if( tep )
+ {
+ tep->getScale( &s_scale, &t_scale );
+ }
+ // Use the nudged south when coming from above sun angle, such
+ // that emboss mapping always shows up on the upward faces of cubes when
+ // it's noon (since a lot of builders build with the sun forced to noon).
+ LLVector3 sun_ray = gSky.mVOSkyp->mBumpSunDir;
+ LLVector3 moon_ray = gSky.getMoonDirection();
+ LLVector3& primary_light_ray = (sun_ray.mV[VZ] > 0) ? sun_ray : moon_ray;
+
+ bump_s_primary_light_ray.load3((offset_multiple * s_scale * primary_light_ray).mV);
+ bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
}
- if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
- { //don't override texture transform during tc bake
- tex_mode = 0;
+ U8 texgen = getTextureEntry()->getTexGen();
+ if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ { //planar texgen needs binormals
+ mVObjp->getVolume()->genBinormals(f);
}
- }
- LLVector4a scalea;
- scalea.load3(scale.mV);
+ U8 tex_mode = 0;
+
+ if (isState(TEXTURE_ANIM))
+ {
+ LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
+ tex_mode = vobj->mTexAnimMode;
+
+ if (!tex_mode)
+ {
+ clearState(TEXTURE_ANIM);
+ }
+ else
+ {
+ os = ot = 0.f;
+ r = 0.f;
+ cos_ang = 1.f;
+ sin_ang = 0.f;
+ ms = mt = 1.f;
+
+ do_xform = false;
+ }
- bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- bool do_tex_mat = tex_mode && mTextureMatrix;
+ if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
+ { //don't override texture transform during tc bake
+ tex_mode = 0;
+ }
+ }
- if (!in_atlas && !do_bump)
- { //not in atlas or not bump mapped, might be able to do a cheap update
- mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
+ LLVector4a scalea;
+ scalea.load3(scale.mV);
- if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
- {
- LLFastTimer t(FTM_FACE_TEX_QUICK);
- if (!do_tex_mat)
+ bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
+ bool do_tex_mat = tex_mode && mTextureMatrix;
+
+ if (!in_atlas && !do_bump)
+ { //not in atlas or not bump mapped, might be able to do a cheap update
+ mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount);
+
+ if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
{
- if (!do_xform)
- {
- LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
- LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
- }
- else
+ LLFastTimer t(FTM_FACE_TEX_QUICK);
+ if (!do_tex_mat)
{
- LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
- F32* dst = (F32*) tex_coords.get();
- LLVector4a* src = (LLVector4a*) vf.mTexCoords;
+ if (!do_xform)
+ {
+ LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
+ LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
+ }
+ else
+ {
+ LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
+ F32* dst = (F32*) tex_coords.get();
+ LLVector4a* src = (LLVector4a*) vf.mTexCoords;
- LLVector4a trans;
- trans.splat(-0.5f);
+ LLVector4a trans;
+ trans.splat(-0.5f);
- LLVector4a rot0;
- rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
+ LLVector4a rot0;
+ rot0.set(cos_ang, -sin_ang, cos_ang, -sin_ang);
- LLVector4a rot1;
- rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
+ LLVector4a rot1;
+ rot1.set(sin_ang, cos_ang, sin_ang, cos_ang);
- LLVector4a scale;
- scale.set(ms, mt, ms, mt);
+ LLVector4a scale;
+ scale.set(ms, mt, ms, mt);
- LLVector4a offset;
- offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
+ LLVector4a offset;
+ offset.set(os+0.5f, ot+0.5f, os+0.5f, ot+0.5f);
- LLVector4Logical mask;
- mask.clear();
- mask.setElement<2>();
- mask.setElement<3>();
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<2>();
+ mask.setElement<3>();
- U32 count = num_vertices/2 + num_vertices%2;
+ U32 count = num_vertices/2 + num_vertices%2;
- for (S32 i = 0; i < count; i++)
+ for (S32 i = 0; i < count; i++)
+ {
+ LLVector4a res = *src++;
+ xform4a(res, trans, mask, rot0, rot1, offset, scale);
+ res.store4a(dst);
+ dst += 4;
+ }
+ }
+ }
+ else
+ { //do tex mat, no texgen, no atlas, no bump
+ for (S32 i = 0; i < num_vertices; i++)
{
- LLVector4a res = *src++;
- xform4a(res, trans, mask, rot0, rot1, offset, scale);
- res.store4a(dst);
- dst += 4;
+ LLVector2 tc(vf.mTexCoords[i]);
+ //LLVector4a& norm = vf.mNormals[i];
+ //LLVector4a& center = *(vf.mCenter);
+
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
+ *tex_coords++ = tc;
}
}
}
else
- { //do tex mat, no texgen, no atlas, no bump
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- //LLVector4a& norm = vf.mNormals[i];
- //LLVector4a& center = *(vf.mCenter);
-
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
- *tex_coords++ = tc;
- }
- }
- }
- else
- { //no bump, no atlas, tex gen planar
- LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
- if (do_tex_mat)
- {
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
- LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
- planarProjection(tc, norm, center, vec);
+ { //no bump, no atlas, tex gen planar
+ LLFastTimer t(FTM_FACE_TEX_QUICK_PLANAR);
+ if (do_tex_mat)
+ {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+ LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& center = *(vf.mCenter);
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
+ planarProjection(tc, norm, center, vec);
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
- *tex_coords++ = tc;
+ *tex_coords++ = tc;
+ }
}
- }
- else
- {
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
- LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
- planarProjection(tc, norm, center, vec);
+ else
+ {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+ LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& center = *(vf.mCenter);
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
+ planarProjection(tc, norm, center, vec);
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
- *tex_coords++ = tc;
+ *tex_coords++ = tc;
+ }
}
}
- }
- if (map_range)
- {
- mVertexBuffer->flush();
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- else
- { //either bump mapped or in atlas, just do the whole expensive loop
- LLFastTimer t(FTM_FACE_TEX_DEFAULT);
- mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);
+ else
+ { //either bump mapped or in atlas, just do the whole expensive loop
+ LLFastTimer t(FTM_FACE_TEX_DEFAULT);
+ mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range);
- std::vector<LLVector2> bump_tc;
+ std::vector<LLVector2> bump_tc;
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
+ LLVector4a& center = *(vf.mCenter);
- if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- {
- LLVector4a vec = vf.mPositions[i];
+ if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ {
+ LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
+ vec.mul(scalea);
- switch (texgen)
+ switch (texgen)
+ {
+ case LLTextureEntry::TEX_GEN_PLANAR:
+ planarProjection(tc, norm, center, vec);
+ break;
+ case LLTextureEntry::TEX_GEN_SPHERICAL:
+ sphericalProjection(tc, norm, center, vec);
+ break;
+ case LLTextureEntry::TEX_GEN_CYLINDRICAL:
+ cylindricalProjection(tc, norm, center, vec);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (tex_mode && mTextureMatrix)
{
- case LLTextureEntry::TEX_GEN_PLANAR:
- planarProjection(tc, norm, center, vec);
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
+ }
+ else
+ {
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ }
+
+ if(in_atlas)
+ {
+ //
+ //manually calculate tex-coord per vertex for varying address modes.
+ //should be removed if shader can handle this.
+ //
+
+ S32 int_part = 0 ;
+ switch(mTexture->getAddressMode())
+ {
+ case LLTexUnit::TAM_CLAMP:
+ if(tc.mV[0] < 0.f)
+ {
+ tc.mV[0] = 0.f ;
+ }
+ else if(tc.mV[0] > 1.f)
+ {
+ tc.mV[0] = 1.f;
+ }
+
+ if(tc.mV[1] < 0.f)
+ {
+ tc.mV[1] = 0.f ;
+ }
+ else if(tc.mV[1] > 1.f)
+ {
+ tc.mV[1] = 1.f;
+ }
break;
- case LLTextureEntry::TEX_GEN_SPHERICAL:
- sphericalProjection(tc, norm, center, vec);
+ case LLTexUnit::TAM_MIRROR:
+ if(tc.mV[0] < 0.f)
+ {
+ tc.mV[0] = -tc.mV[0] ;
+ }
+ int_part = (S32)tc.mV[0] ;
+ if(int_part & 1) //odd number
+ {
+ tc.mV[0] = int_part + 1 - tc.mV[0] ;
+ }
+ else //even number
+ {
+ tc.mV[0] -= int_part ;
+ }
+
+ if(tc.mV[1] < 0.f)
+ {
+ tc.mV[1] = -tc.mV[1] ;
+ }
+ int_part = (S32)tc.mV[1] ;
+ if(int_part & 1) //odd number
+ {
+ tc.mV[1] = int_part + 1 - tc.mV[1] ;
+ }
+ else //even number
+ {
+ tc.mV[1] -= int_part ;
+ }
break;
- case LLTextureEntry::TEX_GEN_CYLINDRICAL:
- cylindricalProjection(tc, norm, center, vec);
+ case LLTexUnit::TAM_WRAP:
+ if(tc.mV[0] > 1.f)
+ tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ;
+ else if(tc.mV[0] < -1.f)
+ tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ;
+
+ if(tc.mV[1] > 1.f)
+ tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ;
+ else if(tc.mV[1] < -1.f)
+ tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ;
+
+ if(tc.mV[0] < 0.f)
+ {
+ tc.mV[0] = 1.0f + tc.mV[0] ;
+ }
+ if(tc.mV[1] < 0.f)
+ {
+ tc.mV[1] = 1.0f + tc.mV[1] ;
+ }
break;
default:
break;
- }
- }
+ }
+
+ tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
+ tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
+ }
+
- if (tex_mode && mTextureMatrix)
- {
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
+ *tex_coords++ = tc;
+ if (do_bump)
+ {
+ bump_tc.push_back(tc);
+ }
}
- else
+
+ if (map_range)
{
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ mVertexBuffer->flush();
}
- if(in_atlas)
+ if (do_bump)
{
- //
- //manually calculate tex-coord per vertex for varying address modes.
- //should be removed if shader can handle this.
- //
-
- S32 int_part = 0 ;
- switch(mTexture->getAddressMode())
+ mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);
+
+ for (S32 i = 0; i < num_vertices; i++)
{
- case LLTexUnit::TAM_CLAMP:
- if(tc.mV[0] < 0.f)
- {
- tc.mV[0] = 0.f ;
- }
- else if(tc.mV[0] > 1.f)
- {
- tc.mV[0] = 1.f;
- }
-
- if(tc.mV[1] < 0.f)
- {
- tc.mV[1] = 0.f ;
- }
- else if(tc.mV[1] > 1.f)
- {
- tc.mV[1] = 1.f;
- }
- break;
- case LLTexUnit::TAM_MIRROR:
- if(tc.mV[0] < 0.f)
- {
- tc.mV[0] = -tc.mV[0] ;
- }
- int_part = (S32)tc.mV[0] ;
- if(int_part & 1) //odd number
- {
- tc.mV[0] = int_part + 1 - tc.mV[0] ;
- }
- else //even number
+ LLVector4a tangent;
+ tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]);
+
+ LLMatrix4a tangent_to_object;
+ tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]);
+ LLVector4a t;
+ tangent_to_object.rotate(binormal_dir, t);
+ LLVector4a binormal;
+ mat_normal.rotate(t, binormal);
+
+ //VECTORIZE THIS
+ if (mDrawablep->isActive())
{
- tc.mV[0] -= int_part ;
+ LLVector3 t;
+ t.set(binormal.getF32ptr());
+ t *= bump_quat;
+ binormal.load3(t.mV);
}
- if(tc.mV[1] < 0.f)
- {
- tc.mV[1] = -tc.mV[1] ;
- }
- int_part = (S32)tc.mV[1] ;
- if(int_part & 1) //odd number
- {
- tc.mV[1] = int_part + 1 - tc.mV[1] ;
- }
- else //even number
- {
- tc.mV[1] -= int_part ;
- }
- break;
- case LLTexUnit::TAM_WRAP:
- if(tc.mV[0] > 1.f)
- tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ;
- else if(tc.mV[0] < -1.f)
- tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ;
-
- if(tc.mV[1] > 1.f)
- tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ;
- else if(tc.mV[1] < -1.f)
- tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ;
-
- if(tc.mV[0] < 0.f)
- {
- tc.mV[0] = 1.0f + tc.mV[0] ;
- }
- if(tc.mV[1] < 0.f)
- {
- tc.mV[1] = 1.0f + tc.mV[1] ;
- }
- break;
- default:
- break;
+ binormal.normalize3fast();
+ LLVector2 tc = bump_tc[i];
+ tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
+
+ *tex_coords2++ = tc;
}
-
- tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
- tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
- }
-
- *tex_coords++ = tc;
- if (do_bump)
- {
- bump_tc.push_back(tc);
- }
- }
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
-
- if (do_bump)
- {
- mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);
-
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector4a tangent;
- tangent.setCross3(vf.mBinormals[i], vf.mNormals[i]);
-
- LLMatrix4a tangent_to_object;
- tangent_to_object.setRows(tangent, vf.mBinormals[i], vf.mNormals[i]);
- LLVector4a t;
- tangent_to_object.rotate(binormal_dir, t);
- LLVector4a binormal;
- mat_normal.rotate(t, binormal);
-
- //VECTORIZE THIS
- if (mDrawablep->isActive())
+ if (map_range)
{
- LLVector3 t;
- t.set(binormal.getF32ptr());
- t *= bump_quat;
- binormal.load3(t.mV);
+ mVertexBuffer->flush();
}
-
- binormal.normalize3fast();
- LLVector2 tc = bump_tc[i];
- tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() );
-
- *tex_coords2++ = tc;
- }
-
- if (map_range)
- {
- mVertexBuffer->flush();
}
}
}
- }
- if (rebuild_pos)
- {
- LLFastTimer t(FTM_FACE_GEOM_POSITION);
- llassert(num_vertices > 0);
+ if (rebuild_pos)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_POSITION);
+ llassert(num_vertices > 0);
- mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
- LLMatrix4a mat_vert;
- mat_vert.loadu(mat_vert_in);
+ LLMatrix4a mat_vert;
+ mat_vert.loadu(mat_vert_in);
- LLVector4a* src = vf.mPositions;
- volatile F32* dst = (volatile F32*) vert.get();
+ LLVector4a* src = vf.mPositions;
+ volatile F32* dst = (volatile F32*) vert.get();
- volatile F32* end = dst+num_vertices*4;
- LLVector4a res;
+ volatile F32* end = dst+num_vertices*4;
+ LLVector4a res;
- LLVector4a texIdx;
+ LLVector4a texIdx;
- U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
+ U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
- F32 val = 0.f;
- U8* vp = (U8*) &val;
- vp[0] = index;
- vp[1] = 0;
- vp[2] = 0;
- vp[3] = 0;
+ F32 val = 0.f;
+ U8* vp = (U8*) &val;
+ vp[0] = index;
+ vp[1] = 0;
+ vp[2] = 0;
+ vp[3] = 0;
- llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
+ llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
- LLVector4Logical mask;
- mask.clear();
- mask.setElement<3>();
+ LLVector4Logical mask;
+ mask.clear();
+ mask.setElement<3>();
- texIdx.set(0,0,0,val);
+ texIdx.set(0,0,0,val);
- {
- LLFastTimer t(FTM_FACE_POSITION_STORE);
- LLVector4a tmp;
-
- do
- {
- mat_vert.affineTransform(*src++, res);
- tmp.setSelectWithMask(mask, texIdx, res);
- tmp.store4a((F32*) dst);
- dst += 4;
+ {
+ LLFastTimer t(FTM_FACE_POSITION_STORE);
+ LLVector4a tmp;
+
+ do
+ {
+ mat_vert.affineTransform(*src++, res);
+ tmp.setSelectWithMask(mask, texIdx, res);
+ tmp.store4a((F32*) dst);
+ dst += 4;
+ }
+ while(dst < end);
}
- while(dst < end);
- }
- {
- LLFastTimer t(FTM_FACE_POSITION_PAD);
- S32 aligned_pad_vertices = mGeomCount - num_vertices;
- res.set(res[0], res[1], res[2], 0.f);
+ {
+ LLFastTimer t(FTM_FACE_POSITION_PAD);
+ S32 aligned_pad_vertices = mGeomCount - num_vertices;
+ res.set(res[0], res[1], res[2], 0.f);
- while (aligned_pad_vertices > 0)
+ while (aligned_pad_vertices > 0)
+ {
+ --aligned_pad_vertices;
+ res.store4a((F32*) dst);
+ dst += 4;
+ }
+ }
+
+ if (map_range)
{
- --aligned_pad_vertices;
- res.store4a((F32*) dst);
- dst += 4;
+ mVertexBuffer->flush();
}
}
- if (map_range)
- {
- mVertexBuffer->flush();
- }
- }
- if (rebuild_normal)
- {
- LLFastTimer t(FTM_FACE_GEOM_NORMAL);
- mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
- F32* normals = (F32*) norm.get();
+ if (rebuild_normal)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_NORMAL);
+ mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
+ F32* normals = (F32*) norm.get();
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector4a normal;
- mat_normal.rotate(vf.mNormals[i], normal);
- normal.normalize3fast();
- normal.store4a(normals);
- normals += 4;
- }
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector4a normal;
+ mat_normal.rotate(vf.mNormals[i], normal);
+ normal.normalize3fast();
+ normal.store4a(normals);
+ normals += 4;
+ }
- if (map_range)
- {
- mVertexBuffer->flush();
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- if (rebuild_binormal)
- {
- LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
- mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
- F32* binormals = (F32*) binorm.get();
+ if (rebuild_binormal)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
+ mVertexBuffer->getBinormalStrider(binorm, mGeomIndex, mGeomCount, map_range);
+ F32* binormals = (F32*) binorm.get();
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector4a binormal;
- mat_normal.rotate(vf.mBinormals[i], binormal);
- binormal.normalize3fast();
- binormal.store4a(binormals);
- binormals += 4;
- }
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector4a binormal;
+ mat_normal.rotate(vf.mBinormals[i], binormal);
+ binormal.normalize3fast();
+ binormal.store4a(binormals);
+ binormals += 4;
+ }
- if (map_range)
- {
- mVertexBuffer->flush();
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- if (rebuild_weights && vf.mWeights)
- {
- LLFastTimer t(FTM_FACE_GEOM_WEIGHTS);
- mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
- F32* weights = (F32*) wght.get();
- LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
- if (map_range)
+ if (rebuild_weights && vf.mWeights)
{
- mVertexBuffer->flush();
+ LLFastTimer t(FTM_FACE_GEOM_WEIGHTS);
+ mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
+ F32* weights = (F32*) wght.get();
+ LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
- {
- LLFastTimer t(FTM_FACE_GEOM_COLOR);
- mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);
+ if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
+ {
+ LLFastTimer t(FTM_FACE_GEOM_COLOR);
+ mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);
- LLVector4a src;
+ LLVector4a src;
- U32 vec[4];
- vec[0] = vec[1] = vec[2] = vec[3] = color.mAll;
+ U32 vec[4];
+ vec[0] = vec[1] = vec[2] = vec[3] = color.mAll;
- src.loadua((F32*) vec);
+ src.loadua((F32*) vec);
- F32* dst = (F32*) colors.get();
- S32 num_vecs = num_vertices/4;
- if (num_vertices%4 > 0)
- {
- ++num_vecs;
- }
+ F32* dst = (F32*) colors.get();
+ S32 num_vecs = num_vertices/4;
+ if (num_vertices%4 > 0)
+ {
+ ++num_vecs;
+ }
- for (S32 i = 0; i < num_vecs; i++)
- {
- src.store4a(dst);
- dst += 4;
- }
+ for (S32 i = 0; i < num_vecs; i++)
+ {
+ src.store4a(dst);
+ dst += 4;
+ }
- if (map_range)
- {
- mVertexBuffer->flush();
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
- }
- if (rebuild_emissive)
- {
- LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
- LLStrider<LLColor4U> emissive;
- mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
+ if (rebuild_emissive)
+ {
+ LLFastTimer t(FTM_FACE_GEOM_EMISSIVE);
+ LLStrider<LLColor4U> emissive;
+ mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
- U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+ U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
- LLVector4a src;
+ LLVector4a src;
- U32 glow32 = glow |
- (glow << 8) |
- (glow << 16) |
- (glow << 24);
+ U32 glow32 = glow |
+ (glow << 8) |
+ (glow << 16) |
+ (glow << 24);
- U32 vec[4];
- vec[0] = vec[1] = vec[2] = vec[3] = glow32;
+ U32 vec[4];
+ vec[0] = vec[1] = vec[2] = vec[3] = glow32;
- src.loadua((F32*) vec);
+ src.loadua((F32*) vec);
- F32* dst = (F32*) emissive.get();
- S32 num_vecs = num_vertices/4;
- if (num_vertices%4 > 0)
- {
- ++num_vecs;
- }
+ F32* dst = (F32*) emissive.get();
+ S32 num_vecs = num_vertices/4;
+ if (num_vertices%4 > 0)
+ {
+ ++num_vecs;
+ }
- for (S32 i = 0; i < num_vecs; i++)
- {
- src.store4a(dst);
- dst += 4;
- }
+ for (S32 i = 0; i < num_vecs; i++)
+ {
+ src.store4a(dst);
+ dst += 4;
+ }
- if (map_range)
- {
- mVertexBuffer->flush();
+ if (map_range)
+ {
+ mVertexBuffer->flush();
+ }
}
}
+
if (rebuild_tcoord)
{
mTexExtents[0].setVec(0,0);
@@ -1932,12 +2139,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
- mLastVertexBuffer = mVertexBuffer;
- mLastGeomCount = mGeomCount;
- mLastGeomIndex = mGeomIndex;
- mLastIndicesCount = mIndicesCount;
- mLastIndicesIndex = mIndicesIndex;
-
return TRUE;
}
@@ -2516,7 +2717,6 @@ void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
void LLFace::clearVertexBuffer()
{
mVertexBuffer = NULL;
- mLastVertexBuffer = NULL;
}
//static
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 82e4ab61b7..76ea5c853a 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -83,6 +83,8 @@ public:
static void initClass();
+ static void cacheFaceInVRAM(const LLVolumeFace& vf);
+
public:
LLFace(LLDrawable* drawablep, LLViewerObject* objp) { init(drawablep, objp); }
~LLFace() { destroy(); }
@@ -222,7 +224,7 @@ public:
//vertex buffer tracking
void setVertexBuffer(LLVertexBuffer* buffer);
- void clearVertexBuffer(); //sets mVertexBuffer and mLastVertexBuffer to NULL
+ void clearVertexBuffer(); //sets mVertexBuffer to NULL
LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; }
U32 getRiggedVertexBufferDataMask() const;
S32 getRiggedIndex(U32 type) const;
@@ -255,8 +257,7 @@ public:
private:
LLPointer<LLVertexBuffer> mVertexBuffer;
- LLPointer<LLVertexBuffer> mLastVertexBuffer;
-
+
U32 mState;
LLFacePool* mDrawPoolp;
U32 mPoolType;
@@ -269,12 +270,6 @@ private:
U32 mIndicesIndex; // index into draw pool for indices (yeah, I know!)
S32 mIndexInTex ;
- //previous rebuild's geometry info
- U16 mLastGeomCount;
- U16 mLastGeomIndex;
- U32 mLastIndicesCount;
- U32 mLastIndicesIndex;
-
LLXformMatrix* mXform;
LLPointer<LLViewerTexture> mTexture;
LLPointer<LLDrawable> mDrawablep;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 575b613ccf..4cbc9cab4a 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -1191,7 +1191,7 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
}
else if (action == "paste")
{
- pastFromClipboard();
+ pasteFromClipboard();
}
else if (action == "delete")
{
@@ -1239,7 +1239,7 @@ BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
return TRUE;
}
-void LLFavoritesBarCtrl::pastFromClipboard() const
+void LLFavoritesBarCtrl::pasteFromClipboard() const
{
LLInventoryModel* model = &gInventory;
if(model && isClipboardPasteable())
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2f75b3bb0e..447d30f1f4 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -90,7 +90,7 @@ protected:
bool enableSelected(const LLSD& userdata);
void doToSelected(const LLSD& userdata);
BOOL isClipboardPasteable() const;
- void pastFromClipboard() const;
+ void pasteFromClipboard() const;
void showDropDownMenu();
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 08f9d26705..ec2493dd2e 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -670,7 +670,14 @@ void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
switch (level)
{
case 0:
- maskFeatures("Low");
+ if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
+ { //only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
+ maskFeatures("LowFixedFunction");
+ }
+ else
+ { //same as low, but with "Basic Shaders" enabled
+ maskFeatures("Low");
+ }
break;
case 1:
maskFeatures("Mid");
@@ -779,6 +786,10 @@ void LLFeatureManager::applyBaseMasks()
{
maskFeatures("MapBufferRange");
}
+ if (gGLManager.mVRAM > 512)
+ {
+ maskFeatures("VRAMGT512");
+ }
// now mask by gpu string
// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 32a533570a..c4dca4cb79 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -65,7 +65,7 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD
mFrameNum = 0;
mCollisionSphereRadius = 0.f;
mRenderRes = 1;
-
+
if(mVO->mDrawable.notNull())
{
mVO->mDrawable->makeActive() ;
@@ -255,50 +255,28 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons
{
}
-//---------------------------------------------------------------------------------
-// This calculates the physics of the flexible object. Note that it has to be 0
-// updated every time step. In the future, perhaps there could be an
-// optimization similar to what Havok does for objects that are stationary.
-//---------------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
-BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
-{
- if (mVO->mDrawable.isNull())
- {
- // Don't do anything until we have a drawable
- return FALSE; // (we are not initialized or updated)
- }
-
- BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
- //flexible objects never go static
- mVO->mDrawable->mQuietCount = 0;
- if (!mVO->mDrawable->isRoot())
- {
- LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
- parent->mDrawable->mQuietCount = 0;
- }
+void LLVolumeImplFlexible::updateRenderRes()
+{
+ LLDrawable* drawablep = mVO->mDrawable;
- LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
-
S32 new_res = mAttributes->getSimulateLOD();
- //number of segments only cares about z axis
- F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, mVO->mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
+#if 1 //optimal approximation of previous behavior that doesn't rely on atan2
+ F32 app_angle = mVO->getScale().mV[2]/drawablep->mDistanceWRTCamera;
// Rendering sections increases with visible angle on the screen
- mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
- if (mRenderRes > FLEXIBLE_OBJECT_MAX_SECTIONS)
- {
- mRenderRes = FLEXIBLE_OBJECT_MAX_SECTIONS;
- }
-
+ mRenderRes = (S32) (12.f*app_angle);
+#else //legacy behavior
+ //number of segments only cares about z axis
+ F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, drawablep->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
- // Bottom cap at 1/4 the original number of sections
- if (mRenderRes < mAttributes->getSimulateLOD()-1)
- {
- mRenderRes = mAttributes->getSimulateLOD()-1;
- }
+ // Rendering sections increases with visible angle on the screen
+ mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
+#endif
+
+ mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS);
+
// Throttle back simulation of segments we're not rendering
if (mRenderRes < new_res)
{
@@ -311,43 +289,65 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6
setAttributesOfAllSections();
mInitialized = TRUE;
}
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
- {
- return FALSE; // (we are not initialized or updated)
- }
-
- bool visible = mVO->mDrawable->isVisible();
+}
+//---------------------------------------------------------------------------------
+// This calculates the physics of the flexible object. Note that it has to be 0
+// updated every time step. In the future, perhaps there could be an
+// optimization similar to what Havok does for objects that are stationary.
+//---------------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
+void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+{
+ LLDrawable* drawablep = mVO->mDrawable;
- if (force_update && visible)
+ if (drawablep)
{
- gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
- }
- else if (visible &&
- !mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) &&
- mVO->getPixelArea() > 256.f)
- {
- U32 id;
- F32 pixel_area = mVO->getPixelArea();
+ //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
- if (mVO->isRootEdit())
+ //flexible objects never go static
+ drawablep->mQuietCount = 0;
+ if (!drawablep->isRoot())
{
- id = mID;
+ LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
+ parent->mDrawable->mQuietCount = 0;
}
- else
+
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
{
- LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
- id = parent->getVolumeInterfaceID();
- }
+ bool visible = drawablep->isVisible();
- U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
+ if ((mSimulateRes == 0) && visible)
+ {
+ updateRenderRes();
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+ }
+ else if (visible &&
+ !drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
+ mVO->getPixelArea() > 256.f)
+ {
+ U32 id;
+ F32 pixel_area = mVO->getPixelArea();
- if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
- {
- gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
+ if (mVO->isRootEdit())
+ {
+ id = mID;
+ }
+ else
+ {
+ LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
+ id = parent->getVolumeInterfaceID();
+ }
+
+ U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
+
+ if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
+ {
+ updateRenderRes();
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+ }
+ }
}
}
-
- return force_update;
}
inline S32 log2(S32 x)
@@ -368,8 +368,10 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
LLPath *path = &volume->getPath();
if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
{
- mVO->markForUpdate(TRUE);
- if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0))
+ //mVO->markForUpdate(TRUE);
+ doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0);
+
+ if (mSimulateRes == 0)
{
return; // we did not get updated or initialized, proceeding without can be dangerous
}
@@ -729,7 +731,11 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable)
else if (!mUpdated || rotated)
{
volume->mDrawable->setState(LLDrawable::REBUILD_POSITION);
- volume->dirtyMesh();
+ LLSpatialGroup* group = volume->mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyMesh();
+ }
volume->genBBoxes(isVolumeGlobal());
}
@@ -814,15 +820,17 @@ LLQuaternion LLVolumeImplFlexible::getEndRotation()
}//------------------------------------------------------------------
-void LLVolumeImplFlexible::updateRelativeXform()
+void LLVolumeImplFlexible::updateRelativeXform(bool force_identity)
{
LLQuaternion delta_rot;
LLVector3 delta_pos, delta_scale;
LLVOVolume* vo = (LLVOVolume*) mVO;
+ bool use_identity = vo->mDrawable->isSpatialRoot() || force_identity;
+
//matrix from local space to parent relative/global space
- delta_rot = vo->mDrawable->isSpatialRoot() ? LLQuaternion() : vo->mDrawable->getRotation();
- delta_pos = vo->mDrawable->isSpatialRoot() ? LLVector3(0,0,0) : vo->mDrawable->getPosition();
+ delta_rot = use_identity ? LLQuaternion() : vo->mDrawable->getRotation();
+ delta_pos = use_identity ? LLVector3(0,0,0) : vo->mDrawable->getPosition();
delta_scale = LLVector3(1,1,1);
// Vertex transform (4x4)
diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h
index fef43d464d..56d579d86f 100644
--- a/indra/newview/llflexibleobject.h
+++ b/indra/newview/llflexibleobject.h
@@ -78,7 +78,8 @@ class LLVolumeImplFlexible : public LLVolumeInterface
LLVector3 getFramePosition() const;
LLQuaternion getFrameRotation() const;
LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; }
- BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+ void updateRenderRes();
+ void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
BOOL doUpdateGeometry(LLDrawable *drawable);
LLVector3 getPivotPosition() const;
void onSetVolume(const LLVolumeParams &volume_params, const S32 detail);
@@ -89,7 +90,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface
bool isVolumeGlobal() const { return true; }
bool isActive() const { return true; }
const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
- void updateRelativeXform();
+ void updateRelativeXform(bool force_identity);
void doFlexibleUpdate(); // Called to update the simulation
void doFlexibleRebuild(); // Called to rebuild the geometry
void preRebuild();
@@ -128,7 +129,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface
LLVector3 mCollisionSpherePosition;
F32 mCollisionSphereRadius;
U32 mID;
-
+
//--------------------------------------
// private methods
//--------------------------------------
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index bca4b5e447..809d344d01 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -211,8 +211,8 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,
BOOL item_is_multi = FALSE;
if ((inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_LANDMARK_VISITED
- || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
- && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
+ || inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS)
+ && !(inv_item->getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK))
{
item_is_multi = TRUE;
}
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index b050a638dc..fa0ad20fdb 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -416,6 +416,9 @@ void LLFloaterBvhPreview::draw()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::resetMotion()
{
+ if (!mAnimPreview)
+ return;
+
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
BOOL paused = avatarp->areAnimationsPaused();
@@ -535,6 +538,9 @@ BOOL LLFloaterBvhPreview::handleHover(S32 x, S32 y, MASK mask)
//-----------------------------------------------------------------------------
BOOL LLFloaterBvhPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
+ if (!mAnimPreview)
+ return false;
+
mAnimPreview->zoom((F32)clicks * -0.2f);
mAnimPreview->requestUpdate();
@@ -670,7 +676,7 @@ void LLFloaterBvhPreview::onCommitBaseAnim()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitLoop()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -689,7 +695,7 @@ void LLFloaterBvhPreview::onCommitLoop()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitLoopIn()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -709,7 +715,7 @@ void LLFloaterBvhPreview::onCommitLoopIn()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitLoopOut()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -729,7 +735,7 @@ void LLFloaterBvhPreview::onCommitLoopOut()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitName()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -770,7 +776,7 @@ void LLFloaterBvhPreview::onCommitEmote()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitPriority()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -784,7 +790,7 @@ void LLFloaterBvhPreview::onCommitPriority()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitEaseIn()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -799,7 +805,7 @@ void LLFloaterBvhPreview::onCommitEaseIn()
//-----------------------------------------------------------------------------
void LLFloaterBvhPreview::onCommitEaseOut()
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -814,7 +820,7 @@ void LLFloaterBvhPreview::onCommitEaseOut()
//-----------------------------------------------------------------------------
bool LLFloaterBvhPreview::validateEaseIn(const LLSD& data)
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return false;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -834,7 +840,7 @@ bool LLFloaterBvhPreview::validateEaseIn(const LLSD& data)
//-----------------------------------------------------------------------------
bool LLFloaterBvhPreview::validateEaseOut(const LLSD& data)
{
- if (!getEnabled())
+ if (!getEnabled() || !mAnimPreview)
return false;
LLVOAvatar* avatarp = mAnimPreview->getDummyAvatar();
@@ -1118,9 +1124,13 @@ BOOL LLPreviewAnimation::render()
LLVertexBuffer::unbind();
LLGLDepthTest gls_depth(GL_TRUE);
- LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
- avatarp->dirtyMesh();
- avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ LLFace* face = avatarp->mDrawable->getFace(0);
+ if (face)
+ {
+ LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
+ avatarp->dirtyMesh();
+ avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ }
}
gGL.color4f(1,1,1,1);
diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp
index f9a403cf9f..116bd241c4 100644
--- a/indra/newview/llfloaterhardwaresettings.cpp
+++ b/indra/newview/llfloaterhardwaresettings.cpp
@@ -37,6 +37,7 @@
#include "llspinctrl.h"
#include "llstartup.h"
#include "lltextbox.h"
+#include "llcombobox.h"
#include "pipeline.h"
// Linden library includes
@@ -99,6 +100,12 @@ void LLFloaterHardwareSettings::refreshEnabledState()
getChildView("vbo")->setEnabled(FALSE);
}
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
+ !gGLManager.mHasVertexBufferObject)
+ {
+ getChildView("texture compression")->setEnabled(FALSE);
+ }
+
// if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
LLSpinCtrl* gamma_ctrl = getChild<LLSpinCtrl>("gamma");
gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
@@ -142,6 +149,13 @@ BOOL LLFloaterHardwareSettings::postBuild()
{
childSetAction("OK", onBtnOK, this);
+ if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
+ { //remove FSAA settings above "4x"
+ LLComboBox* combo = getChild<LLComboBox>("fsaa");
+ combo->remove("8x");
+ combo->remove("16x");
+ }
+
refresh();
center();
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 92ee8ddac6..6b2492d927 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -704,9 +704,13 @@ BOOL LLImagePreviewAvatar::render()
// make sure alpha=0 shows avatar material color
LLGLDisable no_blend(GL_BLEND);
- LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
- gPipeline.enableLightsPreview();
- avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ LLFace* face = avatarp->mDrawable->getFace(0);
+ if (face)
+ {
+ LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool();
+ gPipeline.enableLightsPreview();
+ avatarPoolp->renderAvatars(avatarp); // renders only one avatar
+ }
}
gGL.popUIMatrix();
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index ee18c95b34..cc7c9a5bda 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1901,6 +1901,7 @@ BOOL LLPanelLandOptions::postBuild()
mSnapshotCtrl->setCommitCallback( onCommitAny, this );
mSnapshotCtrl->setAllowNoTexture ( TRUE );
mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mSnapshotCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
}
else
@@ -2226,8 +2227,8 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
BOOL allow_damage = !self->mCheckSafe->get();
BOOL allow_fly = self->mCheckFly->get();
BOOL allow_landmark = TRUE; // cannot restrict landmark creation
- BOOL allow_group_scripts = self->mCheckGroupScripts->get() || self->mCheckOtherScripts->get();
BOOL allow_other_scripts = self->mCheckOtherScripts->get();
+ BOOL allow_group_scripts = self->mCheckGroupScripts->get() || allow_other_scripts;
BOOL allow_publish = FALSE;
BOOL mature_publish = self->mMatureCtrl->get();
BOOL push_restriction = self->mPushRestrictionCtrl->get();
@@ -2240,11 +2241,16 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
LLViewerRegion* region;
region = LLViewerParcelMgr::getInstance()->getSelectionRegion();
- if (!allow_other_scripts && region && region->getAllowDamage())
- {
-
- LLNotificationsUtil::add("UnableToDisableOutsideScripts");
- return;
+ if (region && region->getAllowDamage())
+ { // Damage is allowed on the region - server will always allow scripts
+ if ( (!allow_other_scripts && parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)) ||
+ (!allow_group_scripts && parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS)) )
+ { // Don't allow turning off "Run Scripts" if damage is allowed in the region
+ self->mCheckOtherScripts->set(parcel->getParcelFlag(PF_ALLOW_OTHER_SCRIPTS)); // Restore UI to actual settings
+ self->mCheckGroupScripts->set(parcel->getParcelFlag(PF_ALLOW_GROUP_SCRIPTS));
+ LLNotificationsUtil::add("UnableToDisableOutsideScripts");
+ return;
+ }
}
// Push data into current parcel
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 7448f2bb2a..40d2157e28 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -396,7 +396,6 @@ mCalculateBtn(NULL)
sInstance = this;
mLastMouseX = 0;
mLastMouseY = 0;
- mGLName = 0;
mStatusLock = new LLMutex(NULL);
mModelPreview = NULL;
@@ -538,11 +537,6 @@ LLFloaterModelPreview::~LLFloaterModelPreview()
delete mModelPreview;
}
- if (mGLName)
- {
- LLImageGL::deleteTextures(1, &mGLName );
- }
-
delete mStatusLock;
mStatusLock = NULL;
}
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 64324854a5..981f9b0f72 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -256,7 +256,6 @@ protected:
S32 mLastMouseX;
S32 mLastMouseY;
LLRect mPreviewRect;
- U32 mGLName;
static S32 sUploadAmount;
std::set<LLPointer<DecompRequest> > mCurRequest;
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 1fa194ab19..0965b7b533 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -2236,12 +2236,16 @@ void LLFolderView::doIdle()
arrangeAll();
}
+ mNeedsAutoSelect = mFilter->hasFilterString() &&
+ !(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture());
+
+
if (mFilter->isModified() && mFilter->isNotDefault())
{
mNeedsAutoSelect = TRUE;
}
mFilter->clearModified();
-
+
// filter to determine visibility before arranging
filterFromRoot();
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index d2b4866987..515e544452 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -2183,14 +2183,8 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
item->dirtyFilter();
- // Update the folder creation date if the folder has no creation date
- bool setting_date = false;
- const time_t item_creation_date = item->getCreationDate();
- if ((item_creation_date > 0) && (mCreationDate == 0))
- {
- setCreationDate(item_creation_date);
- setting_date = true;
- }
+ // Update the folder creation date if the child is newer than our current date
+ setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
// Handle sorting
requestArrange();
@@ -2200,11 +2194,8 @@ BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
LLFolderViewFolder* parentp = getParentFolder();
while (parentp)
{
- // Update the parent folder creation date
- if (setting_date && (parentp->mCreationDate == 0))
- {
- parentp->setCreationDate(item_creation_date);
- }
+ // Update the folder creation date if the child is newer than our current date
+ parentp->setCreationDate(llmax<time_t>(parentp->mCreationDate, item->getCreationDate()));
if (parentp->mSortFunction.isByDate())
{
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index 30858871ec..72bea8db10 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -220,17 +220,25 @@ bool LLGiveInventory::doGiveInventoryItem(const LLUUID& to_agent,
return res;
}
-void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
+bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
- const LLUUID& im_session_id)
+ const LLUUID& im_session_id,
+ const std::string& notification_name)
{
- if (!cat) return;
+ if (!cat)
+ {
+ return false;
+ }
llinfos << "LLGiveInventory::giveInventoryCategory() - "
<< cat->getUUID() << llendl;
- if (!isAgentAvatarValid()) return;
+ if (!isAgentAvatarValid())
+ {
+ return false;
+ }
+ bool give_successful = true;
// Test out how many items are being given.
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
@@ -253,24 +261,24 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
if (!complete)
{
LLNotificationsUtil::add("IncompleteInventory");
- return;
+ give_successful = false;
}
count = items.count() + cats.count();
if (count > MAX_ITEMS)
{
LLNotificationsUtil::add("TooManyItems");
- return;
+ give_successful = false;
}
else if (count == 0)
{
LLNotificationsUtil::add("NoItems");
- return;
+ give_successful = false;
}
- else
+ else if (give_successful)
{
if (0 == giveable.countNoCopy())
{
- LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
+ give_successful = LLGiveInventory::commitGiveInventoryCategory(to_agent, cat, im_session_id);
}
else
{
@@ -279,9 +287,16 @@ void LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
LLSD payload;
payload["agent_id"] = to_agent;
payload["folder_id"] = cat->getUUID();
+ if (!notification_name.empty())
+ {
+ payload["success_notification"] = notification_name;
+ }
LLNotificationsUtil::add("CannotCopyCountItems", args, payload, &LLGiveInventory::handleCopyProtectedCategory);
+ give_successful = false;
}
}
+
+ return give_successful;
}
//////////////////////////////////////////////////////////////////////////
@@ -325,6 +340,7 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLSD itmes = notification["payload"]["items"];
LLInventoryItem* item = NULL;
+ bool give_successful = true;
switch(option)
{
case 0: // "Yes"
@@ -343,15 +359,21 @@ bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LL
else
{
LLNotificationsUtil::add("CannotGiveItem");
+ give_successful = false;
}
}
+ if (give_successful && notification["payload"]["success_notification"].isDefined())
+ {
+ LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
+ }
break;
default: // no, cancel, whatever, who cares, not yes.
LLNotificationsUtil::add("TransactionCancelled");
+ give_successful = false;
break;
}
- return false;
+ return give_successful;
}
// static
@@ -408,13 +430,14 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLInventoryCategory* cat = NULL;
+ bool give_successful = true;
switch(option)
{
case 0: // "Yes"
cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
if (cat)
{
- LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
+ give_successful = LLGiveInventory::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
cat);
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
@@ -430,27 +453,37 @@ bool LLGiveInventory::handleCopyProtectedCategory(const LLSD& notification, cons
gInventory.deleteObject(items.get(i)->getUUID());
}
gInventory.notifyObservers();
+
+ if (give_successful && notification["payload"]["success_notification"].isDefined())
+ {
+ LLNotificationsUtil::add(notification["payload"]["success_notification"].asString());
+ }
}
else
{
LLNotificationsUtil::add("CannotGiveCategory");
+ give_successful = false;
}
break;
default: // no, cancel, whatever, who cares, not yes.
LLNotificationsUtil::add("TransactionCancelled");
+ give_successful = false;
break;
}
- return false;
+ return give_successful;
}
// static
-void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
+bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
const LLUUID& im_session_id)
{
- if (!cat) return;
+ if (!cat)
+ {
+ return false;
+ }
llinfos << "LLGiveInventory::commitGiveInventoryCategory() - "
<< cat->getUUID() << llendl;
@@ -467,6 +500,7 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
LLInventoryModel::EXCLUDE_TRASH,
giveable);
+ bool give_successful = true;
// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
// 66. I've cut it down a bit from there to give some pad.
@@ -474,12 +508,12 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
if (count > MAX_ITEMS)
{
LLNotificationsUtil::add("TooManyItems");
- return;
+ give_successful = false;
}
else if (count == 0)
{
LLNotificationsUtil::add("NoItems");
- return;
+ give_successful = false;
}
else
{
@@ -545,6 +579,8 @@ void LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
logInventoryOffer(to_agent, im_session_id);
}
+
+ return give_successful;
}
// EOF
diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h
index e1e221c75b..85bc1ed49c 100644
--- a/indra/newview/llgiveinventory.h
+++ b/indra/newview/llgiveinventory.h
@@ -62,9 +62,10 @@ public:
/**
* Gives passed inventory category to specified avatar in specified session.
*/
- static void doGiveInventoryCategory(const LLUUID& to_agent,
+ static bool doGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* item,
- const LLUUID &session_id = LLUUID::null);
+ const LLUUID &session_id = LLUUID::null,
+ const std::string& notification = std::string());
// give inventory item functionality
static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response);
@@ -85,7 +86,7 @@ private:
// give inventory category functionality
static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response);
- static void commitGiveInventoryCategory(const LLUUID& to_agent,
+ static bool commitGiveInventoryCategory(const LLUUID& to_agent,
const LLInventoryCategory* cat,
const LLUUID &im_session_id = LLUUID::null);
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index c8e48b0d42..0f0ae896a2 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -119,6 +119,7 @@ void LLIMFloaterContainer::addFloater(LLFloater* floaterp,
void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
{
mSessions.erase(id);
+ setFocus(TRUE);
}
void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data)
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index a7c4618fa4..4000570872 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -3237,7 +3237,6 @@ public:
//just like a normal IM
//this is just replicated code from process_improved_im
//and should really go in it's own function -jwolk
- LLChat chat;
std::string message = message_params["message"].asString();
std::string name = message_params["from_name"].asString();
@@ -3255,14 +3254,7 @@ public:
name,
LLMute::flagTextChat);
- BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
- std::string separator_string(": ");
-
- chat.mMuted = is_muted && !is_linden;
- chat.mFromID = from_id;
- chat.mFromName = name;
-
- if (!is_linden && is_busy)
+ if (is_busy || is_muted)
{
return;
}
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index acc139c569..a7b93b8030 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -111,6 +111,7 @@ private:
private:
LLUUID mObjectID;
+ LLUUID mPreviousObjectID;
S32 mObjectFace;
viewer_media_t mMediaImpl;
LLMediaEntry* mMediaEntry;
@@ -249,6 +250,7 @@ void LLInspectObject::onClose(bool app_quitting)
{
// Release selection to deselect
mObjectSelection = NULL;
+ mPreviousObjectID = mObjectID;
getChild<LLMenuButton>("gear_btn")->hideMenu();
}
@@ -266,6 +268,13 @@ void LLInspectObject::update()
LLSelectNode* nodep = selection->getFirstRootNode();
if (!nodep) return;
+ // If we don't have fresh object info yet and it's the object we inspected last time,
+ // keep showing the previously retrieved data until we get the update.
+ if (!nodep->mValid && nodep->getObject()->getID() == mPreviousObjectID)
+ {
+ return;
+ }
+
updateButtons(nodep);
updateName(nodep);
updateDescription(nodep);
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 4d0af94f9f..4573074c73 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -654,7 +654,7 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max();
bool is_increasing = hours > mFilterOps.mHoursAgo;
- bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo;
+ bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo && !isSinceLogoff();
// *NOTE: need to cache last filter time, in case filter goes stale
BOOL less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 85ecb133d0..5485242236 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -822,6 +822,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)
{
parent_id = findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
new_item->setParent(parent_id);
+ LLInventoryModel::update_list_t update;
+ LLInventoryModel::LLCategoryUpdate new_folder(parent_id, 1);
+ update.push_back(new_folder);
+ accountForUpdate(update);
+
}
item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, parent_id);
if(item_array)
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 3a88fbd96d..f8088d04b4 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -60,6 +60,7 @@
#include "llworld.h"
#include "llui.h"
#include "pipeline.h"
+#include "llviewershadermgr.h"
const S32 NUM_AXES = 3;
const S32 MOUSE_DRAG_SLOP = 2; // pixels
@@ -1580,7 +1581,11 @@ void LLManipTranslate::renderSnapGuides()
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
LLGLEnable stipple(GL_LINE_STIPPLE);
gGL.flush();
- glLineStipple(1, 0x3333);
+
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glLineStipple(1, 0x3333);
+ }
switch (mManipPart)
{
@@ -1645,17 +1650,28 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLQuaternion grid_rotation,
LLColor4 inner_color)
{
- if (!gSavedSettings.getBOOL("GridCrossSections"))
+ if (!gSavedSettings.getBOOL("GridCrossSections") || !LLGLSLShader::sNoFixedFunction)
{
return;
}
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+
U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
U32 num_types = LL_ARRAY_SIZE(types);
GLuint stencil_mask = 0xFFFFFFFF;
//stencil in volumes
+
gGL.flush();
+
+ if (shader)
+ {
+ gClipProgram.bind();
+ }
+
{
glStencilMask(stencil_mask);
glClearStencil(1);
@@ -1666,6 +1682,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
glStencilFunc(GL_ALWAYS, 0, stencil_mask);
gGL.setColorMask(false, false);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
gGL.diffuseColor4f(1,1,1,1);
//setup clip plane
@@ -1675,10 +1692,12 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
normal = -normal;
}
F32 d = -(selection_center * normal);
- F64 plane[] = { normal.mV[0], normal.mV[1], normal.mV[2], d };
- LLGLEnable clip(GL_CLIP_PLANE0);
- glClipPlane(GL_CLIP_PLANE0, plane);
+ glh::vec4f plane(normal.mV[0], normal.mV[1], normal.mV[2], d );
+
+ gGL.getModelviewMatrix().inverse().mult_vec_matrix(plane);
+ gClipProgram.uniform4fv("clip_plane", 1, plane.v);
+
BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
@@ -1729,6 +1748,11 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
F32 sz = mGridSizeMeters;
F32 tiles = sz;
+ if (shader)
+ {
+ shader->bind();
+ }
+
//draw volume/plane intersections
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index f461c7e46f..bc7f522848 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1620,7 +1620,7 @@ void LLMeshUploadThread::doWholeModelUpload()
mCurlRequest->process();
//sleep for 10ms to prevent eating a whole core
apr_sleep(10000);
- } while (mCurlRequest->getQueued() > 0);
+ } while (!LLAppViewer::isQuitting() && mCurlRequest->getQueued() > 0);
}
delete mCurlRequest;
@@ -1659,7 +1659,7 @@ void LLMeshUploadThread::requestWholeModelFee()
mCurlRequest->process();
//sleep for 10ms to prevent eating a whole core
apr_sleep(10000);
- } while (mCurlRequest->getQueued() > 0);
+ } while (!LLApp::isQuitting() && mCurlRequest->getQueued() > 0);
delete mCurlRequest;
mCurlRequest = NULL;
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 2a08cb1845..95caa2731a 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -267,7 +267,6 @@ LLNavigationBar::LLNavigationBar()
mBtnForward(NULL),
mBtnHome(NULL),
mCmbLocation(NULL),
- mPurgeTPHistoryItems(false),
mSaveToLocationHistory(false)
{
buildFromFile( "panel_navigation_bar.xml");
@@ -338,12 +337,6 @@ void LLNavigationBar::setVisible(BOOL visible)
void LLNavigationBar::draw()
{
- if(mPurgeTPHistoryItems)
- {
- LLTeleportHistory::getInstance()->purgeItems();
- mPurgeTPHistoryItems = false;
- }
-
if (isBackgroundVisible())
{
static LLUICachedControl<S32> drop_shadow_floater ("DropShadowFloater", 0);
@@ -687,7 +680,7 @@ void LLNavigationBar::clearHistoryCache()
LLLocationHistory* lh = LLLocationHistory::getInstance();
lh->removeItems();
lh->save();
- mPurgeTPHistoryItems= true;
+ LLTeleportHistory::getInstance()->purgeItems();
}
int LLNavigationBar::getDefNavBarHeight()
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index e4ce9e3998..7878bab24e 100644
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -145,7 +145,6 @@ private:
boost::signals2::connection mTeleportFailedConnection;
boost::signals2::connection mTeleportFinishConnection;
boost::signals2::connection mHistoryMenuConnection;
- bool mPurgeTPHistoryItems;
// if true, save location to location history when teleport finishes
bool mSaveToLocationHistory;
};
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index b4224e30e6..705046a517 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -103,15 +103,17 @@ BOOL LLNearbyChatBar::postBuild()
mNearbyChat = getChildView("nearby_chat");
- LLUICtrl* show_btn = getChild<LLUICtrl>("show_nearby_chat");
+ gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE);
+ BOOL show_nearby_chat = gSavedSettings.getBOOL("nearbychat_history_visibility");
+
+ LLButton* show_btn = getChild<LLButton>("show_nearby_chat");
show_btn->setCommitCallback(boost::bind(&LLNearbyChatBar::onToggleNearbyChatPanel, this));
+ show_btn->setToggleState(show_nearby_chat);
mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
mOutputMonitor->setVisible(FALSE);
- gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE);
-
- mNearbyChat->setVisible(gSavedSettings.getBOOL("nearbychat_history_visibility"));
+ showNearbyChatPanel(show_nearby_chat);
// Register for font change notifications
LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
@@ -392,26 +394,23 @@ void LLNearbyChatBar::sendChat( EChatType type )
}
}
-
-void LLNearbyChatBar::onToggleNearbyChatPanel()
+void LLNearbyChatBar::showNearbyChatPanel(bool show)
{
- LLView* nearby_chat = getChildView("nearby_chat");
-
- if (nearby_chat->getVisible())
+ if (!show)
{
- if (!isMinimized())
+ if (mNearbyChat->getVisible() && !isMinimized())
{
mExpandedHeight = getRect().getHeight();
}
setResizeLimits(getMinWidth(), COLLAPSED_HEIGHT);
- nearby_chat->setVisible(FALSE);
+ mNearbyChat->setVisible(FALSE);
reshape(getRect().getWidth(), COLLAPSED_HEIGHT);
enableResizeCtrls(true, true, false);
storeRectControl();
}
else
{
- nearby_chat->setVisible(TRUE);
+ mNearbyChat->setVisible(TRUE);
setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
reshape(getRect().getWidth(), mExpandedHeight);
enableResizeCtrls(true);
@@ -421,6 +420,11 @@ void LLNearbyChatBar::onToggleNearbyChatPanel()
gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible());
}
+void LLNearbyChatBar::onToggleNearbyChatPanel()
+{
+ showNearbyChatPanel(!mNearbyChat->getVisible());
+}
+
void LLNearbyChatBar::setMinimized(BOOL b)
{
LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat");
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 8547cf0bce..0b1c3a4ca4 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -37,6 +37,8 @@
class LLNearbyChatBar : public LLFloater
{
+ LOG_CLASS(LLNearbyChatBar);
+
public:
// constructor for inline chat-bars (e.g. hosted in chat history window)
LLNearbyChatBar(const LLSD& key);
@@ -76,6 +78,7 @@ protected:
/* virtual */ bool applyRectControl();
+ void showNearbyChatPanel(bool show);
void onToggleNearbyChatPanel();
static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 03404e816b..d58d6d536c 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -574,6 +574,7 @@ static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const L
texture_ctrl->setAllowNoTexture(entry->mAllowNoTexture);
// Don't allow (no copy) or (notransfer) textures to be selected.
texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ texture_ctrl->setDnDFilterPermMask(PERM_NONE);
texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);
}
}
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 7301b305b2..3e29805446 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -38,6 +38,7 @@
#include "llfontgl.h"
// project includes
+#include "llagentdata.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcolorswatch.h"
@@ -46,6 +47,7 @@
#include "llface.h"
#include "lllineeditor.h"
#include "llmediaentry.h"
+#include "llnotificationsutil.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
@@ -104,27 +106,11 @@ BOOL LLPanelFace::postBuild()
mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
+ mTextureCtrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onTextureSelectionChanged, this, _1));
mTextureCtrl->setFollowsTop();
mTextureCtrl->setFollowsLeft();
- // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
- mTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
- // Allow any texture to be used during non-immediate mode.
- mTextureCtrl->setNonImmediateFilterPermMask(PERM_NONE);
- LLAggregatePermissions texture_perms;
- if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
- {
- BOOL can_copy =
- texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
- texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
- BOOL can_transfer =
- texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
- texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
- mTextureCtrl->setCanApplyImmediately(can_copy && can_transfer);
- }
- else
- {
- mTextureCtrl->setCanApplyImmediately(FALSE);
- }
+ mTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ mTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
}
mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
@@ -595,28 +581,6 @@ void LLPanelFace::getState()
}
- LLAggregatePermissions texture_perms;
- if(texture_ctrl)
- {
-// texture_ctrl->setValid( editable );
-
- if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
- {
- BOOL can_copy =
- texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
- texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
- BOOL can_transfer =
- texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
- texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
- texture_ctrl->setCanApplyImmediately(can_copy && can_transfer);
- }
- else
- {
- texture_ctrl->setCanApplyImmediately(FALSE);
- }
- }
-
-
// planar align
bool align_planar = false;
bool identical_planar_aligned = false;
@@ -1190,3 +1154,35 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
self->sendTextureInfo();
}
+void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
+{
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
+ if (texture_ctrl)
+ {
+ LLUUID obj_owner_id;
+ std::string obj_owner_name;
+ LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
+
+ LLSaleInfo sale_info;
+ LLSelectMgr::instance().selectGetSaleInfo(sale_info);
+
+ bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this texture?
+ bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this texture?
+ bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply texture belong to the agent?
+ bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply texture not for sale?
+
+ if (can_copy && can_transfer)
+ {
+ texture_ctrl->setCanApply(true, true);
+ return;
+ }
+
+ // if texture has (no-transfer) attribute it can be applied only for object which we own and is not for sale
+ texture_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
+
+ if (gSavedSettings.getBOOL("TextureLivePreview"))
+ {
+ LLNotificationsUtil::add("LivePreviewUnavailable");
+ }
+ }
+}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 42be9b257f..3b5a9b1398 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -91,6 +91,15 @@ protected:
static void onClickAutoFix(void*);
static F32 valueGlow(LLViewerObject* object, S32 face);
+private:
+
+ /*
+ * Checks whether the selected texture from the LLFloaterTexturePicker can be applied to the currently selected object.
+ * If agent selects texture which is not allowed to be applied for the currently selected object,
+ * all controls of the floater texture picker which allow to apply the texture will be disabled.
+ */
+ void onTextureSelectionChanged(LLInventoryItem* itemp);
+
};
#endif
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index b3adfac8a2..26cd3ff1c1 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -85,6 +85,7 @@ BOOL LLPanelLandMedia::postBuild()
mMediaTextureCtrl->setCommitCallback( onCommitAny, this );
mMediaTextureCtrl->setAllowNoTexture ( TRUE );
mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mMediaTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaAutoScaleCheck = getChild<LLCheckBoxCtrl>("media_auto_scale");
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 1f77e7a602..7dfe529b73 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -245,6 +245,7 @@ BOOL LLPanelObject::postBuild()
mCtrlSculptTexture->setDropCallback( boost::bind(&LLPanelObject::onDropSculpt, this, _2 ));
// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mCtrlSculptTexture->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
// Allow any texture to be used during non-immediate mode.
mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
LLAggregatePermissions texture_perms;
diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index e124916c48..cb6989c9dd 100644
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -67,6 +67,19 @@ inline F64 llsgn(const F64 a)
class LLPhysicsMotion
{
public:
+ typedef enum
+ {
+ SMOOTHING = 0,
+ MASS,
+ GRAVITY,
+ SPRING,
+ GAIN,
+ DAMPING,
+ DRAG,
+ MAX_EFFECT,
+ NUM_PARAMS
+ } eParamName;
+
/*
param_driver_name: The param that controls the params that are being affected by the physics.
joint_name: The joint that the body part is attached to. The joint is
@@ -98,6 +111,11 @@ public:
mPositionLastUpdate_local(0)
{
mJointState = new LLJointState;
+
+ for (U32 i = 0; i < NUM_PARAMS; ++i)
+ {
+ mParamCache[i] = NULL;
+ }
}
BOOL initialize();
@@ -111,16 +129,43 @@ public:
return mJointState;
}
protected:
- F32 getParamValue(const std::string& controller_key)
- {
- const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key);
+
+ F32 getParamValue(eParamName param)
+ {
+ static std::string controller_key[] =
+ {
+ "Smoothing",
+ "Mass",
+ "Gravity",
+ "Spring",
+ "Gain",
+ "Damping",
+ "Drag",
+ "MaxEffect"
+ };
+
+ if (!mParamCache[param])
+ {
+ const controller_map_t::const_iterator& entry = mParamControllers.find(controller_key[param]);
if (entry == mParamControllers.end())
{
- return sDefaultController[controller_key];
+ return sDefaultController[controller_key[param]];
}
const std::string& param_name = (*entry).second.c_str();
- return mCharacter->getVisualParamWeight(param_name.c_str());
- }
+ mParamCache[param] = mCharacter->getVisualParam(param_name.c_str());
+ }
+
+ if (mParamCache[param])
+ {
+ return mParamCache[param]->getWeight();
+ }
+ else
+ {
+ return sDefaultController[controller_key[param]];
+ }
+ }
+
+
void setParamValue(LLViewerVisualParam *param,
const F32 new_value_local,
F32 behavior_maxeffect);
@@ -150,6 +195,8 @@ private:
F32 mLastTime;
+ LLVisualParam* mParamCache[NUM_PARAMS];
+
static default_controller_map_t sDefaultController;
};
@@ -427,7 +474,6 @@ BOOL LLPhysicsMotionController::onUpdate(F32 time, U8* joint_mask)
return TRUE;
}
-
// Return TRUE if character has to update visual params.
BOOL LLPhysicsMotion::onUpdate(F32 time)
{
@@ -471,15 +517,16 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
LLJoint *joint = mJointState->getJoint();
- const F32 behavior_mass = getParamValue("Mass");
- const F32 behavior_gravity = getParamValue("Gravity");
- const F32 behavior_spring = getParamValue("Spring");
- const F32 behavior_gain = getParamValue("Gain");
- const F32 behavior_damping = getParamValue("Damping");
- const F32 behavior_drag = getParamValue("Drag");
- const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts.
+ const F32 behavior_mass = getParamValue(MASS);
+ const F32 behavior_gravity = getParamValue(GRAVITY);
+ const F32 behavior_spring = getParamValue(SPRING);
+ const F32 behavior_gain = getParamValue(GAIN);
+ const F32 behavior_damping = getParamValue(DAMPING);
+ const F32 behavior_drag = getParamValue(DRAG);
+ F32 behavior_maxeffect = getParamValue(MAX_EFFECT);
+
+ const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts.
- F32 behavior_maxeffect = getParamValue("MaxEffect");
if (physics_test)
behavior_maxeffect = 1.0f;
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
index 450f9b2be7..3baa1eccc8 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/newview/llpolymesh.cpp
@@ -229,15 +229,18 @@ U32 LLPolyMeshSharedData::getNumKB()
BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
{
U32 i;
- mBaseCoords = new LLVector3[ numVertices ];
- mBaseNormals = new LLVector3[ numVertices ];
- mBaseBinormals = new LLVector3[ numVertices ];
+ mBaseCoords = new LLVector4a[ numVertices ];
+ mBaseNormals = new LLVector4a[ numVertices ];
+ mBaseBinormals = new LLVector4a[ numVertices ];
mTexCoords = new LLVector2[ numVertices ];
mDetailTexCoords = new LLVector2[ numVertices ];
mWeights = new F32[ numVertices ];
for (i = 0; i < numVertices; i++)
{
- mWeights[i] = 0.f;
+ mBaseCoords[i].clear();
+ mBaseNormals[i].clear();
+ mBaseBinormals[i].clear();
+ mWeights[i] = 0.f;
}
mNumVertices = numVertices;
return TRUE;
@@ -408,39 +411,47 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
allocateVertexData( numVertices );
- //----------------------------------------------------------------
- // Coords
- //----------------------------------------------------------------
- numRead = fread(mBaseCoords, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseCoords, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << "can't read Coordinates from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // Normals
- //----------------------------------------------------------------
- numRead = fread(mBaseNormals, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseNormals, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << " can't read Normals from " << fileName << llendl;
- return FALSE;
- }
-
- //----------------------------------------------------------------
- // Binormals
- //----------------------------------------------------------------
- numRead = fread(mBaseBinormals, 3*sizeof(float), numVertices, fp);
- llendianswizzle(mBaseBinormals, sizeof(float), 3*numVertices);
- if (numRead != numVertices)
- {
- llerrs << " can't read Binormals from " << fileName << llendl;
- return FALSE;
- }
-
+ for (U16 i = 0; i < numVertices; ++i)
+ {
+ //----------------------------------------------------------------
+ // Coords
+ //----------------------------------------------------------------
+ numRead = fread(&mBaseCoords[i], sizeof(float), 3, fp);
+ llendianswizzle(&mBaseCoords[i], sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << "can't read Coordinates from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+
+ for (U16 i = 0; i < numVertices; ++i)
+ {
+ //----------------------------------------------------------------
+ // Normals
+ //----------------------------------------------------------------
+ numRead = fread(&mBaseNormals[i], sizeof(float), 3, fp);
+ llendianswizzle(&mBaseNormals[i], sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << " can't read Normals from " << fileName << llendl;
+ return FALSE;
+ }
+ }
+
+ for (U16 i = 0; i < numVertices; ++i)
+ {
+ //----------------------------------------------------------------
+ // Binormals
+ //----------------------------------------------------------------
+ numRead = fread(&mBaseBinormals[i], sizeof(float), 3, fp);
+ llendianswizzle(&mBaseBinormals[i], sizeof(float), 3);
+ if (numRead != 3)
+ {
+ llerrs << " can't read Binormals from " << fileName << llendl;
+ return FALSE;
+ }
+ }
//----------------------------------------------------------------
// TexCoords
@@ -767,21 +778,28 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_
{
// Allocate memory without initializing every vector
// NOTE: This makes asusmptions about the size of LLVector[234]
- int nverts = mSharedData->mNumVertices;
- int nfloats = nverts * (2*4 + 3*3 + 2 + 4);
+ S32 nverts = mSharedData->mNumVertices;
+ //make sure it's an even number of verts for alignment
+ nverts += nverts%2;
+ S32 nfloats = nverts * (
+ 4 + //coords
+ 4 + //normals
+ 4 + //weights
+ 2 + //coords
+ 4 + //scaled normals
+ 4 + //binormals
+ 4); //scaled binormals
+
//use 16 byte aligned vertex data to make LLPolyMesh SSE friendly
mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4);
- int offset = 0;
- mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
- mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
- mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
- mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
-
- // these members don't need to be 16-byte aligned, but the first one might be
- // read during an aligned memcpy of mTexCoords
- mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
- mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
+ S32 offset = 0;
+ mCoords = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mNormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mClothingWeights = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
+ mScaledNormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mBinormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
+ mScaledBinormals = (LLVector4a*)(mVertexData + offset); offset += 4*nverts;
initializeForMorph();
}
}
@@ -906,7 +924,7 @@ void LLPolyMesh::dumpDiagInfo()
//-----------------------------------------------------------------------------
// getWritableCoords()
//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableCoords()
+LLVector4a *LLPolyMesh::getWritableCoords()
{
return mCoords;
}
@@ -914,7 +932,7 @@ LLVector4 *LLPolyMesh::getWritableCoords()
//-----------------------------------------------------------------------------
// getWritableNormals()
//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableNormals()
+LLVector4a *LLPolyMesh::getWritableNormals()
{
return mNormals;
}
@@ -922,7 +940,7 @@ LLVector4 *LLPolyMesh::getWritableNormals()
//-----------------------------------------------------------------------------
// getWritableBinormals()
//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getWritableBinormals()
+LLVector4a *LLPolyMesh::getWritableBinormals()
{
return mBinormals;
}
@@ -931,7 +949,7 @@ LLVector3 *LLPolyMesh::getWritableBinormals()
//-----------------------------------------------------------------------------
// getWritableClothingWeights()
//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableClothingWeights()
+LLVector4a *LLPolyMesh::getWritableClothingWeights()
{
return mClothingWeights;
}
@@ -947,7 +965,7 @@ LLVector2 *LLPolyMesh::getWritableTexCoords()
//-----------------------------------------------------------------------------
// getScaledNormals()
//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getScaledNormals()
+LLVector4a *LLPolyMesh::getScaledNormals()
{
return mScaledNormals;
}
@@ -955,7 +973,7 @@ LLVector3 *LLPolyMesh::getScaledNormals()
//-----------------------------------------------------------------------------
// getScaledBinormals()
//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getScaledBinormals()
+LLVector4a *LLPolyMesh::getScaledBinormals()
{
return mScaledBinormals;
}
@@ -966,17 +984,17 @@ LLVector3 *LLPolyMesh::getScaledBinormals()
//-----------------------------------------------------------------------------
void LLPolyMesh::initializeForMorph()
{
- for (U32 i = 0; i < mSharedData->mNumVertices; ++i)
+ LLVector4a::memcpyNonAliased16((F32*) mCoords, (F32*) mSharedData->mBaseCoords, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
+ LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2));
+
+ for (U32 i = 0; i < mSharedData->mNumVertices; ++i)
{
- mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]);
- mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]);
+ mClothingWeights[i].clear();
}
-
- memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memcpy(mTexCoords, mSharedData->mTexCoords, sizeof(LLVector2) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
- memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
}
//-----------------------------------------------------------------------------
@@ -1098,7 +1116,7 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
{
mAvatar = avatarp;
- mDefaultVec.setVec(0.001f, 0.001f, 0.001f);
+ mDefaultVec.splat(0.001f);
}
//-----------------------------------------------------------------------------
@@ -1171,8 +1189,12 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
//-----------------------------------------------------------------------------
// apply()
//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
+
void LLPolySkeletalDistortion::apply( ESex avatar_sex )
{
+ LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY);
+
F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
LLJoint* joint;
@@ -1228,11 +1250,14 @@ LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
{
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
cloned_morph_data->mName = name;
+ LLVector4a dir;
+ dir.load3(direction.mV);
+
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
{
- cloned_morph_data->mCoords[v] = direction;
- cloned_morph_data->mNormals[v] = LLVector3(0,0,0);
- cloned_morph_data->mBinormals[v] = LLVector3(0,0,0);
+ cloned_morph_data->mCoords[v] = dir;
+ cloned_morph_data->mNormals[v].clear();
+ cloned_morph_data->mBinormals[v].clear();
}
return cloned_morph_data;
}
@@ -1243,17 +1268,27 @@ LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
{
LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
cloned_morph_data->mName = name;
+
+ LLVector4a sc;
+ sc.splat(scale);
+
+ LLVector4a nsc;
+ nsc.set(scale, -scale, scale, scale);
+
for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
{
- cloned_morph_data->mCoords[v] = src_data->mCoords[v]*scale;
- cloned_morph_data->mNormals[v] = src_data->mNormals[v]*scale;
- cloned_morph_data->mBinormals[v] = src_data->mBinormals[v]*scale;
- if (cloned_morph_data->mCoords[v][1] < 0)
- {
- cloned_morph_data->mCoords[v][1] *= -1;
- cloned_morph_data->mNormals[v][1] *= -1;
- cloned_morph_data->mBinormals[v][1] *= -1;
- }
+ if (cloned_morph_data->mCoords[v][1] < 0)
+ {
+ cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
+ cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
+ cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
+ }
+ else
+ {
+ cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
+ cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
+ cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
+ }
}
return cloned_morph_data;
}
diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h
index ba2bf85570..ffb11a3f7e 100644
--- a/indra/newview/llpolymesh.h
+++ b/indra/newview/llpolymesh.h
@@ -73,9 +73,9 @@ private:
// vertex data
S32 mNumVertices;
- LLVector3 *mBaseCoords;
- LLVector3 *mBaseNormals;
- LLVector3 *mBaseBinormals;
+ LLVector4a *mBaseCoords;
+ LLVector4a *mBaseNormals;
+ LLVector4a *mBaseBinormals;
LLVector2 *mTexCoords;
LLVector2 *mDetailTexCoords;
F32 *mWeights;
@@ -217,41 +217,41 @@ public:
}
// Get coords
- const LLVector4 *getCoords() const{
+ const LLVector4a *getCoords() const{
return mCoords;
}
// non const version
- LLVector4 *getWritableCoords();
+ LLVector4a *getWritableCoords();
// Get normals
- const LLVector4 *getNormals() const{
+ const LLVector4a *getNormals() const{
return mNormals;
}
// Get normals
- const LLVector3 *getBinormals() const{
+ const LLVector4a *getBinormals() const{
return mBinormals;
}
// Get base mesh normals
- const LLVector3 *getBaseNormals() const{
+ const LLVector4a *getBaseNormals() const{
llassert(mSharedData);
return mSharedData->mBaseNormals;
}
// Get base mesh normals
- const LLVector3 *getBaseBinormals() const{
+ const LLVector4a *getBaseBinormals() const{
llassert(mSharedData);
return mSharedData->mBaseBinormals;
}
// intermediate morphed normals and output normals
- LLVector4 *getWritableNormals();
- LLVector3 *getScaledNormals();
+ LLVector4a *getWritableNormals();
+ LLVector4a *getScaledNormals();
- LLVector3 *getWritableBinormals();
- LLVector3 *getScaledBinormals();
+ LLVector4a *getWritableBinormals();
+ LLVector4a *getScaledBinormals();
// Get texCoords
const LLVector2 *getTexCoords() const {
@@ -275,9 +275,9 @@ public:
F32 *getWritableWeights() const;
- LLVector4 *getWritableClothingWeights();
+ LLVector4a *getWritableClothingWeights();
- const LLVector4 *getClothingWeights()
+ const LLVector4a *getClothingWeights()
{
return mClothingWeights;
}
@@ -341,17 +341,17 @@ protected:
// Single array of floats for allocation / deletion
F32 *mVertexData;
// deformed vertices (resulting from application of morph targets)
- LLVector4 *mCoords;
+ LLVector4a *mCoords;
// deformed normals (resulting from application of morph targets)
- LLVector3 *mScaledNormals;
+ LLVector4a *mScaledNormals;
// output normals (after normalization)
- LLVector4 *mNormals;
+ LLVector4a *mNormals;
// deformed binormals (resulting from application of morph targets)
- LLVector3 *mScaledBinormals;
+ LLVector4a *mScaledBinormals;
// output binormals (after normalization)
- LLVector3 *mBinormals;
+ LLVector4a *mBinormals;
// weight values that mark verts as clothing/skin
- LLVector4 *mClothingWeights;
+ LLVector4a *mClothingWeights;
// output texture coordinates
LLVector2 *mTexCoords;
@@ -419,17 +419,17 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 0.1f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mDefaultVec; }
+ /*virtual*/ const LLVector4a& getAvgDistortion() { return mDefaultVec; }
/*virtual*/ F32 getMaxDistortion() { return 0.1f; }
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector3(0.001f, 0.001f, 0.001f);}
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);}
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
protected:
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
joint_vec_map_t mJointScales;
joint_vec_map_t mJointOffsets;
- LLVector3 mDefaultVec;
+ LLVector4a mDefaultVec;
// Backlink only; don't make this an LLPointer.
LLVOAvatar *mAvatar;
};
diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp
index cefd7df3fe..d25d1420ee 100644
--- a/indra/newview/llpolymorph.cpp
+++ b/indra/newview/llpolymorph.cpp
@@ -48,7 +48,7 @@ LLPolyMorphData::LLPolyMorphData(const std::string& morph_name)
mNumIndices = 0;
mCurrentIndex = 0;
mTotalDistortion = 0.f;
- mAvgDistortion.zeroVec();
+ mAvgDistortion.clear();
mMaxDistortion = 0.f;
mVertexIndices = NULL;
mCoords = NULL;
@@ -73,9 +73,9 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :
{
const S32 numVertices = mNumIndices;
- mCoords = new LLVector3[numVertices];
- mNormals = new LLVector3[numVertices];
- mBinormals = new LLVector3[numVertices];
+ mCoords = new LLVector4a[numVertices];
+ mNormals = new LLVector4a[numVertices];
+ mBinormals = new LLVector4a[numVertices];
mTexCoords = new LLVector2[numVertices];
mVertexIndices = new U32[numVertices];
@@ -121,16 +121,16 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
//-------------------------------------------------------------------------
// allocate vertices
//-------------------------------------------------------------------------
- mCoords = new LLVector3[numVertices];
- mNormals = new LLVector3[numVertices];
- mBinormals = new LLVector3[numVertices];
+ mCoords = new LLVector4a[numVertices];
+ mNormals = new LLVector4a[numVertices];
+ mBinormals = new LLVector4a[numVertices];
mTexCoords = new LLVector2[numVertices];
// Actually, we are allocating more space than we need for the skiplist
mVertexIndices = new U32[numVertices];
mNumIndices = 0;
mTotalDistortion = 0.f;
mMaxDistortion = 0.f;
- mAvgDistortion.zeroVec();
+ mAvgDistortion.clear();
mMesh = mesh;
//-------------------------------------------------------------------------
@@ -152,36 +152,36 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
}
- numRead = fread(&mCoords[v].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mCoords[v].mV, sizeof(F32), 3);
+ numRead = fread(&mCoords[v], sizeof(F32), 3, fp);
+ llendianswizzle(&mCoords[v], sizeof(F32), 3);
if (numRead != 3)
{
llwarns << "Can't read morph target vertex coordinates" << llendl;
return FALSE;
}
- F32 magnitude = mCoords[v].magVec();
+ F32 magnitude = mCoords[v].getLength3().getF32();
mTotalDistortion += magnitude;
- mAvgDistortion.mV[VX] += fabs(mCoords[v].mV[VX]);
- mAvgDistortion.mV[VY] += fabs(mCoords[v].mV[VY]);
- mAvgDistortion.mV[VZ] += fabs(mCoords[v].mV[VZ]);
+ LLVector4a t;
+ t.setAbs(mCoords[v]);
+ mAvgDistortion.add(t);
if (magnitude > mMaxDistortion)
{
mMaxDistortion = magnitude;
}
- numRead = fread(&mNormals[v].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mNormals[v].mV, sizeof(F32), 3);
+ numRead = fread(&mNormals[v], sizeof(F32), 3, fp);
+ llendianswizzle(&mNormals[v], sizeof(F32), 3);
if (numRead != 3)
{
llwarns << "Can't read morph target normal" << llendl;
return FALSE;
}
- numRead = fread(&mBinormals[v].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mBinormals[v].mV, sizeof(F32), 3);
+ numRead = fread(&mBinormals[v], sizeof(F32), 3, fp);
+ llendianswizzle(&mBinormals[v], sizeof(F32), 3);
if (numRead != 3)
{
llwarns << "Can't read morph target binormal" << llendl;
@@ -200,8 +200,8 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
mNumIndices++;
}
- mAvgDistortion = mAvgDistortion * (1.f/(F32)mNumIndices);
- mAvgDistortion.normVec();
+ mAvgDistortion.mul(1.f/(F32)mNumIndices);
+ mAvgDistortion.normalize3fast();
return TRUE;
}
@@ -367,9 +367,9 @@ BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node)
//-----------------------------------------------------------------------------
// getVertexDistortion()
//-----------------------------------------------------------------------------
-LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh)
+LLVector4a LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh)
{
- if (!mMorphData || mMesh != mesh) return LLVector3::zero;
+ if (!mMorphData || mMesh != mesh) return LLVector4a::getZero();
for(U32 index = 0; index < mMorphData->mNumIndices; index++)
{
@@ -379,17 +379,17 @@ LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh
}
}
- return LLVector3::zero;
+ return LLVector4a::getZero();
}
//-----------------------------------------------------------------------------
// getFirstDistortion()
//-----------------------------------------------------------------------------
-const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
+const LLVector4a *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
{
- if (!mMorphData) return &LLVector3::zero;
+ if (!mMorphData) return &LLVector4a::getZero();
- LLVector3* resultVec;
+ LLVector4a* resultVec;
mMorphData->mCurrentIndex = 0;
if (mMorphData->mNumIndices)
{
@@ -411,11 +411,11 @@ const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **
//-----------------------------------------------------------------------------
// getNextDistortion()
//-----------------------------------------------------------------------------
-const LLVector3 *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
+const LLVector4a *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
{
- if (!mMorphData) return &LLVector3::zero;
+ if (!mMorphData) return &LLVector4a::getZero();
- LLVector3* resultVec;
+ LLVector4a* resultVec;
mMorphData->mCurrentIndex++;
if (mMorphData->mCurrentIndex < mMorphData->mNumIndices)
{
@@ -451,7 +451,7 @@ F32 LLPolyMorphTarget::getTotalDistortion()
//-----------------------------------------------------------------------------
// getAvgDistortion()
//-----------------------------------------------------------------------------
-const LLVector3& LLPolyMorphTarget::getAvgDistortion()
+const LLVector4a& LLPolyMorphTarget::getAvgDistortion()
{
if (mMorphData)
{
@@ -459,7 +459,7 @@ const LLVector3& LLPolyMorphTarget::getAvgDistortion()
}
else
{
- return LLVector3::zero;
+ return LLVector4a::getZero();
}
}
@@ -481,6 +481,8 @@ F32 LLPolyMorphTarget::getMaxDistortion()
//-----------------------------------------------------------------------------
// apply()
//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph");
+
void LLPolyMorphTarget::apply( ESex avatar_sex )
{
if (!mMorphData || mNumMorphMasksPending > 0)
@@ -488,6 +490,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
return;
}
+ LLFastTimer t(FTM_APPLY_MORPH_TARGET);
+
mLastSex = avatar_sex;
// Check for NaN condition (NaN is detected if a variable doesn't equal itself.
@@ -508,15 +512,15 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
if (delta_weight != 0.f)
{
llassert(!mMesh->isLOD());
- LLVector4 *coords = mMesh->getWritableCoords();
+ LLVector4a *coords = mMesh->getWritableCoords();
- LLVector3 *scaled_normals = mMesh->getScaledNormals();
- LLVector4 *normals = mMesh->getWritableNormals();
+ LLVector4a *scaled_normals = mMesh->getScaledNormals();
+ LLVector4a *normals = mMesh->getWritableNormals();
- LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
- LLVector3 *binormals = mMesh->getWritableBinormals();
+ LLVector4a *scaled_binormals = mMesh->getScaledBinormals();
+ LLVector4a *binormals = mMesh->getWritableBinormals();
- LLVector4 *clothing_weights = mMesh->getWritableClothingWeights();
+ LLVector4a *clothing_weights = mMesh->getWritableClothingWeights();
LLVector2 *tex_coords = mMesh->getWritableTexCoords();
F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL;
@@ -531,31 +535,38 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
maskWeight = maskWeightArray[vert_index_morph];
}
- coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight);
+
+ LLVector4a pos = mMorphData->mCoords[vert_index_morph];
+ pos.mul(delta_weight*maskWeight);
+ coords[vert_index_mesh].add(pos);
if (getInfo()->mIsClothingMorph && clothing_weights)
{
- LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight;
- LLVector4* clothing_weight = &clothing_weights[vert_index_mesh];
- clothing_weight->mV[VX] += clothing_offset.mV[VX];
- clothing_weight->mV[VY] += clothing_offset.mV[VY];
- clothing_weight->mV[VZ] += clothing_offset.mV[VZ];
- clothing_weight->mV[VW] = maskWeight;
+ LLVector4a clothing_offset = mMorphData->mCoords[vert_index_morph];
+ clothing_offset.mul(delta_weight * maskWeight);
+ LLVector4a* clothing_weight = &clothing_weights[vert_index_mesh];
+ clothing_weight->add(clothing_offset);
+ clothing_weight->getF32ptr()[VW] = maskWeight;
}
// calculate new normals based on half angles
- scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR;
- LLVector3 normalized_normal = scaled_normals[vert_index_mesh];
- normalized_normal.normVec();
- normals[vert_index_mesh] = LLVector4(normalized_normal);
+ LLVector4a norm = mMorphData->mNormals[vert_index_morph];
+ norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);
+ scaled_normals[vert_index_mesh].add(norm);
+ norm = scaled_normals[vert_index_mesh];
+ norm.normalize3fast();
+ normals[vert_index_mesh] = norm;
// calculate new binormals
- scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR;
- LLVector3 tangent = scaled_binormals[vert_index_mesh] % normalized_normal;
- LLVector3 normalized_binormal = normalized_normal % tangent;
- normalized_binormal.normVec();
- binormals[vert_index_mesh] = normalized_binormal;
-
+ LLVector4a binorm = mMorphData->mBinormals[vert_index_morph];
+ binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR);
+ scaled_binormals[vert_index_mesh].add(binorm);
+ LLVector4a tangent;
+ tangent.setCross3(scaled_binormals[vert_index_mesh], norm);
+ LLVector4a& normalized_binormal = binormals[vert_index_mesh];
+ normalized_binormal.setCross3(norm, tangent);
+ normalized_binormal.normalize3fast();
+
tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight;
}
@@ -582,7 +593,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
//-----------------------------------------------------------------------------
void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert)
{
- LLVector4 *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;
+ LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;
if (!mVertMask)
{
@@ -596,29 +607,47 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3
if (maskWeights)
{
- LLVector4 *coords = mMesh->getWritableCoords();
- LLVector3 *scaled_normals = mMesh->getScaledNormals();
- LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
+ LLVector4a *coords = mMesh->getWritableCoords();
+ LLVector4a *scaled_normals = mMesh->getScaledNormals();
+ LLVector4a *scaled_binormals = mMesh->getScaledBinormals();
LLVector2 *tex_coords = mMesh->getWritableTexCoords();
+ LLVector4Logical clothing_mask;
+ clothing_mask.clear();
+ clothing_mask.setElement<0>();
+ clothing_mask.setElement<1>();
+ clothing_mask.setElement<2>();
+
+
for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++)
{
F32 lastMaskWeight = mLastWeight * maskWeights[vert];
S32 out_vert = mMorphData->mVertexIndices[vert];
// remove effect of existing masked morph
- coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight;
- scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR;
- scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR;
+ LLVector4a t;
+ t = mMorphData->mCoords[vert];
+ t.mul(lastMaskWeight);
+ coords[out_vert].sub(t);
+
+ t = mMorphData->mNormals[vert];
+ t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR);
+ scaled_normals[out_vert].sub(t);
+
+ t = mMorphData->mBinormals[vert];
+ t.mul(lastMaskWeight*NORMAL_SOFTEN_FACTOR);
+ scaled_binormals[out_vert].sub(t);
+
tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight;
if (clothing_weights)
{
- LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight;
- LLVector4* clothing_weight = &clothing_weights[out_vert];
- clothing_weight->mV[VX] -= clothing_offset.mV[VX];
- clothing_weight->mV[VY] -= clothing_offset.mV[VY];
- clothing_weight->mV[VZ] -= clothing_offset.mV[VZ];
+ LLVector4a clothing_offset = mMorphData->mCoords[vert];
+ clothing_offset.mul(lastMaskWeight);
+ LLVector4a* clothing_weight = &clothing_weights[out_vert];
+ LLVector4a t;
+ t.setSub(*clothing_weight, clothing_offset);
+ clothing_weight->setSelectWithMask(clothing_mask, t, *clothing_weight);
}
}
}
@@ -654,7 +683,7 @@ LLPolyVertexMask::~LLPolyVertexMask()
//-----------------------------------------------------------------------------
// generateMask()
//-----------------------------------------------------------------------------
-void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights)
+void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights)
{
// RN debug output that uses Image Debugger (http://www.cs.unc.edu/~baxter/projects/imdebug/)
// BOOL debugImg = FALSE;
@@ -698,7 +727,7 @@ void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height,
if (clothing_weights)
{
- clothing_weights[vertIndex].mV[VW] = mWeights[index];
+ clothing_weights[vertIndex].getF32ptr()[VW] = mWeights[index];
}
}
mWeightsGenerated = TRUE;
diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h
index 8a024f2e9e..46e23b7792 100644
--- a/indra/newview/llpolymorph.h
+++ b/indra/newview/llpolymorph.h
@@ -58,14 +58,14 @@ public:
U32 mNumIndices;
U32* mVertexIndices;
U32 mCurrentIndex;
- LLVector3* mCoords;
- LLVector3* mNormals;
- LLVector3* mBinormals;
+ LLVector4a* mCoords;
+ LLVector4a* mNormals;
+ LLVector4a* mBinormals;
LLVector2* mTexCoords;
F32 mTotalDistortion; // vertex distortion summed over entire morph
F32 mMaxDistortion; // maximum single vertex distortion in a given morph
- LLVector3 mAvgDistortion; // average vertex distortion, to infer directionality of the morph
+ LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph
LLPolyMeshSharedData* mMesh;
};
@@ -78,7 +78,7 @@ public:
LLPolyVertexMask(LLPolyMorphData* morph_data);
~LLPolyVertexMask();
- void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights);
+ void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights);
F32* getMorphMaskWeights();
@@ -157,11 +157,11 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion();
- /*virtual*/ const LLVector3& getAvgDistortion();
+ /*virtual*/ const LLVector4a& getAvgDistortion();
/*virtual*/ F32 getMaxDistortion();
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
void applyMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert);
void addPendingMorphMask() { mNumMorphMasksPending++; }
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 5d7a5b1c59..f86e583b9e 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -40,6 +40,7 @@
#include "llagent.h"
#include "llbutton.h"
+#include "llcallbacklist.h"
#include "llfocusmgr.h"
#include "llnotifications.h"
#include "llprogressbar.h"
@@ -72,6 +73,8 @@ LLProgressView::LLProgressView()
mStartupComplete(false)
{
mUpdateEvents.listen("self", boost::bind(&LLProgressView::handleUpdate, this, _1));
+ mFadeToWorldTimer.stop();
+ mFadeFromLoginTimer.stop();
}
BOOL LLProgressView::postBuild()
@@ -87,8 +90,6 @@ BOOL LLProgressView::postBuild()
mCancelBtn = getChild<LLButton>("cancel_btn");
mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL );
- mFadeToWorldTimer.stop();
- mFadeFromLoginTimer.stop();
getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
@@ -106,6 +107,9 @@ BOOL LLProgressView::postBuild()
LLProgressView::~LLProgressView()
{
+ // Just in case something went wrong, make sure we deregister our idle callback.
+ gIdleCallbacks.deleteFunction(onIdle, this);
+
gFocusMgr.releaseFocusIfNeeded( this );
sInstance = NULL;
@@ -154,6 +158,7 @@ void LLProgressView::revealIntroPanel()
}
mFadeFromLoginTimer.start();
+ gIdleCallbacks.addFunction(onIdle, this);
}
void LLProgressView::setStartupComplete()
@@ -236,13 +241,6 @@ void LLProgressView::draw()
}
LLPanel::draw();
-
- if (mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
- {
- mFadeFromLoginTimer.stop();
- LLPanelLogin::closePanel();
- }
-
return;
}
@@ -424,3 +422,21 @@ void LLProgressView::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent even
}
}
}
+
+
+// static
+void LLProgressView::onIdle(void* user_data)
+{
+ LLProgressView* self = (LLProgressView*) user_data;
+
+ // Close login panel on mFadeToWorldTimer expiration.
+ if (self->mFadeFromLoginTimer.getStarted() &&
+ self->mFadeFromLoginTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME)
+ {
+ self->mFadeFromLoginTimer.stop();
+ LLPanelLogin::closePanel();
+
+ // Nothing to do anymore.
+ gIdleCallbacks.deleteFunction(onIdle, user_data);
+ }
+}
diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h
index fac00ad04d..813576b21d 100644
--- a/indra/newview/llprogressview.h
+++ b/indra/newview/llprogressview.h
@@ -41,6 +41,8 @@ class LLProgressView :
public LLViewerMediaObserver
{
+ LOG_CLASS(LLProgressView);
+
public:
LLProgressView();
virtual ~LLProgressView();
@@ -74,10 +76,6 @@ public:
static void onClickMessage(void*);
bool onAlertModal(const LLSD& sd);
- // note - this is not just hiding the intro panel - it also hides the parent panel
- // and is used when the intro is finished and we want to show the world
- void removeIntroPanel();
-
protected:
LLProgressBar* mProgressBar;
LLMediaCtrl* mMediaCtrl;
@@ -96,6 +94,7 @@ protected:
LLEventStream mUpdateEvents;
bool handleUpdate(const LLSD& event_data);
+ static void onIdle(void* user_data);
};
#endif // LL_LLPROGRESSVIEW_H
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 6111255a66..a55565909f 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1508,6 +1508,49 @@ struct LLSelectMgrSendFunctor : public LLSelectedObjectFunctor
}
};
+void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
+{
+ if (!item)
+ {
+ return;
+ }
+ LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID());
+
+ for (iterator iter = begin(); iter != end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = (*iter)->getObject();
+ if (!object)
+ {
+ continue;
+ }
+
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ bool texture_copied = false;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ //(no-copy) textures must be moved to the object's inventory only once
+ // without making any copies
+ if (!texture_copied)
+ {
+ LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ texture_copied = true;
+ }
+
+ // apply texture for the selected faces
+ LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+ object->setTEImage(te, image);
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ object->sendTEUpdate();
+ }
+ }
+ }
+}
+
//-----------------------------------------------------------------------------
// selectionSetImage()
//-----------------------------------------------------------------------------
@@ -1559,8 +1602,18 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
}
return true;
}
- } setfunc(item, imageid);
- getSelection()->applyToTEs(&setfunc);
+ };
+
+ if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ {
+ getSelection()->applyNoCopyTextureToTEs(item);
+ }
+ else
+ {
+ f setfunc(item, imageid);
+ getSelection()->applyToTEs(&setfunc);
+ }
+
struct g : public LLSelectedObjectFunctor
{
@@ -3051,11 +3104,11 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response,
// TODO: Make sure you have delete permissions on all of them.
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
// attempt to derez into the trash.
- LLDeRezInfo* info = new LLDeRezInfo(DRD_TRASH, trash_id);
+ LLDeRezInfo info(DRD_TRASH, trash_id);
LLSelectMgr::getInstance()->sendListToRegions("DeRezObject",
packDeRezHeader,
packObjectLocalID,
- (void*)info,
+ (void*) &info,
SEND_ONLY_ROOTS);
// VEFFECT: Delete Object - one effect for all deletes
if (LLSelectMgr::getInstance()->mSelectedObjects->mSelectType != SELECT_TYPE_HUD)
@@ -3745,13 +3798,15 @@ void LLSelectMgr::deselectAllIfTooFar()
void LLSelectMgr::selectionSetObjectName(const std::string& name)
{
+ std::string name_copy(name);
+
// we only work correctly if 1 object is selected.
if(mSelectedObjects->getRootObjectCount() == 1)
{
sendListToRegions("ObjectName",
packAgentAndSessionID,
packObjectName,
- (void*)(new std::string(name)),
+ (void*)(&name_copy),
SEND_ONLY_ROOTS);
}
else if(mSelectedObjects->getObjectCount() == 1)
@@ -3759,20 +3814,22 @@ void LLSelectMgr::selectionSetObjectName(const std::string& name)
sendListToRegions("ObjectName",
packAgentAndSessionID,
packObjectName,
- (void*)(new std::string(name)),
+ (void*)(&name_copy),
SEND_INDIVIDUALS);
}
}
void LLSelectMgr::selectionSetObjectDescription(const std::string& desc)
{
+ std::string desc_copy(desc);
+
// we only work correctly if 1 object is selected.
if(mSelectedObjects->getRootObjectCount() == 1)
{
sendListToRegions("ObjectDescription",
packAgentAndSessionID,
packObjectDescription,
- (void*)(new std::string(desc)),
+ (void*)(&desc_copy),
SEND_ONLY_ROOTS);
}
else if(mSelectedObjects->getObjectCount() == 1)
@@ -3780,7 +3837,7 @@ void LLSelectMgr::selectionSetObjectDescription(const std::string& desc)
sendListToRegions("ObjectDescription",
packAgentAndSessionID,
packObjectDescription,
- (void*)(new std::string(desc)),
+ (void*)(&desc_copy),
SEND_INDIVIDUALS);
}
}
@@ -4298,15 +4355,14 @@ void LLSelectMgr::packObjectName(LLSelectNode* node, void* user_data)
gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
gMessageSystem->addStringFast(_PREHASH_Name, *name);
}
- delete name;
}
// static
void LLSelectMgr::packObjectDescription(LLSelectNode* node, void* user_data)
{
const std::string* desc = (const std::string*)user_data;
- if(!desc->empty())
- {
+ if(desc)
+ { // Empty (non-null, but zero length) descriptions are OK
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_LocalID, node->getObject()->getLocalID());
gMessageSystem->addStringFast(_PREHASH_Description, *desc);
@@ -5580,7 +5636,7 @@ void pushWireframe(LLDrawable* drawable)
for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
- LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, face.mTexCoords, face.mNumIndices, face.mIndices);
+ LLVertexBuffer::drawElements(LLRender::TRIANGLES, face.mPositions, NULL, face.mNumIndices, face.mIndices);
}
}
@@ -5607,7 +5663,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)
if (shader)
{
- gHighlightProgram.bind();
+ gDebugProgram.bind();
}
gGL.matrixMode(LLRender::MM_MODELVIEW);
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 87ada5ac6b..94606b9fba 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -307,6 +307,15 @@ public:
bool applyToRootNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
bool applyToNodes(LLSelectedNodeFunctor* func, bool firstonly = false);
+ /*
+ * Used to apply (no-copy) textures to the selected object or
+ * selected face/faces of the object.
+ * This method moves (no-copy) texture to the object's inventory
+ * and doesn't make copy of the texture for each face.
+ * Then this only texture is used for all selected faces.
+ */
+ void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
+
ESelectType getSelectType() const { return mSelectType; }
private:
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 1ce05da849..92c2863ffd 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -352,7 +352,7 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
getChildView("BtnCreator")->setEnabled(FALSE);
getChildView("LabelCreatorTitle")->setEnabled(FALSE);
getChildView("LabelCreatorName")->setEnabled(FALSE);
- getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown"));
+ getChild<LLUICtrl>("LabelCreatorName")->setValue(getString("unknown_multiple"));
}
////////////////
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 24cb559fd0..64b82aa0bb 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -94,7 +94,7 @@ BOOL LLSidepanelTaskInfo::postBuild()
mPayBtn = getChild<LLButton>("pay_btn");
mPayBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onPayButtonClicked, this));
mBuyBtn = getChild<LLButton>("buy_btn");
- mBuyBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onBuyButtonClicked, this));
+ mBuyBtn->setClickedCallback(boost::bind(&handle_buy));
mDetailsBtn = getChild<LLButton>("details_btn");
mDetailsBtn->setClickedCallback(boost::bind(&LLSidepanelTaskInfo::onDetailsButtonClicked, this));
@@ -1114,8 +1114,6 @@ void LLSidepanelTaskInfo::doClickAction(U8 click_action)
// Set click action back to its old value
U8 click_action = 0;
LLSelectMgr::getInstance()->selectionGetClickAction(&click_action);
-// box->setCurrentByIndex((S32)click_action);
-
return;
}
}
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5d196a465f..d82b62dc19 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -68,6 +68,7 @@ const F32 SG_OCCLUSION_FUDGE = 0.25f;
#define assert_states_valid(x)
#endif
+extern bool gShiftFrame;
static U32 sZombieGroups = 0;
U32 LLSpatialGroup::sNodeCount = 0;
@@ -85,12 +86,32 @@ static F32 sCurMaxTexPriority = 1.f;
class LLOcclusionQueryPool : public LLGLNamePool
{
+public:
+ LLOcclusionQueryPool()
+ {
+ mCurQuery = 1;
+ }
+
protected:
+
+ std::list<GLuint> mAvailableName;
+ GLuint mCurQuery;
+
virtual GLuint allocateName()
{
- GLuint name;
- glGenQueriesARB(1, &name);
- return name;
+ GLuint ret = 0;
+
+ if (!mAvailableName.empty())
+ {
+ ret = mAvailableName.front();
+ mAvailableName.pop_front();
+ }
+ else
+ {
+ ret = mCurQuery++;
+ }
+
+ return ret;
}
virtual void releaseName(GLuint name)
@@ -98,7 +119,8 @@ protected:
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
LLSpatialGroup::sPendingQueries.erase(name);
#endif
- glDeleteQueriesARB(1, &name);
+ llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end());
+ mAvailableName.push_back(name);
}
};
@@ -259,79 +281,39 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
return (U8*) (sOcclusionIndices+cypher*8);
}
-
-static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
-
-void LLSpatialGroup::buildOcclusion()
+//create a vertex buffer for efficiently rendering cubes
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage)
{
- //if (mOcclusionVerts.isNull())
- {
- mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,
- LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
- mOcclusionVerts->allocateBuffer(8, 64, true);
-
- LLStrider<U16> idx;
- mOcclusionVerts->getIndexStrider(idx);
- for (U32 i = 0; i < 64; i++)
- {
- *idx++ = sOcclusionIndices[i];
- }
- }
+ LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage);
- LLVector4a fudge;
- fudge.splat(SG_OCCLUSION_FUDGE);
-
- LLVector4a r;
- r.setAdd(mBounds[1], fudge);
+ ret->allocateBuffer(8, 64, true);
LLStrider<LLVector3> pos;
-
- {
- LLFastTimer t(FTM_BUILD_OCCLUSION);
- mOcclusionVerts->getVertexStrider(pos);
- }
+ LLStrider<U16> idx;
- {
- LLVector4a* v = (LLVector4a*) pos.get();
+ ret->getVertexStrider(pos);
+ ret->getIndexStrider(idx);
- const LLVector4a& c = mBounds[0];
- const LLVector4a& s = r;
-
- static const LLVector4a octant[] =
- {
- LLVector4a(-1.f, -1.f, -1.f),
- LLVector4a(-1.f, -1.f, 1.f),
- LLVector4a(-1.f, 1.f, -1.f),
- LLVector4a(-1.f, 1.f, 1.f),
-
- LLVector4a(1.f, -1.f, -1.f),
- LLVector4a(1.f, -1.f, 1.f),
- LLVector4a(1.f, 1.f, -1.f),
- LLVector4a(1.f, 1.f, 1.f),
- };
-
- //vertex positions are encoded so the 3 bits of their vertex index
- //correspond to their axis facing, with bit position 3,2,1 matching
- //axis facing x,y,z, bit set meaning positive facing, bit clear
- //meaning negative facing
-
- for (S32 i = 0; i < 8; ++i)
- {
- LLVector4a p;
- p.setMul(s, octant[i]);
- p.add(c);
- v[i] = p;
- }
- }
-
+ pos[0] = LLVector3(-1,-1,-1);
+ pos[1] = LLVector3(-1,-1, 1);
+ pos[2] = LLVector3(-1, 1,-1);
+ pos[3] = LLVector3(-1, 1, 1);
+ pos[4] = LLVector3( 1,-1,-1);
+ pos[5] = LLVector3( 1,-1, 1);
+ pos[6] = LLVector3( 1, 1,-1);
+ pos[7] = LLVector3( 1, 1, 1);
+
+ for (U32 i = 0; i < 64; i++)
{
- mOcclusionVerts->flush();
- LLVertexBuffer::unbind();
+ idx[i] = sOcclusionIndices[i];
}
- clearState(LLSpatialGroup::OCCLUSION_DIRTY);
+ ret->flush();
+
+ return ret;
}
+static LLFastTimer::DeclareTimer FTM_BUILD_OCCLUSION("Build Occlusion");
BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group);
@@ -394,8 +376,6 @@ LLSpatialGroup::~LLSpatialGroup()
}
}
- mOcclusionVerts = NULL;
-
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
clearDrawMap();
clearAtlasList() ;
@@ -562,7 +542,7 @@ void LLSpatialGroup::validate()
validateDrawMap();
- for (element_iter i = getData().begin(); i != getData().end(); ++i)
+ for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
sg_assert(drawable->getSpatialGroup() == this);
@@ -687,6 +667,11 @@ void LLSpatialGroup::rebuildGeom()
if (!isDead())
{
mSpatialPartition->rebuildGeom(this);
+
+ if (isState(LLSpatialGroup::MESH_DIRTY))
+ {
+ gPipeline.markMeshDirty(this);
+ }
}
}
@@ -699,6 +684,9 @@ void LLSpatialGroup::rebuildMesh()
}
static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+static LLFastTimer::DeclareTimer FTM_ADD_GEOMETRY_COUNT("Add Geometry");
+static LLFastTimer::DeclareTimer FTM_CREATE_VB("Create VB");
+static LLFastTimer::DeclareTimer FTM_GET_GEOMETRY("Get Geometry");
void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
{
@@ -720,27 +708,36 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
//get geometry count
U32 index_count = 0;
U32 vertex_count = 0;
-
- addGeometryCount(group, vertex_count, index_count);
+
+ {
+ LLFastTimer t(FTM_ADD_GEOMETRY_COUNT);
+ addGeometryCount(group, vertex_count, index_count);
+ }
if (vertex_count > 0 && index_count > 0)
{ //create vertex buffer containing volume geometry for this node
- group->mBuilt = 1.f;
- if (group->mVertexBuffer.isNull() ||
- !group->mVertexBuffer->isWriteable() ||
- (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
{
- group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
- group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
- stop_glerror();
+ LLFastTimer t(FTM_CREATE_VB);
+ group->mBuilt = 1.f;
+ if (group->mVertexBuffer.isNull() ||
+ !group->mVertexBuffer->isWriteable() ||
+ (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
+ {
+ group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
+ group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true);
+ stop_glerror();
+ }
+ else
+ {
+ group->mVertexBuffer->resizeBuffer(vertex_count, index_count);
+ stop_glerror();
+ }
}
- else
+
{
- group->mVertexBuffer->resizeBuffer(vertex_count, index_count);
- stop_glerror();
+ LLFastTimer t(FTM_GET_GEOMETRY);
+ getGeometry(group);
}
-
- getGeometry(group);
}
else
{
@@ -762,7 +759,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma
{
const OctreeNode* node = mOctreeNode;
- if (node->getData().empty())
+ if (node->isEmpty())
{ //don't do anything if there are no objects
if (empty && mOctreeNode->getParent())
{ //only root is allowed to be empty
@@ -779,14 +776,14 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& ma
clearState(OBJECT_DIRTY);
//initialize bounding box to first element
- OctreeNode::const_element_iter i = node->getData().begin();
+ OctreeNode::const_element_iter i = node->getDataBegin();
LLDrawable* drawablep = *i;
const LLVector4a* minMax = drawablep->getSpatialExtents();
newMin = minMax[0];
newMax = minMax[1];
- for (++i; i != node->getData().end(); ++i)
+ for (++i; i != node->getDataEnd(); ++i)
{
drawablep = *i;
minMax = drawablep->getSpatialExtents();
@@ -927,16 +924,14 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
mObjectExtents[0].add(offset);
mObjectExtents[1].add(offset);
- //if (!mSpatialPartition->mRenderByGroup)
+ if (!mSpatialPartition->mRenderByGroup &&
+ mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TREE &&
+ mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_TERRAIN &&
+ mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_BRIDGE)
{
setState(GEOM_DIRTY);
gPipeline.markRebuild(this, TRUE);
}
-
- if (mOcclusionVerts.notNull())
- {
- setState(OCCLUSION_DIRTY);
- }
}
class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler
@@ -1186,6 +1181,7 @@ void LLSpatialGroup::clearOcclusionState(U32 state, S32 mode)
//======================================
LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
+ mObjectBoxSize(1.f),
mState(0),
mGeometryBytes(0),
mSurfaceArea(0.f),
@@ -1234,8 +1230,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mVisible[i] = 0;
}
- mOcclusionVerts = NULL;
-
mRadius = 1;
mPixelArea = 1024.f;
}
@@ -1248,13 +1242,18 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
return;
}
+ if (gShiftFrame)
+ {
+ return;
+ }
+
#if !LL_RELEASE_FOR_DOWNLOAD
if (isState(LLSpatialGroup::OBJECT_DIRTY))
{
llerrs << "Spatial group dirty on distance update." << llendl;
}
#endif
- if (!getData().empty())
+ if (!isEmpty())
{
mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].getLength3().getF32() :
(F32) mOctreeNode->getSize().getLength3().getF32();
@@ -1405,7 +1404,7 @@ void LLSpatialGroup::handleDestruction(const TreeNode* node)
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
setState(DEAD);
- for (element_iter i = getData().begin(); i != getData().end(); ++i)
+ for (element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
if (drawable->getSpatialGroup() == this)
@@ -1464,10 +1463,14 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo
unbound();
}
-void LLSpatialGroup::destroyGL()
+void LLSpatialGroup::destroyGL(bool keep_occlusion)
{
setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
- gPipeline.markRebuild(this, TRUE);
+
+ if (!keep_occlusion)
+ { //going to need a rebuild
+ gPipeline.markRebuild(this, TRUE);
+ }
mLastUpdateTime = gFrameTimeSeconds;
mVertexBuffer = NULL;
@@ -1475,24 +1478,29 @@ void LLSpatialGroup::destroyGL()
clearDrawMap();
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ if (!keep_occlusion)
{
- if (mOcclusionQuery[i])
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
{
- sQueryPool.release(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
+ if (mOcclusionQuery[i])
+ {
+ sQueryPool.release(mOcclusionQuery[i]);
+ mOcclusionQuery[i] = 0;
+ }
}
}
- mOcclusionVerts = NULL;
- for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = getDataBegin(); i != getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
for (S32 j = 0; j < drawable->getNumFaces(); j++)
{
LLFace* facep = drawable->getFace(j);
- facep->clearVertexBuffer();
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
}
}
}
@@ -1555,15 +1563,13 @@ BOOL LLSpatialGroup::rebound()
mBounds[1].mul(0.5f);
}
- setState(OCCLUSION_DIRTY);
-
clearState(DIRTY);
return TRUE;
}
static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
-static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Occlusion Wait");
void LLSpatialGroup::checkOcclusion()
{
@@ -1583,7 +1589,9 @@ void LLSpatialGroup::checkOcclusion()
{
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
- if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
+ static LLCachedControl<bool> wait_for_query(gSavedSettings, "RenderSynchronousOcclusion");
+
+ if (wait_for_query && mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
{ //query was issued last frame, wait until it's available
S32 max_loop = 1024;
LLFastTimer t(FTM_OCCLUSION_WAIT);
@@ -1634,7 +1642,9 @@ void LLSpatialGroup::checkOcclusion()
else
{
assert_states_valid(this);
+
setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
+
assert_states_valid(this);
}
@@ -1689,12 +1699,6 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
}
- if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY))
- {
- LLFastTimer t(FTM_OCCLUSION_BUILD);
- buildOcclusion();
- }
-
// Depth clamp all water to avoid it being culled as a result of being
// behind the far clip plane, and in the case of edge water to avoid
// it being culled while still visible.
@@ -1725,10 +1729,13 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
}
- {
- LLFastTimer t(FTM_OCCLUSION_SET_BUFFER);
- mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
- }
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ llassert(shader);
+
+ shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mBounds[0].getF32ptr());
+ shader->uniform3f(LLShaderMgr::BOX_SIZE, mBounds[1][0]+SG_OCCLUSION_FUDGE,
+ mBounds[1][1]+SG_OCCLUSION_FUDGE,
+ mBounds[1][2]+SG_OCCLUSION_FUDGE);
if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
{
@@ -1737,12 +1744,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
else
@@ -1750,12 +1757,12 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
LLFastTimer t(FTM_OCCLUSION_DRAW);
if (camera->getOrigin().isExactlyZero())
{ //origin is invalid, draw entire box
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
- mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
@@ -1840,12 +1847,14 @@ BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
- drawablep->setSpatialGroup(NULL);
-
if (!curp->removeObject(drawablep))
{
OCT_ERRS << "Failed to remove drawable from octree!" << llendl;
}
+ else
+ {
+ drawablep->setSpatialGroup(NULL);
+ }
assert_octree_valid(mOctree);
@@ -2116,7 +2125,7 @@ public:
virtual void processGroup(LLSpatialGroup* group)
{
- llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty())
+ llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->isEmpty())
if (mRes < 2)
{
@@ -2183,7 +2192,7 @@ public:
{
LLSpatialGroup::OctreeNode* branch = group->mOctreeNode;
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -2307,7 +2316,7 @@ public:
LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
group->destroyGL();
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
if (drawable->getVObj().notNull() && !group->mSpatialPartition->mRenderByGroup)
@@ -2479,18 +2488,21 @@ void pushVerts(LLSpatialGroup* group, U32 mask)
void pushVerts(LLFace* face, U32 mask)
{
- llassert(face->verify());
+ if (face)
+ {
+ llassert(face->verify());
- LLVertexBuffer* buffer = face->getVertexBuffer();
+ LLVertexBuffer* buffer = face->getVertexBuffer();
- if (buffer && (face->getGeomCount() >= 3))
- {
- buffer->setBuffer(mask);
- U16 start = face->getGeomStart();
- U16 end = start + face->getGeomCount()-1;
- U32 count = face->getIndicesCount();
- U16 offset = face->getIndicesStart();
- buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+ if (buffer && (face->getGeomCount() >= 3))
+ {
+ buffer->setBuffer(mask);
+ U16 start = face->getGeomStart();
+ U16 end = start + face->getGeomCount()-1;
+ U32 count = face->getIndicesCount();
+ U16 offset = face->getIndicesStart();
+ buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
+ }
}
}
@@ -2614,7 +2626,7 @@ void renderOctree(LLSpatialGroup* group)
gGL.flush();
glLineWidth(1.f);
gGL.flush();
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
if (!group->mSpatialPartition->isBridge())
@@ -2627,7 +2639,7 @@ void renderOctree(LLSpatialGroup* group)
for (S32 j = 0; j < drawable->getNumFaces(); j++)
{
LLFace* face = drawable->getFace(j);
- if (face->getVertexBuffer())
+ if (face && face->getVertexBuffer())
{
if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f)
{
@@ -2660,7 +2672,7 @@ void renderOctree(LLSpatialGroup* group)
}
else
{
- if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty()
+ if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty()
&& group->mSpatialPartition->mRenderByGroup)
{
col.setVec(0.8f, 0.4f, 0.1f, 0.1f);
@@ -2728,7 +2740,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
- !group->getData().empty();
+ !group->isEmpty();
if (render_objects)
{
@@ -2756,19 +2768,6 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
}
- /*else if (camera && group->mOcclusionVerts.notNull())
- {
- LLVertexBuffer::unbind();
- group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- gGL.diffuseColor4f(1.0f, 0.f, 0.f, 0.5f);
- group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- gGL.diffuseColor4f(1.0f, 1.f, 1.f, 1.0f);
- group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }*/
}
}
@@ -2998,15 +2997,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
for (S32 i = 0; i < drawable->getNumFaces(); i++)
{
LLFace* facep = drawable->getFace(i);
+ if (facep)
+ {
+ ext = facep->mExtents;
- ext = facep->mExtents;
-
- pos.setAdd(ext[0], ext[1]);
- pos.mul(0.5f);
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
+ pos.setAdd(ext[0], ext[1]);
+ pos.mul(0.5f);
+ size.setSub(ext[1], ext[0]);
+ size.mul(0.5f);
- drawBoxOutline(pos,size);
+ drawBoxOutline(pos,size);
+ }
}
//render drawable bounding box
@@ -3470,7 +3471,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
void renderPhysicsShapes(LLSpatialGroup* group)
{
- for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
LLVOVolume* volume = drawable->getVOVolume();
@@ -3498,18 +3499,21 @@ void renderPhysicsShapes(LLSpatialGroup* group)
for (S32 i = 0; i < drawable->getNumFaces(); ++i)
{
LLFace* face = drawable->getFace(i);
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (buff)
+ if (face)
{
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
- buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+ buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
+ buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
- gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+ gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+ }
}
}
}
@@ -3533,6 +3537,7 @@ void renderTexturePriority(LLDrawable* drawable)
//LLViewerTexture* imagep = facep->getTexture();
//if (imagep)
+ if (facep)
{
//F32 vsize = imagep->mMaxVirtualSize;
@@ -3585,7 +3590,11 @@ void renderPoints(LLDrawable* drawablep)
gGL.diffuseColor3f(1,1,1);
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
- gGL.vertex3fv(drawablep->getFace(i)->mCenterLocal.mV);
+ LLFace * face = drawablep->getFace(i);
+ if (face)
+ {
+ gGL.vertex3fv(face->mCenterLocal.mV);
+ }
}
gGL.end();
}
@@ -3662,7 +3671,11 @@ void renderLights(LLDrawable* drawablep)
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
- pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
+ LLFace * face = drawablep->getFace(i);
+ if (face)
+ {
+ pushVerts(face, LLVertexBuffer::MAP_VERTEX);
+ }
}
const LLVector4a* ext = drawablep->getSpatialExtents();
@@ -3703,7 +3716,7 @@ public:
LLVector3 center, size;
- if (branch->getData().empty())
+ if (branch->isEmpty())
{
gGL.diffuseColor3f(1.f,0.2f,0.f);
center.set(branch->getCenter().getF32ptr());
@@ -3739,8 +3752,8 @@ public:
}
gGL.begin(LLRender::TRIANGLES);
- for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin();
- iter != branch->getData().end();
+ for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
+ iter != branch->getDataEnd();
++iter)
{
const LLVolumeTriangle* tri = *iter;
@@ -3977,7 +3990,7 @@ public:
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
{
- if (!group->getData().empty())
+ if (!group->isEmpty())
{
gGL.diffuseColor3f(0,0,1);
drawBoxOutline(group->mObjectBounds[0],
@@ -3985,7 +3998,7 @@ public:
}
}
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -4060,18 +4073,21 @@ public:
for (U32 i = 0; i < drawable->getNumFaces(); ++i)
{
LLFace* facep = drawable->getFace(i);
- U8 index = facep->getTextureIndex();
- if (facep->mDrawInfo)
+ if (facep)
{
- if (index < 255)
+ U8 index = facep->getTextureIndex();
+ if (facep->mDrawInfo)
{
- if (facep->mDrawInfo->mTextureList.size() <= index)
- {
- llerrs << "Face texture index out of bounds." << llendl;
- }
- else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
+ if (index < 255)
{
- llerrs << "Face texture index incorrect." << llendl;
+ if (facep->mDrawInfo->mTextureList.size()<= index)
+ {
+ llerrs << "Face texture index out of bounds." << llendl;
+ }
+ else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
+ {
+ llerrs << "Face texture index incorrect." << llendl;
+ }
}
}
}
@@ -4167,7 +4183,7 @@ public:
return;
}
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
@@ -4390,7 +4406,7 @@ public:
virtual void visit(const LLSpatialGroup::OctreeNode* branch)
{
- for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i)
+ for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getDataBegin(); i != branch->getDataEnd(); ++i)
{
check(*i);
}
@@ -4576,28 +4592,62 @@ LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
LLCullResult::LLCullResult()
{
+ mVisibleGroupsAllocated = 0;
+ mAlphaGroupsAllocated = 0;
+ mOcclusionGroupsAllocated = 0;
+ mDrawableGroupsAllocated = 0;
+ mVisibleListAllocated = 0;
+ mVisibleBridgeAllocated = 0;
+
+ mVisibleGroups = NULL;
+ mVisibleGroupsEnd = NULL;
+ mAlphaGroups = NULL;
+ mAlphaGroupsEnd = NULL;
+ mOcclusionGroups = NULL;
+ mOcclusionGroupsEnd = NULL;
+ mDrawableGroups = NULL;
+ mDrawableGroupsEnd = NULL;
+ mVisibleList = NULL;
+ mVisibleListEnd = NULL;
+ mVisibleBridge = NULL;
+ mVisibleBridgeEnd = NULL;
+
+ for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
+ {
+ mRenderMap[i] = NULL;
+ mRenderMapEnd[i] = NULL;
+ mRenderMapAllocated[i] = 0;
+ }
+
clear();
}
+void LLCullResult::pushBack(void**& head, U32& count, void* val)
+{
+ count++;
+ head = (void**) realloc((void*) head, sizeof(void*) * count);
+ head[count-1] = val;
+}
+
void LLCullResult::clear()
{
mVisibleGroupsSize = 0;
- mVisibleGroupsEnd = mVisibleGroups.begin();
+ mVisibleGroupsEnd = mVisibleGroups;
mAlphaGroupsSize = 0;
- mAlphaGroupsEnd = mAlphaGroups.begin();
+ mAlphaGroupsEnd = mAlphaGroups;
mOcclusionGroupsSize = 0;
- mOcclusionGroupsEnd = mOcclusionGroups.begin();
+ mOcclusionGroupsEnd = mOcclusionGroups;
mDrawableGroupsSize = 0;
- mDrawableGroupsEnd = mDrawableGroups.begin();
+ mDrawableGroupsEnd = mDrawableGroups;
mVisibleListSize = 0;
- mVisibleListEnd = mVisibleList.begin();
+ mVisibleListEnd = mVisibleList;
mVisibleBridgeSize = 0;
- mVisibleBridgeEnd = mVisibleBridge.begin();
+ mVisibleBridgeEnd = mVisibleBridge;
for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
@@ -4607,176 +4657,176 @@ void LLCullResult::clear()
mRenderMap[i][j] = 0;
}
mRenderMapSize[i] = 0;
- mRenderMapEnd[i] = mRenderMap[i].begin();
+ mRenderMapEnd[i] = mRenderMap[i];
}
}
-LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups()
+LLCullResult::sg_iterator LLCullResult::beginVisibleGroups()
{
- return mVisibleGroups.begin();
+ return mVisibleGroups;
}
-LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups()
+LLCullResult::sg_iterator LLCullResult::endVisibleGroups()
{
return mVisibleGroupsEnd;
}
-LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups()
+LLCullResult::sg_iterator LLCullResult::beginAlphaGroups()
{
- return mAlphaGroups.begin();
+ return mAlphaGroups;
}
-LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups()
+LLCullResult::sg_iterator LLCullResult::endAlphaGroups()
{
return mAlphaGroupsEnd;
}
-LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups()
+LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups()
{
- return mOcclusionGroups.begin();
+ return mOcclusionGroups;
}
-LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups()
+LLCullResult::sg_iterator LLCullResult::endOcclusionGroups()
{
return mOcclusionGroupsEnd;
}
-LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups()
+LLCullResult::sg_iterator LLCullResult::beginDrawableGroups()
{
- return mDrawableGroups.begin();
+ return mDrawableGroups;
}
-LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups()
+LLCullResult::sg_iterator LLCullResult::endDrawableGroups()
{
return mDrawableGroupsEnd;
}
-LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList()
+LLCullResult::drawable_iterator LLCullResult::beginVisibleList()
{
- return mVisibleList.begin();
+ return mVisibleList;
}
-LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList()
+LLCullResult::drawable_iterator LLCullResult::endVisibleList()
{
return mVisibleListEnd;
}
-LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge()
+LLCullResult::bridge_iterator LLCullResult::beginVisibleBridge()
{
- return mVisibleBridge.begin();
+ return mVisibleBridge;
}
-LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge()
+LLCullResult::bridge_iterator LLCullResult::endVisibleBridge()
{
return mVisibleBridgeEnd;
}
-LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type)
+LLCullResult::drawinfo_iterator LLCullResult::beginRenderMap(U32 type)
{
- return mRenderMap[type].begin();
+ return mRenderMap[type];
}
-LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type)
+LLCullResult::drawinfo_iterator LLCullResult::endRenderMap(U32 type)
{
return mRenderMapEnd[type];
}
void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)
{
- if (mVisibleGroupsSize < mVisibleGroups.size())
+ if (mVisibleGroupsSize < mVisibleGroupsAllocated)
{
mVisibleGroups[mVisibleGroupsSize] = group;
}
else
{
- mVisibleGroups.push_back(group);
+ pushBack((void**&) mVisibleGroups, mVisibleGroupsAllocated, (void*) group);
}
++mVisibleGroupsSize;
- mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize;
+ mVisibleGroupsEnd = mVisibleGroups+mVisibleGroupsSize;
}
void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)
{
- if (mAlphaGroupsSize < mAlphaGroups.size())
+ if (mAlphaGroupsSize < mAlphaGroupsAllocated)
{
mAlphaGroups[mAlphaGroupsSize] = group;
}
else
{
- mAlphaGroups.push_back(group);
+ pushBack((void**&) mAlphaGroups, mAlphaGroupsAllocated, (void*) group);
}
++mAlphaGroupsSize;
- mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize;
+ mAlphaGroupsEnd = mAlphaGroups+mAlphaGroupsSize;
}
void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)
{
- if (mOcclusionGroupsSize < mOcclusionGroups.size())
+ if (mOcclusionGroupsSize < mOcclusionGroupsAllocated)
{
mOcclusionGroups[mOcclusionGroupsSize] = group;
}
else
{
- mOcclusionGroups.push_back(group);
+ pushBack((void**&) mOcclusionGroups, mOcclusionGroupsAllocated, (void*) group);
}
++mOcclusionGroupsSize;
- mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize;
+ mOcclusionGroupsEnd = mOcclusionGroups+mOcclusionGroupsSize;
}
void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
{
- if (mDrawableGroupsSize < mDrawableGroups.size())
+ if (mDrawableGroupsSize < mDrawableGroupsAllocated)
{
mDrawableGroups[mDrawableGroupsSize] = group;
}
else
{
- mDrawableGroups.push_back(group);
+ pushBack((void**&) mDrawableGroups, mDrawableGroupsAllocated, (void*) group);
}
++mDrawableGroupsSize;
- mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize;
+ mDrawableGroupsEnd = mDrawableGroups+mDrawableGroupsSize;
}
void LLCullResult::pushDrawable(LLDrawable* drawable)
{
- if (mVisibleListSize < mVisibleList.size())
+ if (mVisibleListSize < mVisibleListAllocated)
{
mVisibleList[mVisibleListSize] = drawable;
}
else
{
- mVisibleList.push_back(drawable);
+ pushBack((void**&) mVisibleList, mVisibleListAllocated, (void*) drawable);
}
++mVisibleListSize;
- mVisibleListEnd = mVisibleList.begin()+mVisibleListSize;
+ mVisibleListEnd = mVisibleList+mVisibleListSize;
}
void LLCullResult::pushBridge(LLSpatialBridge* bridge)
{
- if (mVisibleBridgeSize < mVisibleBridge.size())
+ if (mVisibleBridgeSize < mVisibleBridgeAllocated)
{
mVisibleBridge[mVisibleBridgeSize] = bridge;
}
else
{
- mVisibleBridge.push_back(bridge);
+ pushBack((void**&) mVisibleBridge, mVisibleBridgeAllocated, (void*) bridge);
}
++mVisibleBridgeSize;
- mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize;
+ mVisibleBridgeEnd = mVisibleBridge+mVisibleBridgeSize;
}
void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)
{
- if (mRenderMapSize[type] < mRenderMap[type].size())
+ if (mRenderMapSize[type] < mRenderMapAllocated[type])
{
mRenderMap[type][mRenderMapSize[type]] = draw_info;
}
else
{
- mRenderMap[type].push_back(draw_info);
+ pushBack((void**&) mRenderMap[type], mRenderMapAllocated[type], (void*) draw_info);
}
++mRenderMapSize[type];
- mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type];
+ mRenderMapEnd[type] = mRenderMap[type] + mRenderMapSize[type];
}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 6c14ecf452..e82c50b92b 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -263,11 +263,10 @@ public:
SKIP_FRUSTUM_CHECK = 0x00000020,
IN_IMAGE_QUEUE = 0x00000040,
IMAGE_DIRTY = 0x00000080,
- OCCLUSION_DIRTY = 0x00000100,
- MESH_DIRTY = 0x00000200,
- NEW_DRAWINFO = 0x00000400,
- IN_BUILD_Q1 = 0x00000800,
- IN_BUILD_Q2 = 0x00001000,
+ MESH_DIRTY = 0x00000100,
+ NEW_DRAWINFO = 0x00000200,
+ IN_BUILD_Q1 = 0x00000400,
+ IN_BUILD_Q2 = 0x00000800,
STATE_MASK = 0x0000FFFF,
} eSpatialState;
@@ -313,10 +312,9 @@ public:
BOOL boundObjects(BOOL empty, LLVector4a& newMin, LLVector4a& newMax);
void unbound();
BOOL rebound();
- void buildOcclusion(); //rebuild mOcclusionVerts
void checkOcclusion(); //read back last occlusion query (if any)
void doOcclusion(LLCamera* camera); //issue occlusion query
- void destroyGL();
+ void destroyGL(bool keep_occlusion = false);
void updateDistance(LLCamera& camera);
BOOL needsUpdate();
@@ -327,8 +325,13 @@ public:
void dirtyGeom() { setState(GEOM_DIRTY); }
void dirtyMesh() { setState(MESH_DIRTY); }
+
+ //octree wrappers to make code more readable
element_list& getData() { return mOctreeNode->getData(); }
+ element_iter getDataBegin() { return mOctreeNode->getDataBegin(); }
+ element_iter getDataEnd() { return mOctreeNode->getDataEnd(); }
U32 getElementCount() const { return mOctreeNode->getElementCount(); }
+ bool isEmpty() const { return mOctreeNode->isEmpty(); }
void drawObjectBox(LLColor4 col);
@@ -378,6 +381,8 @@ public:
LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node
LLVector4a mViewAngle;
LLVector4a mLastUpdateViewAngle;
+
+ F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3()
private:
U32 mCurUpdatingTime ;
@@ -413,7 +418,6 @@ public:
LLSpatialPartition* mSpatialPartition;
LLPointer<LLVertexBuffer> mVertexBuffer;
- LLPointer<LLVertexBuffer> mOcclusionVerts;
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
U32 mBufferUsage;
@@ -543,34 +547,39 @@ class LLCullResult
public:
LLCullResult();
- typedef std::vector<LLSpatialGroup*> sg_list_t;
- typedef std::vector<LLDrawable*> drawable_list_t;
- typedef std::vector<LLSpatialBridge*> bridge_list_t;
- typedef std::vector<LLDrawInfo*> drawinfo_list_t;
+ typedef LLSpatialGroup** sg_list_t;
+ typedef LLDrawable** drawable_list_t;
+ typedef LLSpatialBridge** bridge_list_t;
+ typedef LLDrawInfo** drawinfo_list_t;
+
+ typedef LLSpatialGroup** sg_iterator;
+ typedef LLSpatialBridge** bridge_iterator;
+ typedef LLDrawInfo** drawinfo_iterator;
+ typedef LLDrawable** drawable_iterator;
void clear();
- sg_list_t::iterator beginVisibleGroups();
- sg_list_t::iterator endVisibleGroups();
+ sg_iterator beginVisibleGroups();
+ sg_iterator endVisibleGroups();
- sg_list_t::iterator beginAlphaGroups();
- sg_list_t::iterator endAlphaGroups();
+ sg_iterator beginAlphaGroups();
+ sg_iterator endAlphaGroups();
bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; }
- sg_list_t::iterator beginOcclusionGroups();
- sg_list_t::iterator endOcclusionGroups();
+ sg_iterator beginOcclusionGroups();
+ sg_iterator endOcclusionGroups();
- sg_list_t::iterator beginDrawableGroups();
- sg_list_t::iterator endDrawableGroups();
+ sg_iterator beginDrawableGroups();
+ sg_iterator endDrawableGroups();
- drawable_list_t::iterator beginVisibleList();
- drawable_list_t::iterator endVisibleList();
+ drawable_iterator beginVisibleList();
+ drawable_iterator endVisibleList();
- bridge_list_t::iterator beginVisibleBridge();
- bridge_list_t::iterator endVisibleBridge();
+ bridge_iterator beginVisibleBridge();
+ bridge_iterator endVisibleBridge();
- drawinfo_list_t::iterator beginRenderMap(U32 type);
- drawinfo_list_t::iterator endRenderMap(U32 type);
+ drawinfo_iterator beginRenderMap(U32 type);
+ drawinfo_iterator endRenderMap(U32 type);
void pushVisibleGroup(LLSpatialGroup* group);
void pushAlphaGroup(LLSpatialGroup* group);
@@ -590,28 +599,41 @@ public:
void assertDrawMapsEmpty();
private:
+
+ void pushBack(void** &head, U32& count, void* val);
+
U32 mVisibleGroupsSize;
U32 mAlphaGroupsSize;
U32 mOcclusionGroupsSize;
U32 mDrawableGroupsSize;
U32 mVisibleListSize;
U32 mVisibleBridgeSize;
+
+ U32 mVisibleGroupsAllocated;
+ U32 mAlphaGroupsAllocated;
+ U32 mOcclusionGroupsAllocated;
+ U32 mDrawableGroupsAllocated;
+ U32 mVisibleListAllocated;
+ U32 mVisibleBridgeAllocated;
+
U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];
sg_list_t mVisibleGroups;
- sg_list_t::iterator mVisibleGroupsEnd;
+ sg_iterator mVisibleGroupsEnd;
sg_list_t mAlphaGroups;
- sg_list_t::iterator mAlphaGroupsEnd;
+ sg_iterator mAlphaGroupsEnd;
sg_list_t mOcclusionGroups;
- sg_list_t::iterator mOcclusionGroupsEnd;
+ sg_iterator mOcclusionGroupsEnd;
sg_list_t mDrawableGroups;
- sg_list_t::iterator mDrawableGroupsEnd;
+ sg_iterator mDrawableGroupsEnd;
drawable_list_t mVisibleList;
- drawable_list_t::iterator mVisibleListEnd;
+ drawable_iterator mVisibleListEnd;
bridge_list_t mVisibleBridge;
- bridge_list_t::iterator mVisibleBridgeEnd;
+ bridge_iterator mVisibleBridgeEnd;
drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
- drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
+ U32 mRenderMapAllocated[LLRenderPass::NUM_RENDER_TYPES];
+ drawinfo_iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
+
};
@@ -655,6 +677,7 @@ class LLParticlePartition : public LLSpatialPartition
{
public:
LLParticlePartition();
+ virtual void rebuildGeom(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
@@ -669,10 +692,14 @@ public:
};
//spatial partition for grass (implemented in LLVOGrass.cpp)
-class LLGrassPartition : public LLParticlePartition
+class LLGrassPartition : public LLSpatialPartition
{
public:
LLGrassPartition();
+ virtual void getGeometry(LLSpatialGroup* group);
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
+protected:
+ U32 mRenderPass;
};
//class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index 66df7dae3e..230e871b49 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -56,6 +56,7 @@
#include "lldrawable.h"
extern LLPipeline gPipeline;
+extern bool gShiftFrame;
LLColor4U MAX_WATER_COLOR(0, 48, 96, 240);
@@ -294,7 +295,7 @@ void LLSurface::initTextures()
mWaterObjp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, mRegionp);
gPipeline.createObject(mWaterObjp);
LLVector3d water_pos_global = from_region_handle(mRegionp->getHandle());
- water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT);
+ water_pos_global += LLVector3d(128.0, 128.0, DEFAULT_WATER_HEIGHT); // region doesn't have a valid water height yet
mWaterObjp->setPositionGlobal(water_pos_global);
}
}
@@ -608,6 +609,11 @@ void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta)
void LLSurface::updatePatchVisibilities(LLAgent &agent)
{
+ if (gShiftFrame)
+ {
+ return;
+ }
+
LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());
LLSurfacePatch *patchp;
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 5077c2c7e1..a9ba2bce9c 100644
--- a/indra/newview/llsurfacepatch.cpp
+++ b/indra/newview/llsurfacepatch.cpp
@@ -43,6 +43,7 @@
#include "lldrawpool.h"
#include "noise.h"
+extern bool gShiftFrame;
extern U64 gFrameTime;
extern LLPipeline gPipeline;
@@ -218,7 +219,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3
pos_agent.mV[VX] += x * mSurfacep->getMetersPerGrid();
pos_agent.mV[VY] += y * mSurfacep->getMetersPerGrid();
pos_agent.mV[VZ] = *(mDataZ + point_offset);
- *vertex = pos_agent;
+ *vertex = pos_agent-mVObjp->getRegion()->getOriginAgent();
LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent();
LLVector3 tex_pos = rel_pos * (1.f/surface_stride);
@@ -366,10 +367,13 @@ void LLSurfacePatch::updateCameraDistanceRegion(const LLVector3 &pos_region)
{
if (LLPipeline::sDynamicLOD)
{
- LLVector3 dv = pos_region;
- dv -= mCenterRegion;
- mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
- llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
+ if (!gShiftFrame)
+ {
+ LLVector3 dv = pos_region;
+ dv -= mCenterRegion;
+ mVisInfo.mDistance = llmax(0.f, (F32)(dv.magVec() - mRadius))/
+ llmax(LLVOSurfacePatch::sLODFactor, 0.1f);
+ }
}
else
{
diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h
index 74c22b0cdf..2c0da60b48 100644
--- a/indra/newview/lltexlayerparams.h
+++ b/indra/newview/lltexlayerparams.h
@@ -76,11 +76,11 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
+ /*virtual*/ const LLVector4a& getAvgDistortion() { return mAvgDistortionVec; }
/*virtual*/ F32 getMaxDistortion() { return 3.f; }
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f);}
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector4a(1.f, 1.f, 1.f);}
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
// New functions
BOOL render( S32 x, S32 y, S32 width, S32 height );
@@ -94,7 +94,7 @@ private:
LLPointer<LLImageRaw> mStaticImageRaw;
BOOL mNeedsCreateTexture;
BOOL mStaticImageInvalid;
- LLVector3 mAvgDistortionVec;
+ LLVector4a mAvgDistortionVec;
F32 mCachedEffectiveWeight;
public:
@@ -155,18 +155,18 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
+ /*virtual*/ const LLVector4a& getAvgDistortion() { return mAvgDistortionVec; }
/*virtual*/ F32 getMaxDistortion() { return 3.f; }
- /*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector3(1.f, 1.f, 1.f); }
- /*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
- /*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
+ /*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh) { return LLVector4a(1.f, 1.f, 1.f); }
+ /*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return &mAvgDistortionVec;};
+ /*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh) { index = 0; poly_mesh = NULL; return NULL;};
// New functions
LLColor4 getNetColor() const;
protected:
virtual void onGlobalColorChanged(bool upload_bake) {}
private:
- LLVector3 mAvgDistortionVec;
+ LLVector4a mAvgDistortionVec;
};
class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp
index d2e4b01732..f8c1bca8ae 100644
--- a/indra/newview/lltextureatlas.cpp
+++ b/indra/newview/lltextureatlas.cpp
@@ -116,7 +116,6 @@ LLGLuint LLTextureAtlas::insertSubTexture(LLImageGL* source_gl_tex, S32 discard_
return 0 ;
}
- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE);
glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h,
mGLTexturep->getPrimaryFormat(), mGLTexturep->getFormatType(), raw_image->getData());
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index ed9faa0706..6703ef4a41 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -97,6 +97,7 @@ public:
LLTextureCtrl* owner,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
+ PermissionMask dnd_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
LLUIImagePtr fallback_image_name);
@@ -134,6 +135,9 @@ public:
void onFilterEdit(const std::string& search_string );
+ void setCanApply(bool can_preview, bool can_apply);
+ void setTextureSelectedCallback(texture_selected_callback cb) {mTextureSelectedCallback = cb;}
+
static void onBtnSetToDefault( void* userdata );
static void onBtnSelect( void* userdata );
static void onBtnCancel( void* userdata );
@@ -175,6 +179,7 @@ protected:
LLFilterEditor* mFilterEdit;
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mNoCopyTextureSelected;
@@ -184,12 +189,18 @@ protected:
LLRadioGroup* mModeSelector;
LLScrollListCtrl* mLocalScrollCtrl;
+
+private:
+ bool mCanApply;
+ bool mCanPreview;
+ texture_selected_callback mTextureSelectedCallback;
};
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLTextureCtrl* owner,
const std::string& label,
PermissionMask immediate_filter_perm_mask,
+ PermissionMask dnd_filter_perm_mask,
PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
LLUIImagePtr fallback_image)
@@ -205,9 +216,12 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mActive( TRUE ),
mFilterEdit(NULL),
mImmediateFilterPermMask(immediate_filter_perm_mask),
+ mDnDFilterPermMask(dnd_filter_perm_mask),
mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
mContextConeOpacity(0.f),
- mSelectedItemPinned( FALSE )
+ mSelectedItemPinned( FALSE ),
+ mCanApply(true),
+ mCanPreview(true)
{
buildFromFile("floater_texture_ctrl.xml");
mCanApplyImmediately = can_apply_immediately;
@@ -319,7 +333,7 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
if (xfer) item_perm_mask |= PERM_TRANSFER;
//PermissionMask filter_perm_mask = getFilterPermMask(); Commented out due to no-copy texture loss.
- PermissionMask filter_perm_mask = mImmediateFilterPermMask;
+ PermissionMask filter_perm_mask = mDnDFilterPermMask;
if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
{
if (drop)
@@ -464,7 +478,7 @@ BOOL LLFloaterTexturePicker::postBuild()
mNoCopyTextureSelected = FALSE;
- getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("ApplyTextureImmediately"));
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
if (!mCanApplyImmediately)
@@ -546,7 +560,7 @@ void LLFloaterTexturePicker::draw()
// if we're inactive, gray out "apply immediate" checkbox
getChildView("show_folders_check")->setEnabled(mActive && mCanApplyImmediately && !mNoCopyTextureSelected);
- getChildView("Select")->setEnabled(mActive);
+ getChildView("Select")->setEnabled(mActive && mCanApply);
getChildView("Pipette")->setEnabled(mActive);
getChild<LLUICtrl>("Pipette")->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
@@ -702,8 +716,7 @@ PermissionMask LLFloaterTexturePicker::getFilterPermMask()
void LLFloaterTexturePicker::commitIfImmediateSet()
{
- bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean();
- if (!mNoCopyTextureSelected && apply_immediate && mOwner)
+ if (!mNoCopyTextureSelected && mOwner && mCanApply)
{
mOwner->onFloaterCommit(LLTextureCtrl::TEXTURE_CHANGE);
}
@@ -713,6 +726,7 @@ void LLFloaterTexturePicker::commitIfImmediateSet()
void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
if (self->mOwner)
{
self->setImageID( self->mOwner->getDefaultImageAssetID() );
@@ -724,6 +738,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
void LLFloaterTexturePicker::onBtnWhite(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
self->setImageID( self->mWhiteImageAssetID );
self->commitIfImmediateSet();
}
@@ -804,13 +819,14 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
mNoCopyTextureSelected = FALSE;
if (itemp)
{
+ mTextureSelectedCallback(itemp);
if (!itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
mNoCopyTextureSelected = TRUE;
}
mImageAssetID = itemp->getAssetUUID();
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
- if (user_action)
+ if (user_action && mCanPreview)
{
// only commit intentional selections, not implicit ones
commitIfImmediateSet();
@@ -947,7 +963,7 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da
LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
- gSavedSettings.setBOOL("ApplyTextureImmediately", check_box->get());
+ gSavedSettings.setBOOL("TextureLivePreview", check_box->get());
picker->updateFilterPermMask();
picker->commitIfImmediateSet();
@@ -958,6 +974,16 @@ void LLFloaterTexturePicker::updateFilterPermMask()
//mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss.
}
+void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply)
+{
+ getChildRef<LLUICtrl>("Select").setEnabled(can_apply);
+ getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview);
+ getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview);
+
+ mCanApply = can_apply;
+ mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false;
+}
+
void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
{
std::string upper_case_search_string = search_string;
@@ -1108,6 +1134,15 @@ void LLTextureCtrl::setCanApplyImmediately(BOOL b)
}
}
+void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply)
+{
+ LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+ if( floaterp )
+ {
+ floaterp->setCanApply(can_preview, can_apply);
+ }
+}
+
void LLTextureCtrl::setVisible( BOOL visible )
{
if( !visible )
@@ -1188,12 +1223,19 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
this,
mLabel,
mImmediateFilterPermMask,
+ mDnDFilterPermMask,
mNonImmediateFilterPermMask,
mCanApplyImmediately,
mFallbackImage);
mFloaterHandle = floaterp->getHandle();
+ LLFloaterTexturePicker* texture_floaterp = dynamic_cast<LLFloaterTexturePicker*>(floaterp);
+ if (texture_floaterp && mOnTextureSelectedCallback)
+ {
+ texture_floaterp->setTextureSelectedCallback(mOnTextureSelectedCallback);
+ }
+
LLFloater* root_floater = gFloaterView->getParentFloater(this);
if (root_floater)
root_floater->addDependentFloater(floaterp);
@@ -1318,6 +1360,16 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
}
}
+void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
+{
+ mOnTextureSelectedCallback = cb;
+ LLFloaterTexturePicker* floaterp = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get());
+ if (floaterp)
+ {
+ floaterp->setTextureSelectedCallback(cb);
+ }
+}
+
void LLTextureCtrl::setImageAssetName(const std::string& name)
{
LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 3abe84dcc3..599d9c70c5 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -43,6 +43,7 @@ class LLViewerFetchedTexture;
// used for setting drag & drop callbacks.
typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
+typedef boost::function<void (LLInventoryItem*)> texture_selected_callback;
//////////////////////////////////////////////////////////////////////////////////////////
@@ -147,8 +148,12 @@ public:
void setCaption(const std::string& caption);
void setCanApplyImmediately(BOOL b);
+ void setCanApply(bool can_preview, bool can_apply);
+
void setImmediateFilterPermMask(PermissionMask mask)
{ mImmediateFilterPermMask = mask; }
+ void setDnDFilterPermMask(PermissionMask mask)
+ { mDnDFilterPermMask = mask; }
void setNonImmediateFilterPermMask(PermissionMask mask)
{ mNonImmediateFilterPermMask = mask; }
PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
@@ -172,6 +177,11 @@ public:
void setOnSelectCallback(commit_callback_t cb) { mOnSelectCallback = cb; }
+ /*
+ * callback for changing texture selection in inventory list of texture floater
+ */
+ void setOnTextureSelectedCallback(texture_selected_callback cb);
+
void setShowLoadingPlaceholder(BOOL showLoadingPlaceholder);
LLViewerFetchedTexture* getTexture() { return mTexturep; }
@@ -185,6 +195,7 @@ private:
drag_n_drop_callback mDropCallback;
commit_callback_t mOnCancelCallback;
commit_callback_t mOnSelectCallback;
+ texture_selected_callback mOnTextureSelectedCallback;
LLPointer<LLViewerFetchedTexture> mTexturep;
LLUIColor mBorderColor;
LLUUID mImageItemID;
@@ -198,6 +209,7 @@ private:
std::string mLabel;
BOOL mAllowNoTexture; // If true, the user can select "none" as an option
PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mCommitOnSelection;
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 245c2a23e6..41aee484db 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -93,6 +93,13 @@ public:
static S32 getOperationId() { return sOperationId; }
+ // deal with permissions of object, etc. returns TRUE if drop can
+ // proceed, otherwise FALSE.
+ static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id);
+
protected:
enum EDropTarget
{
@@ -219,13 +226,6 @@ protected:
// inventory items to determine if a drop would be ok.
static EAcceptance willObjectAcceptInventory(LLViewerObject* obj, LLInventoryItem* item);
- // deal with permissions of object, etc. returns TRUE if drop can
- // proceed, otherwise FALSE.
- static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
- LLInventoryItem* item,
- LLToolDragAndDrop::ESource source,
- const LLUUID& src_id);
-
public:
// helper functions
static BOOL isInventoryDropAcceptable(LLViewerObject* obj, LLInventoryItem* item) { return (ACCEPT_YES_COPY_SINGLE <= willObjectAcceptInventory(obj, item)); }
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 718201e381..0d5daf129f 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -225,7 +225,8 @@ BOOL LLVisualParamHint::render()
LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
- if (gAgentAvatarp->mDrawable.notNull())
+ if (gAgentAvatarp->mDrawable.notNull() &&
+ gAgentAvatarp->mDrawable->getFace(0))
{
LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool();
LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index ab45aae5cc..bef24dd69b 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -326,7 +326,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)
static bool handleUseOcclusionChanged(const LLSD& newvalue)
{
- LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery
+ LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery && LLGLSLShader::sNoFixedFunction
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
return true;
}
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 0adb187dd2..0ad2a6eb9b 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -79,6 +79,7 @@
#include "llpostprocess.h"
extern LLPointer<LLViewerTexture> gStartTexture;
+extern bool gShiftFrame;
LLPointer<LLViewerTexture> gDisconnectedImagep = NULL;
@@ -162,8 +163,11 @@ void display_startup()
glClear(GL_DEPTH_BUFFER_BIT);
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Update Camera");
+
void display_update_camera()
{
+ LLFastTimer t(FTM_UPDATE_CAMERA);
LLMemType mt_uc(LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA);
// TODO: cut draw distance down if customizing avatar?
// TODO: cut draw distance on per-parcel basis?
@@ -217,6 +221,11 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Bump");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete");
+static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window");
+static LLFastTimer::DeclareTimer FTM_HUD_UPDATE("HUD Update");
+static LLFastTimer::DeclareTimer FTM_DISPLAY_UPDATE_GEOM("Update Geom");
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UNBIND("Texture Unbind");
+static LLFastTimer::DeclareTimer FTM_TELEPORT_DISPLAY("Teleport Display");
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
@@ -226,6 +235,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gWindowResized)
{ //skip render on frames where window has been resized
+ LLFastTimer t(FTM_RESIZE_WINDOW);
gGL.flush();
glClear(GL_COLOR_BUFFER_BIT);
gViewerWindow->getWindow()->swapBuffers();
@@ -362,6 +372,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gTeleportDisplay)
{
+ LLFastTimer t(FTM_TELEPORT_DISPLAY);
LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.
@@ -581,6 +592,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// *TODO: merge these two methods
{
+ LLFastTimer t(FTM_HUD_UPDATE);
LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD);
LLHUDManager::getInstance()->updateEffects();
LLHUDObject::updateAll();
@@ -588,6 +600,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
{
+ LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM);
LLMemType mt_ug(LLMemType::MTYPE_DISPLAY_UPDATE_GEOM);
const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
gPipeline.createObjects(max_geom_update_time);
@@ -597,6 +610,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
gPipeline.updateGL();
+
stop_glerror();
S32 water_clip = 0;
@@ -622,11 +636,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLSpatialGroup::sNoDelete = TRUE;
LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
- /*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
- { //force occlusion on for all render types if doing deferred render (tighter shadow frustum)
- LLPipeline::sUseOcclusion = 3;
- }*/
-
S32 occlusion = LLPipeline::sUseOcclusion;
if (gDepthDirty)
{ //depth buffer is invalid, don't overwrite occlusion state
@@ -755,12 +764,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gTextureList.updateImages(max_image_decode_time);
}
- {
+ /*{
LLFastTimer t(FTM_IMAGE_UPDATE_DELETE);
//remove dead textures from GL
LLImageGL::deleteDeadTextures();
stop_glerror();
- }
+ }*/
}
LLGLState::checkStates();
@@ -889,6 +898,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
LLMemType mt_rg(LLMemType::MTYPE_DISPLAY_RENDER_GEOM);
+
+ if (gSavedSettings.getBOOL("RenderDepthPrePass") && LLGLSLShader::sNoFixedFunction)
+ {
+ gGL.setColorMask(false, false);
+
+ U32 types[] = {
+ LLRenderPass::PASS_SIMPLE,
+ LLRenderPass::PASS_FULLBRIGHT,
+ LLRenderPass::PASS_SHINY
+ };
+
+ U32 num_types = LL_ARRAY_SIZE(types);
+ gOcclusionProgram.bind();
+ for (U32 i = 0; i < num_types; i++)
+ {
+ gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
+ }
+
+ gOcclusionProgram.unbind();
+ }
+
+
gGL.setColorMask(true, false);
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
{
@@ -911,14 +942,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
stop_glerror();
}
- for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- { //dummy cleanup of any currently bound textures
- if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
- {
- gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
- gGL.getTexUnit(i)->disable();
+ {
+ LLFastTimer t(FTM_TEXTURE_UNBIND);
+ for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
+ { //dummy cleanup of any currently bound textures
+ if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
+ {
+ gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
+ gGL.getTexUnit(i)->disable();
+ }
}
}
+
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
if (to_texture)
@@ -984,6 +1019,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
display_stats();
LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
+
+ gShiftFrame = false;
}
void render_hud_attachments()
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 4e14824e69..3a04bbed4f 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -127,7 +127,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
{
for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
{
- object->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
+ LLFace *face = object->mDrawable->getFace(face_num);
+ if (face)
+ {
+ face->setState(LLFace::HUD_RENDER);
+ }
}
}
@@ -146,7 +150,11 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
{
for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
{
- childp->mDrawable->getFace(face_num)->setState(LLFace::HUD_RENDER);
+ LLFace * face = childp->mDrawable->getFace(face_num);
+ if (face)
+ {
+ face->setState(LLFace::HUD_RENDER);
+ }
}
}
}
@@ -254,7 +262,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
{
for (S32 face_num = 0; face_num < object->mDrawable->getNumFaces(); face_num++)
{
- object->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
+ LLFace * face = object->mDrawable->getFace(face_num);
+ if (face)
+ {
+ face->clearState(LLFace::HUD_RENDER);
+ }
}
}
}
@@ -272,7 +284,11 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
{
for (S32 face_num = 0; face_num < childp->mDrawable->getNumFaces(); face_num++)
{
- childp->mDrawable->getFace(face_num)->clearState(LLFace::HUD_RENDER);
+ LLFace * face = childp->mDrawable->getFace(face_num);
+ if (face)
+ {
+ face->clearState(LLFace::HUD_RENDER);
+ }
}
}
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 7481414b5c..03a12f7c4e 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -93,6 +93,7 @@
#include "lltoolpie.h"
#include "lltoolselectland.h"
#include "lltrans.h"
+#include "llviewerdisplay.h" //for gWindowResized
#include "llviewergenericmessage.h"
#include "llviewerhelp.h"
#include "llviewermenufile.h" // init_menu_file()
@@ -205,7 +206,7 @@ BOOL enable_take();
void handle_take();
void handle_object_show_inspector();
void handle_avatar_show_inspector();
-bool confirm_take(const LLSD& notification, const LLSD& response);
+bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle);
void handle_buy_object(LLSaleInfo sale_info);
void handle_buy_contents(LLSaleInfo sale_info);
@@ -1118,6 +1119,7 @@ class LLAdvancedToggleWireframe : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
gUseWireframe = !(gUseWireframe);
+ gWindowResized = TRUE;
LLPipeline::updateRenderDeferred();
gPipeline.resetVertexBuffers();
return true;
@@ -4448,7 +4450,10 @@ void handle_take()
LLNotification::Params params("ConfirmObjectTakeLock");
params.payload(payload);
- params.functor.function(confirm_take);
+ // MAINT-290
+ // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.
+ // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened
+ params.functor.function(boost::bind(confirm_take, _1, _2, LLSelectMgr::instance().getSelection()));
if(locked_but_takeable_object ||
!you_own_everything)
@@ -4501,7 +4506,7 @@ void handle_avatar_show_inspector()
-bool confirm_take(const LLSD& notification, const LLSD& response)
+bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if(enable_take() && (option == 0))
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 854e2bea52..bf7e84e2c8 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -132,6 +132,7 @@ static const U32 LLREQUEST_PERMISSION_THROTTLE_LIMIT = 5; // requests
static const F32 LLREQUEST_PERMISSION_THROTTLE_INTERVAL = 10.0f; // seconds
extern BOOL gDebugClicks;
+extern bool gShiftFrame;
// function prototypes
bool check_offer_throttle(const std::string& from_name, bool check_only);
@@ -2706,7 +2707,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
case IM_SESSION_SEND:
{
- if (!is_linden && is_busy)
+ if (is_busy)
{
return;
}
@@ -2770,7 +2771,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
chat.mSourceType = CHAT_SOURCE_OBJECT;
- if(SYSTEM_FROM == name)
+ // To conclude that the source type of message is CHAT_SOURCE_SYSTEM it's not
+ // enough to check only from name (i.e. fromName = "Second Life"). For example
+ // source type of messages from objects called "Second Life" should not be CHAT_SOURCE_SYSTEM.
+ bool chat_from_system = (SYSTEM_FROM == name) && region_id.isNull() && position.isNull();
+ if(chat_from_system)
{
// System's UUID is NULL (fixes EXT-4766)
chat.mFromID = LLUUID::null;
@@ -2795,7 +2800,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
// IMs from obejcts don't open IM sessions.
LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
- if(SYSTEM_FROM != name && nearby_chat)
+ if(!chat_from_system && nearby_chat)
{
chat.mOwnerID = from_id;
LLSD args;
@@ -2814,7 +2819,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
//Object IMs send with from name: 'Second Life' need to be displayed also in notification toasts (EXT-1590)
- if (SYSTEM_FROM != name) break;
+ if (!chat_from_system) break;
LLSD substitutions;
substitutions["NAME"] = name;
@@ -3734,6 +3739,7 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
+ gShiftFrame = true;
gAgentMovementCompleted = true;
LLUUID agent_id;
@@ -4064,6 +4070,8 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
head_rot_chg = dot(last_head_rot, head_rotation);
+ //static S32 msg_number = 0; // Used for diagnostic log messages
+
if (force_send ||
(cam_center_chg.magVec() > TRANSLATE_THRESHOLD) ||
(head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) ||
@@ -4072,19 +4080,20 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
control_flag_change != 0 ||
flag_change != 0)
{
-/*
+ /* Diagnotics to show why we send the AgentUpdate message. Also un-commment the msg_number code above and below this block
+ msg_number += 1;
if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT)
{
- //LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL;
- LL_INFOS("Messaging") << "head_rot_chg = " << head_rot_chg << LL_ENDL;
+ //LL_INFOS("Messaging") << " head rot " << head_rotation << LL_ENDL;
+ LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL;
}
if (cam_rot_chg.magVec() > ROTATION_THRESHOLD)
{
- LL_INFOS("Messaging") << "cam rot " << cam_rot_chg.magVec() << LL_ENDL;
+ LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam rot " << cam_rot_chg.magVec() << LL_ENDL;
}
if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD)
{
- LL_INFOS("Messaging") << "cam center " << cam_center_chg.magVec() << LL_ENDL;
+ LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam center " << cam_center_chg.magVec() << LL_ENDL;
}
// if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD)
// {
@@ -4092,9 +4101,9 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
// }
if (control_flag_change)
{
- LL_INFOS("Messaging") << "dcf = " << control_flag_change << LL_ENDL;
+ LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL;
}
-*/
+ */
duplicate_count = 0;
}
@@ -4129,6 +4138,26 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
if (duplicate_count < DUP_MSGS && !gDisconnected)
{
+ /* More diagnostics to count AgentUpdate messages
+ static S32 update_sec = 0;
+ static S32 update_count = 0;
+ static S32 max_update_count = 0;
+ S32 cur_sec = lltrunc( LLTimer::getTotalSeconds() );
+ update_count += 1;
+ if (cur_sec != update_sec)
+ {
+ if (update_sec != 0)
+ {
+ update_sec = cur_sec;
+ //msg_number = 0;
+ max_update_count = llmax(max_update_count, update_count);
+ llinfos << "Sent " << update_count << " AgentUpdate messages per second, max is " << max_update_count << llendl;
+ }
+ update_sec = cur_sec;
+ update_count = 0;
+ }
+ */
+
LLFastTimer t(FTM_AGENT_UPDATE_SEND);
// Build the message
msg->newMessageFast(_PREHASH_AgentUpdate);
@@ -4297,8 +4326,6 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
LL_DEBUGS("Messaging") << "Kill message for local " << local_id << LL_ENDL;
}
- LLSelectMgr::getInstance()->removeObjectFromSelections(id);
-
// ...don't kill the avatar
if (!(id == gAgentID))
{
@@ -4321,6 +4348,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
gObjectList.mNumUnknownKills++;
}
}
+
+ // We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab,
+ // which is using the object, release the mouse capture correctly when the object dies.
+ // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical().
+ LLSelectMgr::getInstance()->removeObjectFromSelections(id);
+
}
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index cd300accb7..af007743bf 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -199,6 +199,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mID(id),
mLocalID(0),
mTotalCRC(0),
+ mListIndex(-1),
mTEImages(NULL),
mGLName(0),
mbCanSelect(TRUE),
@@ -432,7 +433,9 @@ void LLViewerObject::dump() const
llinfos << "PositionAgent: " << getPositionAgent() << llendl;
llinfos << "PositionGlobal: " << getPositionGlobal() << llendl;
llinfos << "Velocity: " << getVelocity() << llendl;
- if (mDrawable.notNull() && mDrawable->getNumFaces())
+ if (mDrawable.notNull() &&
+ mDrawable->getNumFaces() &&
+ mDrawable->getFace(0))
{
LLFacePool *poolp = mDrawable->getFace(0)->getPool();
if (poolp)
@@ -2169,8 +2172,8 @@ BOOL LLViewerObject::isActive() const
BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- static LLFastTimer::DeclareTimer ftm("Viewer Object");
- LLFastTimer t(ftm);
+ //static LLFastTimer::DeclareTimer ftm("Viewer Object");
+ //LLFastTimer t(ftm);
if (mDead)
{
@@ -2798,6 +2801,23 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
(object = gObjectList.findObject(ft->mTaskID)))
{
object->loadTaskInvFile(ft->mFilename);
+
+ LLInventoryObject::object_list_t::iterator it = object->mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = object->mInventory->end();
+ std::list<LLUUID>& pending_lst = object->mPendingInventoryItemsIDs;
+
+ for (; it != end && pending_lst.size(); ++it)
+ {
+ LLViewerInventoryItem* item = dynamic_cast<LLViewerInventoryItem*>(it->get());
+ if(item && item->getType() != LLAssetType::AT_CATEGORY)
+ {
+ std::list<LLUUID>::iterator id_it = std::find(pending_lst.begin(), pending_lst.begin(), item->getAssetUUID());
+ if (id_it != pending_lst.end())
+ {
+ pending_lst.erase(id_it);
+ }
+ }
+ }
}
else
{
@@ -2910,7 +2930,22 @@ void LLViewerObject::updateInventory(
bool is_new)
{
LLMemType mt(LLMemType::MTYPE_OBJECT);
-
+
+ std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin();
+ std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end();
+
+ bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end;
+ bool is_fetched = getInventoryItemByAsset(item->getAssetUUID()) != NULL;
+
+ if (is_fetched || is_fetching)
+ {
+ return;
+ }
+ else
+ {
+ mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
+ }
+
// This slices the object into what we're concerned about on the
// viewer. The simulator will take the permissions and transfer
// ownership.
@@ -4477,7 +4512,11 @@ U32 LLViewerObject::getNumVertices() const
num_faces = mDrawable->getNumFaces();
for (i = 0; i < num_faces; i++)
{
- num_vertices += mDrawable->getFace(i)->getGeomCount();
+ LLFace * facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ num_vertices += facep->getGeomCount();
+ }
}
}
return num_vertices;
@@ -4492,7 +4531,11 @@ U32 LLViewerObject::getNumIndices() const
num_faces = mDrawable->getNumFaces();
for (i = 0; i < num_faces; i++)
{
- num_indices += mDrawable->getFace(i)->getIndicesCount();
+ LLFace * facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ num_indices += facep->getIndicesCount();
+ }
}
}
return num_indices;
@@ -4769,9 +4812,11 @@ void LLViewerObject::deleteParticleSource()
// virtual
void LLViewerObject::updateDrawable(BOOL force_damped)
{
- if (mDrawable.notNull() &&
- !mDrawable->isState(LLDrawable::ON_MOVE_LIST) &&
- isChanged(MOVED))
+ if (!isChanged(MOVED))
+ { //most common case, having an empty if case here makes for better branch prediction
+ }
+ else if (mDrawable.notNull() &&
+ !mDrawable->isState(LLDrawable::ON_MOVE_LIST))
{
BOOL damped_motion =
!isChanged(SHIFTED) && // not shifted between regions this frame and...
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index c8152e1539..30c3d03635 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -229,6 +229,8 @@ public:
const LLUUID &getID() const { return mID; }
U32 getLocalID() const { return mLocalID; }
U32 getCRC() const { return mTotalCRC; }
+ S32 getListIndex() const { return mListIndex; }
+ void setListIndex(S32 idx) { mListIndex = idx; }
virtual BOOL isFlexible() const { return FALSE; }
virtual BOOL isSculpted() const { return FALSE; }
@@ -589,6 +591,9 @@ public:
// Last total CRC received from sim, used for caching
U32 mTotalCRC;
+ // index into LLViewerObjectList::mActiveObjects or -1 if not in list
+ S32 mListIndex;
+
LLPointer<LLViewerTexture> *mTEImages;
// Selection, picking and rendering variables
@@ -684,6 +689,10 @@ protected:
F32 mAppAngle; // Apparent visual arc in degrees
F32 mPixelArea; // Apparent area in pixels
+ // IDs of of all items in the object's content which are added to the object's content,
+ // but not updated on the server yet. After item was updated, its ID will be removed from this list.
+ std::list<LLUUID> mPendingInventoryItemsIDs;
+
// This is the object's inventory from the viewer's perspective.
LLInventoryObject::object_list_t* mInventory;
class LLInventoryCallbackInfo
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 6912faa9ec..383d4a7955 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -928,21 +928,30 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
LLViewerObject *objectp = NULL;
// Make a copy of the list in case something in idleUpdate() messes with it
- std::vector<LLViewerObject*> idle_list;
-
+ static std::vector<LLViewerObject*> idle_list;
+
+ U32 idle_count = 0;
+
static LLFastTimer::DeclareTimer idle_copy("Idle Copy");
{
LLFastTimer t(idle_copy);
- idle_list.reserve( mActiveObjects.size() );
-
- for (std::set<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
+
+ for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin();
active_iter != mActiveObjects.end(); active_iter++)
{
objectp = *active_iter;
if (objectp)
{
- idle_list.push_back( objectp );
+ if (idle_count >= idle_list.size())
+ {
+ idle_list.push_back( objectp );
+ }
+ else
+ {
+ idle_list[idle_count] = objectp;
+ }
+ ++idle_count;
}
else
{ // There shouldn't be any NULL pointers in the list, but they have caused
@@ -952,10 +961,13 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
}
}
+ std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count;
+
if (gSavedSettings.getBOOL("FreezeTime"))
{
+
for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin();
- iter != idle_list.end(); iter++)
+ iter != idle_end; iter++)
{
objectp = *iter;
if (objectp->isAvatar())
@@ -967,17 +979,17 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
else
{
for (std::vector<LLViewerObject*>::iterator idle_iter = idle_list.begin();
- idle_iter != idle_list.end(); idle_iter++)
+ idle_iter != idle_end; idle_iter++)
{
objectp = *idle_iter;
- if (!objectp->idleUpdate(agent, world, frame_time))
+ if (objectp->idleUpdate(agent, world, frame_time))
{
- // If Idle Update returns false, kill object!
- kill_list.push_back(objectp);
+ num_active_objects++;
}
else
{
- num_active_objects++;
+ // If Idle Update returns false, kill object!
+ kill_list.push_back(objectp);
}
}
for (std::vector<LLViewerObject*>::iterator kill_iter = kill_list.begin();
@@ -1215,7 +1227,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
{
//llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list in cleanupReferences." << llendl;
objectp->setOnActiveList(FALSE);
- mActiveObjects.erase(objectp);
+ removeFromActiveList(objectp);
}
if (objectp->isOnMap())
@@ -1392,6 +1404,26 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
mNumDeadObjects = 0;
}
+void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp)
+{
+ S32 idx = objectp->getListIndex();
+ if (idx != -1)
+ { //remove by moving last element to this object's position
+ llassert(mActiveObjects[idx] == objectp);
+
+ objectp->setListIndex(-1);
+
+ S32 last_index = mActiveObjects.size()-1;
+
+ if (idx != last_index)
+ {
+ mActiveObjects[idx] = mActiveObjects[last_index];
+ mActiveObjects[idx]->setListIndex(idx);
+ mActiveObjects.pop_back();
+ }
+ }
+}
+
void LLViewerObjectList::updateActive(LLViewerObject *objectp)
{
LLMemType mt(LLMemType::MTYPE_OBJECT);
@@ -1406,13 +1438,29 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)
if (active)
{
//llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl;
- mActiveObjects.insert(objectp);
- objectp->setOnActiveList(TRUE);
+ S32 idx = objectp->getListIndex();
+ if (idx <= -1)
+ {
+ mActiveObjects.push_back(objectp);
+ objectp->setListIndex(mActiveObjects.size()-1);
+ objectp->setOnActiveList(TRUE);
+ }
+ else
+ {
+ llassert(idx < mActiveObjects.size());
+ llassert(mActiveObjects[idx] == objectp);
+
+ if (idx >= mActiveObjects.size() ||
+ mActiveObjects[idx] != objectp)
+ {
+ llwarns << "Invalid object list index detected!" << llendl;
+ }
+ }
}
else
{
//llinfos << "Removing " << objectp->mID << " " << objectp->getPCodeString() << " from active list." << llendl;
- mActiveObjects.erase(objectp);
+ removeFromActiveList(objectp);
objectp->setOnActiveList(FALSE);
}
}
@@ -1486,6 +1534,10 @@ void LLViewerObjectList::onPhysicsFlagsFetchFailure(const LLUUID& object_id)
mPendingPhysicsFlags.erase(object_id);
}
+static LLFastTimer::DeclareTimer FTM_SHIFT_OBJECTS("Shift Objects");
+static LLFastTimer::DeclareTimer FTM_PIPELINE_SHIFT("Pipeline Shift");
+static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift");
+
void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
{
// This is called when we shift our origin when we cross region boundaries...
@@ -1497,6 +1549,8 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
return;
}
+ LLFastTimer t(FTM_SHIFT_OBJECTS);
+
LLViewerObject *objectp;
for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
@@ -1513,8 +1567,15 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
}
}
- gPipeline.shiftObjects(offset);
- LLWorld::getInstance()->shiftRegions(offset);
+ {
+ LLFastTimer t(FTM_PIPELINE_SHIFT);
+ gPipeline.shiftObjects(offset);
+ }
+
+ {
+ LLFastTimer t(FTM_REGION_SHIFT);
+ LLWorld::getInstance()->shiftRegions(offset);
+ }
}
void LLViewerObjectList::repartitionObjects()
@@ -1718,7 +1779,10 @@ void LLViewerObjectList::generatePickList(LLCamera &camera)
LLViewerObject* last_objectp = NULL;
for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
{
- LLViewerObject* objectp = drawablep->getFace(face_num)->getViewerObject();
+ LLFace * facep = drawablep->getFace(face_num);
+ if (!facep) continue;
+
+ LLViewerObject* objectp = facep->getViewerObject();
if (objectp && objectp != last_objectp)
{
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index c5f2a2c1ee..336fc3cf20 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -118,7 +118,9 @@ public:
void dirtyAllObjectInventory();
+ void removeFromActiveList(LLViewerObject* objectp);
void updateActive(LLViewerObject *objectp);
+
void updateAvatarVisibility();
// Selection related stuff
@@ -195,7 +197,7 @@ protected:
typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;
vobj_list_t mObjects;
- std::set<LLPointer<LLViewerObject> > mActiveObjects;
+ std::vector<LLPointer<LLViewerObject> > mActiveObjects;
vobj_list_t mMapObjects;
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 6b3e04348a..345023dbfa 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -476,7 +476,7 @@ void LLViewerPartSim::checkParticleCount(U32 size)
LLViewerPartSim::LLViewerPartSim()
{
LLMemType mt(LLMemType::MTYPE_PARTICLES);
- sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount");
+ sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT);
static U32 id_seed = 0;
mID = ++id_seed;
}
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index 3e20f999c0..c9959c63ec 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -39,6 +39,8 @@ class LLViewerRegion;
class LLViewerTexture;
class LLVOPartGroup;
+#define LL_MAX_PARTICLE_COUNT 8192
+
typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);
///////////////////
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e3cb985ddb..e4108e2cd1 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1461,7 +1461,8 @@ void LLViewerRegion::unpackRegionHandshake()
// all of our terrain stuff, by
if (compp->getParamsReady())
{
- getLand().dirtyAllPatches();
+ //this line creates frame stalls on region crossing and removing it appears to have no effect
+ //getLand().dirtyAllPatches();
}
else
{
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 10c61c01d5..a6c564a6a1 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -63,8 +63,16 @@ bool LLViewerShaderMgr::sSkipReload = false;
LLVector4 gShinyOrigin;
+//transform shaders
+LLGLSLShader gTransformPositionProgram;
+LLGLSLShader gTransformTexCoordProgram;
+LLGLSLShader gTransformNormalProgram;
+LLGLSLShader gTransformColorProgram;
+LLGLSLShader gTransformBinormalProgram;
+
//utility shaders
LLGLSLShader gOcclusionProgram;
+LLGLSLShader gOcclusionCubeProgram;
LLGLSLShader gCustomAlphaProgram;
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gSplatTextureRectProgram;
@@ -72,6 +80,7 @@ LLGLSLShader gGlowCombineFXAAProgram;
LLGLSLShader gTwoTextureAddProgram;
LLGLSLShader gOneTextureNoColorProgram;
LLGLSLShader gDebugProgram;
+LLGLSLShader gClipProgram;
LLGLSLShader gAlphaMaskProgram;
//object shaders
@@ -178,6 +187,7 @@ LLGLSLShader gDeferredSunProgram;
LLGLSLShader gDeferredBlurLightProgram;
LLGLSLShader gDeferredSoftenProgram;
LLGLSLShader gDeferredShadowProgram;
+LLGLSLShader gDeferredShadowCubeProgram;
LLGLSLShader gDeferredShadowAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAttachmentShadowProgram;
@@ -437,7 +447,8 @@ void LLViewerShaderMgr::setShaders()
S32 wl_class = 2;
S32 water_class = 2;
S32 deferred_class = 0;
-
+ S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
+
if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
gSavedSettings.getBOOL("RenderDeferred") &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
@@ -475,6 +486,7 @@ void LLViewerShaderMgr::setShaders()
gSky.mVOSkyp->forceSkyUpdate();
}
+
// Load lighting shaders
mVertexShaderLevel[SHADER_LIGHTING] = light_class;
mVertexShaderLevel[SHADER_INTERFACE] = light_class;
@@ -484,6 +496,7 @@ void LLViewerShaderMgr::setShaders()
mVertexShaderLevel[SHADER_EFFECT] = effect_class;
mVertexShaderLevel[SHADER_WINDLIGHT] = wl_class;
mVertexShaderLevel[SHADER_DEFERRED] = deferred_class;
+ mVertexShaderLevel[SHADER_TRANSFORM] = transform_class;
BOOL loaded = loadBasicShaders();
@@ -493,65 +506,109 @@ void LLViewerShaderMgr::setShaders()
gPipeline.mVertexShadersLoaded = 1;
// Load all shaders to set max levels
- loadShadersEnvironment();
- loadShadersWater();
- loadShadersWindLight();
- loadShadersEffects();
- loadShadersInterface();
+ loaded = loadShadersEnvironment();
+
+ if (loaded)
+ {
+ loaded = loadShadersWater();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersWindLight();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersEffects();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersInterface();
+ }
- // Load max avatar shaders to set the max level
- mVertexShaderLevel[SHADER_AVATAR] = 3;
- mMaxAvatarShaderLevel = 3;
-
- if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
- { //hardware skinning is enabled and rigged attachment shaders loaded correctly
- BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
- S32 avatar_class = 1;
-
- // cloth is a class3 shader
- if(avatar_cloth)
- {
- avatar_class = 3;
- }
+ if (loaded)
+ {
+ loaded = loadTransformShaders();
+ }
- // Set the actual level
- mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
- loadShadersAvatar();
- if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)
- {
- if (mVertexShaderLevel[SHADER_AVATAR] == 0)
+ if (loaded)
+ {
+ // Load max avatar shaders to set the max level
+ mVertexShaderLevel[SHADER_AVATAR] = 3;
+ mMaxAvatarShaderLevel = 3;
+
+ if (gSavedSettings.getBOOL("RenderAvatarVP") && loadShadersObject())
+ { //hardware skinning is enabled and rigged attachment shaders loaded correctly
+ BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+ S32 avatar_class = 1;
+
+ // cloth is a class3 shader
+ if(avatar_cloth)
{
- gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+ avatar_class = 3;
}
- if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3)
+
+ // Set the actual level
+ mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
+ loadShadersAvatar();
+ if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)
{
- avatar_cloth = true;
+ if (mVertexShaderLevel[SHADER_AVATAR] == 0)
+ {
+ gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+ }
+ if(llmax(mVertexShaderLevel[SHADER_AVATAR]-1,0) >= 3)
+ {
+ avatar_cloth = true;
+ }
+ else
+ {
+ avatar_cloth = false;
+ }
+ gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
}
- else
+ }
+ else
+ { //hardware skinning not possible, neither is deferred rendering
+ mVertexShaderLevel[SHADER_AVATAR] = 0;
+ mVertexShaderLevel[SHADER_DEFERRED] = 0;
+
+ if (gSavedSettings.getBOOL("RenderAvatarVP"))
{
- avatar_cloth = false;
+ gSavedSettings.setBOOL("RenderDeferred", FALSE);
+ gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
+ gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
}
- gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
+
+ loadShadersAvatar(); // unloads
+
+ loaded = loadShadersObject();
}
}
- else
- { //hardware skinning not possible, neither is deferred rendering
- mVertexShaderLevel[SHADER_AVATAR] = 0;
- mVertexShaderLevel[SHADER_DEFERRED] = 0;
-
- if (gSavedSettings.getBOOL("RenderAvatarVP"))
- {
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
- gSavedSettings.setBOOL("RenderAvatarVP", FALSE);
+
+ if (!loaded)
+ { //some shader absolutely could not load, try to fall back to a simpler setting
+ if (gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
+ { //disable windlight and try again
+ gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE);
+ reentrance = false;
+ setShaders();
+ return;
}
- loadShadersAvatar(); // unloads
- loadShadersObject();
- }
+ if (gSavedSettings.getBOOL("VertexShaderEnable"))
+ { //disable shaders outright and try again
+ gSavedSettings.setBOOL("VertexShaderEnable", FALSE);
+ reentrance = false;
+ setShaders();
+ return;
+ }
+ }
- if (!loadShadersDeferred())
- {
+ if (loaded && !loadShadersDeferred())
+ { //everything else succeeded but deferred failed, disable deferred and try again
gSavedSettings.setBOOL("RenderDeferred", FALSE);
reentrance = false;
setShaders();
@@ -600,7 +657,9 @@ void LLViewerShaderMgr::setShaders()
void LLViewerShaderMgr::unloadShaders()
{
gOcclusionProgram.unload();
+ gOcclusionCubeProgram.unload();
gDebugProgram.unload();
+ gClipProgram.unload();
gAlphaMaskProgram.unload();
gUIProgram.unload();
gCustomAlphaProgram.unload();
@@ -692,6 +751,12 @@ void LLViewerShaderMgr::unloadShaders()
gDeferredSkinnedBumpProgram.unload();
gDeferredSkinnedAlphaProgram.unload();
+ gTransformPositionProgram.unload();
+ gTransformTexCoordProgram.unload();
+ gTransformNormalProgram.unload();
+ gTransformColorProgram.unload();
+ gTransformBinormalProgram.unload();
+
mVertexShaderLevel[SHADER_LIGHTING] = 0;
mVertexShaderLevel[SHADER_OBJECT] = 0;
mVertexShaderLevel[SHADER_AVATAR] = 0;
@@ -700,6 +765,7 @@ void LLViewerShaderMgr::unloadShaders()
mVertexShaderLevel[SHADER_INTERFACE] = 0;
mVertexShaderLevel[SHADER_EFFECT] = 0;
mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
+ mVertexShaderLevel[SHADER_TRANSFORM] = 0;
gPipeline.mVertexShadersLoaded = 0;
}
@@ -828,7 +894,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
{
gTerrainProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -868,7 +934,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gWaterProgram.unload();
gUnderWaterProgram.unload();
gTerrainWaterProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -953,7 +1019,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
gGlowExtractProgram.unload();
gPostColorFilterProgram.unload();
gPostNightVisionProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -1013,6 +1079,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBlurLightProgram.unload();
gDeferredSoftenProgram.unload();
gDeferredShadowProgram.unload();
+ gDeferredShadowCubeProgram.unload();
gDeferredShadowAlphaMaskProgram.unload();
gDeferredAvatarShadowProgram.unload();
gDeferredAttachmentShadowProgram.unload();
@@ -1200,7 +1267,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader";
gDeferredSpotLightProgram.mShaderFiles.clear();
gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredSpotLightProgram.createShader(NULL, NULL);
}
@@ -1209,7 +1276,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader";
gDeferredMultiSpotLightProgram.mShaderFiles.clear();
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
@@ -1368,6 +1435,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ gDeferredShadowCubeProgram.mName = "Deferred Shadow Cube Shader";
+ gDeferredShadowCubeProgram.mShaderFiles.clear();
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
+ success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
@@ -2410,7 +2487,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarWaterProgram.unload();
gAvatarEyeballProgram.unload();
gAvatarPickProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2504,7 +2581,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (mVertexShaderLevel[SHADER_INTERFACE] == 0)
{
gHighlightProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2647,6 +2724,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
+ gOcclusionCubeProgram.mShaderFiles.clear();
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOcclusionCubeProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gOcclusionCubeProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gDebugProgram.mName = "Debug Shader";
gDebugProgram.mShaderFiles.clear();
gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2657,6 +2744,16 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
+ gClipProgram.mName = "Clip Shader";
+ gClipProgram.mShaderFiles.clear();
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gClipProgram.mShaderLevel = mVertexShaderLevel[SHADER_INTERFACE];
+ success = gClipProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
gAlphaMaskProgram.mName = "Alpha Mask Shader";
gAlphaMaskProgram.mShaderFiles.clear();
gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2682,7 +2779,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
{
gWLSkyProgram.unload();
gWLCloudProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2712,6 +2809,95 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
return success;
}
+BOOL LLViewerShaderMgr::loadTransformShaders()
+{
+ BOOL success = TRUE;
+
+ if (mVertexShaderLevel[SHADER_TRANSFORM] < 1)
+ {
+ gTransformPositionProgram.unload();
+ gTransformTexCoordProgram.unload();
+ gTransformNormalProgram.unload();
+ gTransformColorProgram.unload();
+ gTransformBinormalProgram.unload();
+ return TRUE;
+ }
+
+ if (success)
+ {
+ gTransformPositionProgram.mName = "Position Transform Shader";
+ gTransformPositionProgram.mShaderFiles.clear();
+ gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformPositionProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "position_out",
+ "texture_index_out",
+ };
+
+ success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings);
+ }
+
+ if (success)
+ {
+ gTransformTexCoordProgram.mName = "TexCoord Transform Shader";
+ gTransformTexCoordProgram.mShaderFiles.clear();
+ gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformTexCoordProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "texcoord_out",
+ };
+
+ success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+ if (success)
+ {
+ gTransformNormalProgram.mName = "Normal Transform Shader";
+ gTransformNormalProgram.mShaderFiles.clear();
+ gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformNormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "normal_out",
+ };
+
+ success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+ if (success)
+ {
+ gTransformColorProgram.mName = "Color Transform Shader";
+ gTransformColorProgram.mShaderFiles.clear();
+ gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformColorProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "color_out",
+ };
+
+ success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+ if (success)
+ {
+ gTransformBinormalProgram.mName = "Binormal Transform Shader";
+ gTransformBinormalProgram.mShaderFiles.clear();
+ gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "binormal_out",
+ };
+
+ success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+
+ return success;
+}
+
std::string LLViewerShaderMgr::getShaderDirPrefix(void)
{
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 95eb551bf1..8f7ff8dd2f 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -54,6 +54,7 @@ public:
BOOL loadShadersWater();
BOOL loadShadersInterface();
BOOL loadShadersWindLight();
+ BOOL loadTransformShaders();
std::vector<S32> mVertexShaderLevel;
S32 mMaxAvatarShaderLevel;
@@ -69,6 +70,7 @@ public:
SHADER_WINDLIGHT,
SHADER_WATER,
SHADER_DEFERRED,
+ SHADER_TRANSFORM,
SHADER_COUNT
};
@@ -209,13 +211,24 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade
extern LLVector4 gShinyOrigin;
+//transform shaders
+extern LLGLSLShader gTransformPositionProgram;
+extern LLGLSLShader gTransformTexCoordProgram;
+extern LLGLSLShader gTransformNormalProgram;
+extern LLGLSLShader gTransformColorProgram;
+extern LLGLSLShader gTransformBinormalProgram;
+
+
+
//utility shaders
extern LLGLSLShader gOcclusionProgram;
+extern LLGLSLShader gOcclusionCubeProgram;
extern LLGLSLShader gCustomAlphaProgram;
extern LLGLSLShader gGlowCombineProgram;
extern LLGLSLShader gSplatTextureRectProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;
extern LLGLSLShader gDebugProgram;
+extern LLGLSLShader gClipProgram;
extern LLGLSLShader gAlphaMaskProgram;
//output tex0[tc0] + tex1[tc1]
@@ -328,6 +341,7 @@ extern LLGLSLShader gDeferredBlurLightProgram;
extern LLGLSLShader gDeferredAvatarProgram;
extern LLGLSLShader gDeferredSoftenProgram;
extern LLGLSLShader gDeferredShadowProgram;
+extern LLGLSLShader gDeferredShadowCubeProgram;
extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
extern LLGLSLShader gDeferredPostProgram;
extern LLGLSLShader gDeferredCoFProgram;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index c88122f22c..28dea8aa04 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -789,6 +789,24 @@ void send_stats()
system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
system["gpu_vendor"] = gGLManager.mGLVendorShort;
system["gpu_version"] = gGLManager.mDriverVersionVendorString;
+ system["opengl_version"] = gGLManager.mGLVersionString;
+
+ S32 shader_level = 0;
+ if (LLPipeline::sRenderDeferred)
+ {
+ shader_level = 3;
+ }
+ else if (gPipeline.canUseWindLightShadersOnObjects())
+ {
+ shader_level = 2;
+ }
+ else if (gPipeline.canUseVertexShaders())
+ {
+ shader_level = 1;
+ }
+
+
+ system["shader_level"] = shader_level;
LLSD &download = body["downloads"];
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 61236edc86..a0782c1852 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1377,10 +1377,10 @@ void LLViewerFetchedTexture::dump()
// ONLY called from LLViewerFetchedTextureList
void LLViewerFetchedTexture::destroyTexture()
{
- if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
- {
- return ;
- }
+ //if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
+ //{
+ // return ;
+ //}
if (mNeedsCreateTexture)//return if in the process of generating a new texture.
{
return ;
@@ -3290,10 +3290,14 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
sMediaMap.insert(std::make_pair(id, this));
mGLTexturep = gl_image ;
+
if(mGLTexturep.isNull())
{
generateGLTexture() ;
}
+
+ mGLTexturep->setAllowCompression(false);
+
mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
mIsPlaying = FALSE ;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index b96441127d..af8afef203 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -263,6 +263,9 @@ protected:
void reorganizeVolumeList() ;
void setTexelsPerImage();
private:
+ friend class LLBumpImageList;
+ friend class LLUIImageList;
+
//note: do not make this function public.
/*virtual*/ LLImageGL* getGLTexture() const ;
virtual void switchToCachedImage();
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 089f45ca89..c463b85913 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -680,7 +680,7 @@ void LLViewerTextureList::updateImagesDecodePriorities()
// Flush formatted images using a lazy flush
//
const F32 LAZY_FLUSH_TIMEOUT = 30.f; // stop decoding
- const F32 MAX_INACTIVE_TIME = 50.f; // actually delete
+ const F32 MAX_INACTIVE_TIME = 20.f; // actually delete
S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
S32 num_refs = imagep->getNumRefs();
@@ -1432,6 +1432,9 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
imagep->setAddressMode(LLTexUnit::TAM_CLAMP);
+ //don't compress UI images
+ imagep->getGLTexture()->setAllowCompression(false);
+
//all UI images are non-deletable
imagep->setNoDelete();
diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h
index dd7751acd7..3bc95cbfbf 100644
--- a/indra/newview/llviewervisualparam.h
+++ b/indra/newview/llviewervisualparam.h
@@ -83,11 +83,11 @@ public:
// New Virtual functions
virtual F32 getTotalDistortion() = 0;
- virtual const LLVector3& getAvgDistortion() = 0;
+ virtual const LLVector4a& getAvgDistortion() = 0;
virtual F32 getMaxDistortion() = 0;
- virtual LLVector3 getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0;
- virtual const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0;
- virtual const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0;
+ virtual LLVector4a getVertexDistortion(S32 index, LLPolyMesh *mesh) = 0;
+ virtual const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **mesh) = 0;
+ virtual const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **mesh) = 0;
// interface methods
F32 getDisplayOrder() const { return getInfo()->mEditGroupDisplayOrder; }
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index ecd76f5495..862d53c613 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -175,6 +175,7 @@
#include "llviewershadermgr.h"
#include "llviewerstats.h"
#include "llvoavatarself.h"
+#include "llvopartgroup.h"
#include "llvovolume.h"
#include "llworld.h"
#include "llworldmapview.h"
@@ -534,7 +535,10 @@ public:
}
- addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024)));
+ addText(xpos, ypos, llformat("%d MB Index Data (%d MB Pooled, %d KIndices)", LLVertexBuffer::sAllocatedIndexBytes/(1024*1024), LLVBOPool::sIndexBytesPooled/(1024*1024), LLVertexBuffer::sIndexCount/1024));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled, %d KVerts)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024), LLVertexBuffer::sVertexCount/1024));
ypos += y_inc;
addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
@@ -742,40 +746,41 @@ public:
if (gSavedSettings.getBOOL("DebugShowTextureInfo"))
{
LLViewerObject* objectp = NULL ;
- //objectp = = gAgentCamera.getFocusObject();
LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
if (nodep)
{
- objectp = nodep->getObject();
+ objectp = nodep->getObject();
}
+
if (objectp && !objectp->isDead())
{
S32 num_faces = objectp->mDrawable->getNumFaces() ;
-
+ std::set<LLViewerFetchedTexture*> tex_list;
+
for(S32 i = 0 ; i < num_faces; i++)
{
LLFace* facep = objectp->mDrawable->getFace(i) ;
if(facep)
- {
- //addText(xpos, ypos, llformat("ts_min: %.3f ts_max: %.3f tt_min: %.3f tt_max: %.3f", facep->mTexExtents[0].mV[0], facep->mTexExtents[1].mV[0],
- // facep->mTexExtents[0].mV[1], facep->mTexExtents[1].mV[1]));
- //ypos += y_inc;
-
- addText(xpos, ypos, llformat("v_size: %.3f: p_size: %.3f", facep->getVirtualSize(), facep->getPixelArea()));
- ypos += y_inc;
-
- //const LLTextureEntry *tep = facep->getTextureEntry();
- //if(tep)
- //{
- // addText(xpos, ypos, llformat("scale_s: %.3f: scale_t: %.3f", tep->mScaleS, tep->mScaleT)) ;
- // ypos += y_inc;
- //}
-
- LLViewerTexture* tex = facep->getTexture() ;
+ {
+ LLViewerFetchedTexture* tex = dynamic_cast<LLViewerFetchedTexture*>(facep->getTexture()) ;
if(tex)
{
- addText(xpos, ypos, llformat("ID: %s v_size: %.3f", tex->getID().asString().c_str(), tex->getMaxVirtualSize()));
+ if(tex_list.find(tex) != tex_list.end())
+ {
+ continue ; //already displayed.
+ }
+ tex_list.insert(tex);
+
+ std::string uuid_str;
+ tex->getID().toString(uuid_str);
+ uuid_str = uuid_str.substr(0,7);
+
+ addText(xpos, ypos, llformat("ID: %s v_size: %.3f", uuid_str.c_str(), tex->getMaxVirtualSize()));
+ ypos += y_inc;
+
+ addText(xpos, ypos, llformat("discard level: %d desired level: %d Missing: %s", tex->getDiscardLevel(),
+ tex->getDesiredDiscardLevel(), tex->isMissingAsset() ? "Y" : "N"));
ypos += y_inc;
}
}
@@ -4656,6 +4661,8 @@ void LLViewerWindow::stopGL(BOOL save_state)
LLVOAvatar::destroyGL();
stop_glerror();
+ LLVOPartGroup::destroyGL();
+
LLViewerDynamicTexture::destroyGL();
stop_glerror();
@@ -4709,7 +4716,8 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
gBumpImageList.restoreGL();
LLViewerDynamicTexture::restoreGL();
LLVOAvatar::restoreGL();
-
+ LLVOPartGroup::restoreGL();
+
gResizeScreenTexture = TRUE;
gWindowResized = TRUE;
@@ -4755,8 +4763,11 @@ void LLViewerWindow::requestResolutionUpdate()
mResDirty = true;
}
+static LLFastTimer::DeclareTimer FTM_WINDOW_CHECK_SETTINGS("Window Settings");
+
void LLViewerWindow::checkSettings()
{
+ LLFastTimer t(FTM_WINDOW_CHECK_SETTINGS);
if (mStatesDirty)
{
gGL.refreshState();
@@ -5192,8 +5203,10 @@ void LLPickInfo::getSurfaceInfo()
if (objectp->mDrawable.notNull() && mObjectFace > -1)
{
LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
-
- mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
+ if (facep)
+ {
+ mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
+ }
}
// and XY coords:
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a7a4281860..ade21ff30e 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -799,6 +799,7 @@ LLVOAvatar::~LLVOAvatar()
lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
mRoot.removeAllChildren();
+ mJointMap.clear();
deleteAndClearArray(mSkeleton);
deleteAndClearArray(mCollisionVolumes);
@@ -892,7 +893,7 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll)
}
if (mBakedTextureDatas[i].mMaskTexName)
{
- glDeleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
mBakedTextureDatas[i].mMaskTexName = 0 ;
}
}
@@ -1365,8 +1366,6 @@ void LLVOAvatar::onShift(const LLVector4a& shift_vector)
const LLVector3& shift = reinterpret_cast<const LLVector3&>(shift_vector);
mLastAnimExtents[0] += shift;
mLastAnimExtents[1] += shift;
- mNeedsImpostorUpdate = TRUE;
- mNeedsAnimUpdate = TRUE;
}
void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax)
@@ -1840,6 +1839,7 @@ void LLVOAvatar::buildCharacter()
// remove all of mRoot's children
//-------------------------------------------------------------------------
mRoot.removeAllChildren();
+ mJointMap.clear();
mIsBuilt = FALSE;
//-------------------------------------------------------------------------
@@ -2000,11 +2000,17 @@ void LLVOAvatar::releaseMeshData()
if (mDrawable.notNull())
{
LLFace* facep = mDrawable->getFace(0);
- facep->setSize(0, 0);
- for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
+ if (facep)
{
- facep = mDrawable->getFace(i);
facep->setSize(0, 0);
+ for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
+ {
+ facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ facep->setSize(0, 0);
+ }
+ }
}
}
@@ -2089,15 +2095,20 @@ void LLVOAvatar::updateMeshData()
part_index-- ;
}
- LLFace* facep ;
+ LLFace* facep = NULL;
if(f_num < mDrawable->getNumFaces())
{
facep = mDrawable->getFace(f_num);
}
else
{
- facep = mDrawable->addFace(mDrawable->getFace(0)->getPool(), mDrawable->getFace(0)->getTexture()) ;
+ facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ facep = mDrawable->addFace(facep->getPool(), facep->getTexture()) ;
+ }
}
+ if (!facep) continue;
// resize immediately
facep->setSize(num_vertices, num_indices);
@@ -2291,7 +2302,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
}
}
-static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Update Avatar");
+static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update");
static LLFastTimer::DeclareTimer FTM_JOINT_UPDATE("Update Joints");
//------------------------------------------------------------------------
@@ -4130,11 +4141,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
{
- updateMeshData();
+ updateMeshData();
mDirtyMesh = 0;
- mNeedsSkin = TRUE;
- mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
- }
+ mNeedsSkin = TRUE;
+ mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+ }
}
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -4159,10 +4170,14 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
mNeedsSkin = FALSE;
mLastSkinTime = gFrameTimeSeconds;
- LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer();
- if (vb)
+ LLFace * face = mDrawable->getFace(0);
+ if (face)
{
- vb->flush();
+ LLVertexBuffer* vb = face->getVertexBuffer();
+ if (vb)
+ {
+ vb->flush();
+ }
}
}
}
@@ -5045,7 +5060,20 @@ const LLUUID& LLVOAvatar::getID() const
// RN: avatar joints are multi-rooted to include screen-based attachments
LLJoint *LLVOAvatar::getJoint( const std::string &name )
{
- LLJoint* jointp = mRoot.findJoint(name);
+ joint_map_t::iterator iter = mJointMap.find(name);
+
+ LLJoint* jointp = NULL;
+
+ if (iter == mJointMap.end() || iter->second == NULL)
+ { //search for joint and cache found joint in lookup table
+ jointp = mRoot.findJoint(name);
+ mJointMap[name] = jointp;
+ }
+ else
+ { //return cached pointer
+ jointp = iter->second;
+ }
+
return jointp;
}
@@ -7379,7 +7407,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
}
U32 gl_name;
- LLImageGL::generateTextures(1, &gl_name );
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &gl_name );
stop_glerror();
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
@@ -7416,7 +7444,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
maskData->mLastDiscardLevel = discard_level;
if (self->mBakedTextureDatas[baked_index].mMaskTexName)
{
- LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
}
self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;
found_texture_id = true;
@@ -8262,7 +8290,7 @@ BOOL LLVOAvatar::updateLOD()
BOOL res = updateJointLODs();
LLFace* facep = mDrawable->getFace(0);
- if (!facep->getVertexBuffer())
+ if (!facep || !facep->getVertexBuffer())
{
dirtyMesh(2);
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 6a4e09593c..d106086c88 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -320,6 +320,10 @@ public:
LLVector3 mHeadOffset; // current head position
LLViewerJoint mRoot;
+
+ typedef std::map<std::string, LLJoint*> joint_map_t;
+ joint_map_t mJointMap;
+
protected:
static BOOL parseSkeletonFile(const std::string& filename);
void buildCharacter();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index f063653cc5..c99e94e60c 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -2605,7 +2605,7 @@ void LLVOAvatarSelf::deleteScratchTextures()
namep;
namep = sScratchTexNames.getNextData() )
{
- LLImageGL::deleteTextures(1, (U32 *)namep );
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (U32 *)namep );
stop_glerror();
}
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 8a79d564d3..5ad9ccc9af 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -34,6 +34,7 @@
#include "llagentcamera.h"
#include "llnotificationsutil.h"
#include "lldrawable.h"
+#include "lldrawpoolalpha.h"
#include "llface.h"
#include "llsky.h"
#include "llsurface.h"
@@ -380,8 +381,10 @@ BOOL LLVOGrass::updateLOD()
{
mNumBlades <<= 1;
}
-
- face->setSize(mNumBlades*8, mNumBlades*12);
+ if (face)
+ {
+ face->setSize(mNumBlades*8, mNumBlades*12);
+ }
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
}
else if (num_blades <= (mNumBlades >> 1))
@@ -391,7 +394,10 @@ BOOL LLVOGrass::updateLOD()
mNumBlades >>=1;
}
- face->setSize(mNumBlades*8, mNumBlades*12);
+ if (face)
+ {
+ face->setSize(mNumBlades*8, mNumBlades*12);
+ }
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
return TRUE;
}
@@ -449,14 +455,16 @@ void LLVOGrass::plantBlades()
}
LLFace *face = mDrawable->getFace(0);
+ if (face)
+ {
+ face->setTexture(getTEImage(0));
+ face->setState(LLFace::GLOBAL);
+ face->setSize(mNumBlades * 8, mNumBlades * 12);
+ face->setVertexBuffer(NULL);
+ face->setTEOffset(0);
+ face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
+ }
- face->setTexture(getTEImage(0));
- face->setState(LLFace::GLOBAL);
- face->setSize(mNumBlades * 8, mNumBlades * 12);
- face->setVertexBuffer(NULL);
- face->setTEOffset(0);
- face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
-
mDepth = (face->mCenterLocal - LLViewerCamera::getInstance()->getOrigin())*LLViewerCamera::getInstance()->getAtAxis();
mDrawable->setPosition(face->mCenterLocal);
mDrawable->movePartition();
@@ -486,6 +494,8 @@ void LLVOGrass::getGeometry(S32 idx,
LLColor4U color(255,255,255,255);
LLFace *face = mDrawable->getFace(idx);
+ if (!face)
+ return;
F32 width = sSpeciesTable[mSpecies]->mBladeSizeX;
F32 height = sSpeciesTable[mSpecies]->mBladeSizeY;
@@ -594,6 +604,7 @@ U32 LLVOGrass::getPartitionType() const
}
LLGrassPartition::LLGrassPartition()
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)
{
mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
mPartitionType = LLViewerRegion::PARTITION_GRASS;
@@ -604,6 +615,143 @@ LLGrassPartition::LLGrassPartition()
mBufferUsage = GL_DYNAMIC_DRAW_ARB;
}
+void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
+{
+ group->mBufferUsage = mBufferUsage;
+
+ mFaceList.clear();
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
+ {
+ LLDrawable* drawablep = *i;
+
+ if (drawablep->isDead())
+ {
+ continue;
+ }
+
+ LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
+ obj->mDepth = 0.f;
+
+ if (drawablep->isAnimating())
+ {
+ group->mBufferUsage = GL_STREAM_DRAW_ARB;
+ }
+
+ U32 count = 0;
+ for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
+ {
+ drawablep->updateFaceSize(j);
+
+ LLFace* facep = drawablep->getFace(j);
+ if ( !facep || !facep->hasGeometry())
+ {
+ continue;
+ }
+
+ if ((facep->getGeomCount() + vertex_count) <= 65536)
+ {
+ count++;
+ facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
+ obj->mDepth += facep->mDistance;
+
+ mFaceList.push_back(facep);
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+ llassert(facep->getIndicesCount() < 65536);
+ }
+ else
+ {
+ facep->clearVertexBuffer();
+ }
+ }
+
+ obj->mDepth /= count;
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
+
+void LLGrassPartition::getGeometry(LLSpatialGroup* group)
+{
+ LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
+ LLFastTimer ftm(FTM_REBUILD_GRASS_VB);
+
+ std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
+
+ U32 index_count = 0;
+ U32 vertex_count = 0;
+
+ group->clearDrawMap();
+
+ LLVertexBuffer* buffer = group->mVertexBuffer;
+
+ LLStrider<U16> indicesp;
+ LLStrider<LLVector4a> verticesp;
+ LLStrider<LLVector3> normalsp;
+ LLStrider<LLVector2> texcoordsp;
+ LLStrider<LLColor4U> colorsp;
+
+ buffer->getVertexStrider(verticesp);
+ buffer->getNormalStrider(normalsp);
+ buffer->getColorStrider(colorsp);
+ buffer->getTexCoord0Strider(texcoordsp);
+ buffer->getIndexStrider(indicesp);
+
+ LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
+
+ for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
+ {
+ LLFace* facep = *i;
+ LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
+ facep->setGeomIndex(vertex_count);
+ facep->setIndicesIndex(index_count);
+ facep->setVertexBuffer(buffer);
+ facep->setPoolType(LLDrawPool::POOL_ALPHA);
+ object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp);
+
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
+ S32 idx = draw_vec.size()-1;
+
+ BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
+ F32 vsize = facep->getVirtualSize();
+
+ if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
+ draw_vec[idx]->mTexture == facep->getTexture() &&
+ (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
+ //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
+ draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
+ draw_vec[idx]->mFullbright == fullbright)
+ {
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mEnd += facep->getGeomCount();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
+ else
+ {
+ U32 start = facep->getGeomIndex();
+ U32 end = start + facep->getGeomCount()-1;
+ U32 offset = facep->getIndicesStart();
+ U32 count = facep->getIndicesCount();
+ LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
+ //facep->getTexture(),
+ buffer, fullbright);
+ info->mExtents[0] = group->mObjectExtents[0];
+ info->mExtents[1] = group->mObjectExtents[1];
+ info->mVSize = vsize;
+ draw_vec.push_back(info);
+ //for alpha sorting
+ facep->setDrawInfo(info);
+ }
+ }
+
+ buffer->flush();
+ mFaceList.clear();
+}
+
// virtual
void LLVOGrass::updateDrawable(BOOL force_damped)
{
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 0060f81ab5..6da54435e3 100644
--- a/indra/newview/llvoground.cpp
+++ b/indra/newview/llvoground.cpp
@@ -82,6 +82,7 @@ LLDrawable *LLVOGround::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+// TO DO - this always returns TRUE,
BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
{
LLStrider<LLVector3> verticesp;
@@ -96,6 +97,8 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
if (drawable->getNumFaces() < 1)
drawable->addFace(poolp, NULL);
face = drawable->getFace(0);
+ if (!face)
+ return TRUE;
if (!face->getVertexBuffer())
{
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 5c10a80b07..02282fd6a6 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -48,6 +48,117 @@ const F32 MAX_PART_LIFETIME = 120.f;
extern U64 gFrameTime;
+LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL;
+S32 LLVOPartGroup::sVBSlotFree[];
+S32* LLVOPartGroup::sVBSlotCursor = NULL;
+
+//static
+void LLVOPartGroup::restoreGL()
+{
+ for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i)
+ {
+ sVBSlotFree[i] = i;
+ }
+
+ sVBSlotCursor = sVBSlotFree;
+
+ sVB = new LLVertexBuffer(VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ U32 count = LL_MAX_PARTICLE_COUNT;
+ sVB->allocateBuffer(count*4, count*6, true);
+
+ //indices and texcoords are always the same, set once
+ LLStrider<U16> indicesp;
+
+ LLStrider<LLVector4a> verticesp;
+
+ sVB->getIndexStrider(indicesp);
+ sVB->getVertexStrider(verticesp);
+
+ LLVector4a v;
+ v.set(0,0,0,0);
+
+
+ U16 vert_offset = 0;
+
+ for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
+ {
+ *indicesp++ = vert_offset + 0;
+ *indicesp++ = vert_offset + 1;
+ *indicesp++ = vert_offset + 2;
+
+ *indicesp++ = vert_offset + 1;
+ *indicesp++ = vert_offset + 3;
+ *indicesp++ = vert_offset + 2;
+
+ *verticesp++ = v;
+
+ vert_offset += 4;
+ }
+
+ LLStrider<LLVector2> texcoordsp;
+ sVB->getTexCoord0Strider(texcoordsp);
+
+ for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
+ {
+ *texcoordsp++ = LLVector2(0.f, 1.f);
+ *texcoordsp++ = LLVector2(0.f, 0.f);
+ *texcoordsp++ = LLVector2(1.f, 1.f);
+ *texcoordsp++ = LLVector2(1.f, 0.f);
+ }
+
+ sVB->flush();
+
+}
+
+//static
+void LLVOPartGroup::destroyGL()
+{
+ sVB = NULL;
+}
+
+//static
+S32 LLVOPartGroup::findAvailableVBSlot()
+{
+ if (sVBSlotCursor >= sVBSlotFree+LL_MAX_PARTICLE_COUNT)
+ { //no more available slots
+ return -1;
+ }
+
+ S32 ret = *sVBSlotCursor;
+ sVBSlotCursor++;
+
+ return ret;
+}
+
+bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
+{
+ while (start < end)
+ {
+ if (*start == idx)
+ { //not allocated (in free list)
+ return false;
+ }
+ ++start;
+ }
+
+ //allocated (not in free list)
+ return true;
+}
+
+//static
+void LLVOPartGroup::freeVBSlot(S32 idx)
+{
+ llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
+ llassert(sVBSlotCursor > sVBSlotFree);
+ llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
+
+ if (sVBSlotCursor > sVBSlotFree)
+ {
+ sVBSlotCursor--;
+ *sVBSlotCursor = idx;
+ }
+}
+
LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
: LLAlphaObject(id, pcode, regionp),
mViewerPartGroupp(NULL)
@@ -62,7 +173,6 @@ LLVOPartGroup::~LLVOPartGroup()
{
}
-
BOOL LLVOPartGroup::isActive() const
{
return FALSE;
@@ -287,9 +397,6 @@ void LLVOPartGroup::getGeometry(S32 idx,
const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
- U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex();
-
-
LLVector4a part_pos_agent;
part_pos_agent.load3(part.mPosAgent.mV);
LLVector4a camera_agent;
@@ -361,33 +468,18 @@ void LLVOPartGroup::getGeometry(S32 idx,
verticesp->setAdd(ppamu, right);
(*verticesp++).getF32ptr()[3] = 0.f;
- //*verticesp++ = part_pos_agent + up - right;
- //*verticesp++ = part_pos_agent - up - right;
- //*verticesp++ = part_pos_agent + up + right;
- //*verticesp++ = part_pos_agent - up + right;
-
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
- *texcoordsp++ = LLVector2(0.f, 1.f);
- *texcoordsp++ = LLVector2(0.f, 0.f);
- *texcoordsp++ = LLVector2(1.f, 1.f);
- *texcoordsp++ = LLVector2(1.f, 0.f);
-
- *normalsp++ = normal;
- *normalsp++ = normal;
- *normalsp++ = normal;
- *normalsp++ = normal;
-
- *indicesp++ = vert_offset + 0;
- *indicesp++ = vert_offset + 1;
- *indicesp++ = vert_offset + 2;
-
- *indicesp++ = vert_offset + 1;
- *indicesp++ = vert_offset + 3;
- *indicesp++ = vert_offset + 2;
+ if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK))
+ { //not fullbright, needs normal
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ }
}
U32 LLVOPartGroup::getPartitionType() const
@@ -412,6 +504,49 @@ LLHUDParticlePartition::LLHUDParticlePartition() :
mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO");
+
+void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
+{
+ if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))
+ {
+ return;
+ }
+
+ if (group->changeLOD())
+ {
+ group->mLastUpdateDistance = group->mDistance;
+ group->mLastUpdateViewAngle = group->mViewAngle;
+ }
+
+ LLFastTimer ftm(FTM_REBUILD_PARTICLE_VBO);
+
+ group->clearDrawMap();
+
+ //get geometry count
+ U32 index_count = 0;
+ U32 vertex_count = 0;
+
+ addGeometryCount(group, vertex_count, index_count);
+
+
+ if (vertex_count > 0 && index_count > 0)
+ {
+ group->mBuilt = 1.f;
+ //use one vertex buffer for all groups
+ group->mVertexBuffer = LLVOPartGroup::sVB;
+ getGeometry(group);
+ }
+ else
+ {
+ group->mVertexBuffer = NULL;
+ group->mBufferMap.clear();
+ }
+
+ group->mLastUpdateTime = gFrameTimeSeconds;
+ group->clearState(LLSpatialGroup::GEOM_DIRTY);
+}
+
void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
{
group->mBufferUsage = mBufferUsage;
@@ -419,7 +554,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
mFaceList.clear();
LLViewerCamera* camera = LLViewerCamera::getInstance();
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawablep = *i;
@@ -431,11 +566,6 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
obj->mDepth = 0.f;
- if (drawablep->isAnimating())
- {
- group->mBufferUsage = GL_STREAM_DRAW_ARB;
- }
-
U32 count = 0;
for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
{
@@ -447,13 +577,14 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
continue;
}
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
count++;
facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
obj->mDepth += facep->mDistance;
mFaceList.push_back(facep);
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
llassert(facep->getIndicesCount() < 65536);
}
@@ -461,15 +592,13 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
}
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
-static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB");
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_GEOM("Particle Geom");
void LLParticlePartition::getGeometry(LLSpatialGroup* group)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
- LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ?
- FTM_REBUILD_GRASS_VB :
- FTM_REBUILD_PARTICLE_VB);
+ LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM);
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
@@ -489,21 +618,44 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
buffer->getVertexStrider(verticesp);
buffer->getNormalStrider(normalsp);
buffer->getColorStrider(colorsp);
- buffer->getTexCoord0Strider(texcoordsp);
- buffer->getIndexStrider(indicesp);
-
+
LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
{
LLFace* facep = *i;
LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
- facep->setGeomIndex(vertex_count);
- facep->setIndicesIndex(index_count);
- facep->setVertexBuffer(buffer);
- facep->setPoolType(LLDrawPool::POOL_ALPHA);
- object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp);
+
+ if (facep->getIndicesStart() == 0xFFFFFFFF)
+ { //set the indices of this face
+ S32 idx = LLVOPartGroup::findAvailableVBSlot();
+ if (idx >= 0)
+ {
+ facep->setGeomIndex(idx*4);
+ facep->setIndicesIndex(idx*6);
+ facep->setVertexBuffer(LLVOPartGroup::sVB);
+ facep->setPoolType(LLDrawPool::POOL_ALPHA);
+ }
+ else
+ {
+ continue; //out of space in particle buffer
+ }
+ }
+
+ S32 geom_idx = (S32) facep->getGeomIndex();
+
+ LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart();
+ LLStrider<LLVector4a> cur_vert = verticesp + geom_idx;
+ LLStrider<LLVector3> cur_norm = normalsp + geom_idx;
+ LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx;
+ LLStrider<LLColor4U> cur_col = colorsp + geom_idx;
+
+ object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx);
+ llassert(facep->getGeomCount() == 4);
+ llassert(facep->getIndicesCount() == 6);
+
+
vertex_count += facep->getGeomCount();
index_count += facep->getIndicesCount();
@@ -512,18 +664,31 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
F32 vsize = facep->getVirtualSize();
- if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
+ bool batched = false;
+
+ if (idx >= 0 &&
draw_vec[idx]->mTexture == facep->getTexture() &&
- (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
- //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
- draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
draw_vec[idx]->mFullbright == fullbright)
{
- draw_vec[idx]->mCount += facep->getIndicesCount();
- draw_vec[idx]->mEnd += facep->getGeomCount();
- draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)
+ {
+ batched = true;
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mEnd += facep->getGeomCount();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
+ else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
+ {
+ batched = true;
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mStart -= facep->getGeomCount();
+ draw_vec[idx]->mOffset = facep->getIndicesStart();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
}
- else
+
+
+ if (!batched)
{
U32 start = facep->getGeomIndex();
U32 end = start + facep->getGeomCount()-1;
@@ -541,7 +706,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
}
}
- buffer->flush();
mFaceList.clear();
}
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index e58fed86d9..6160bceb24 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -31,18 +31,32 @@
#include "v3math.h"
#include "v3color.h"
#include "llframetimer.h"
+#include "llviewerpartsim.h"
+#include "llvertexbuffer.h"
class LLViewerPartGroup;
class LLVOPartGroup : public LLAlphaObject
{
public:
+
+ //vertex buffer for holding all particles
+ static LLPointer<LLVertexBuffer> sVB;
+ static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT];
+ static S32* sVBSlotCursor;
+
+ static void restoreGL();
+ static void destroyGL();
+ static S32 findAvailableVBSlot();
+ static void freeVBSlot(S32 idx);
+
enum
{
- VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) |
- (1 << LLVertexBuffer::TYPE_NORMAL) |
- (1 << LLVertexBuffer::TYPE_TEXCOORD0) |
- (1 << LLVertexBuffer::TYPE_COLOR)
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_COLOR |
+ LLVertexBuffer::MAP_TEXTURE_INDEX
};
LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index bf6158eeaf..94a3111f4c 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -296,18 +296,20 @@ void LLVOSurfacePatch::updateFaceSize(S32 idx)
}
LLFace* facep = mDrawable->getFace(idx);
-
- S32 num_vertices = 0;
- S32 num_indices = 0;
-
- if (mLastStride)
+ if (facep)
{
- getGeomSizesMain(mLastStride, num_vertices, num_indices);
- getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
- getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
- }
+ S32 num_vertices = 0;
+ S32 num_indices = 0;
+
+ if (mLastStride)
+ {
+ getGeomSizesMain(mLastStride, num_vertices, num_indices);
+ getGeomSizesNorth(mLastStride, mLastNorthStride, num_vertices, num_indices);
+ getGeomSizesEast(mLastStride, mLastEastStride, num_vertices, num_indices);
+ }
- facep->setSize(num_vertices, num_indices);
+ facep->setSize(num_vertices, num_indices);
+ }
}
BOOL LLVOSurfacePatch::updateLOD()
@@ -322,30 +324,32 @@ void LLVOSurfacePatch::getGeometry(LLStrider<LLVector3> &verticesp,
LLStrider<U16> &indicesp)
{
LLFace* facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ U32 index_offset = facep->getGeomIndex();
- U32 index_offset = facep->getGeomIndex();
-
- updateMainGeometry(facep,
- verticesp,
- normalsp,
- texCoords0p,
- texCoords1p,
- indicesp,
- index_offset);
- updateNorthGeometry(facep,
- verticesp,
- normalsp,
- texCoords0p,
- texCoords1p,
- indicesp,
- index_offset);
- updateEastGeometry(facep,
+ updateMainGeometry(facep,
verticesp,
normalsp,
texCoords0p,
texCoords1p,
indicesp,
index_offset);
+ updateNorthGeometry(facep,
+ verticesp,
+ normalsp,
+ texCoords0p,
+ texCoords1p,
+ indicesp,
+ index_offset);
+ updateEastGeometry(facep,
+ verticesp,
+ normalsp,
+ texCoords0p,
+ texCoords1p,
+ indicesp,
+ index_offset);
+ }
}
void LLVOSurfacePatch::updateMainGeometry(LLFace *facep,
@@ -864,7 +868,11 @@ void LLVOSurfacePatch::dirtyGeom()
if (mDrawable)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
- mDrawable->getFace(0)->setVertexBuffer(NULL);
+ LLFace* facep = mDrawable->getFace(0);
+ if (facep)
+ {
+ facep->setVertexBuffer(NULL);
+ }
mDrawable->movePartition();
}
}
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 4564207da4..337ddfb24d 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -374,7 +374,7 @@ BOOL LLVOTree::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
// *TODO: I don't know what's so special about trees
// that they don't get REBUILD_POSITION automatically
// at a higher level.
- const LLVector3 &this_position = getPositionAgent();
+ const LLVector3 &this_position = getPositionRegion();
if (this_position != mLastPosition)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
@@ -490,11 +490,16 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
if(mTrunkLOD >= sMAX_NUM_TREE_LOD_LEVELS) //do not display the tree.
{
mReferenceBuffer = NULL ;
- mDrawable->getFace(0)->setVertexBuffer(NULL);
+ LLFace * facep = drawable->getFace(0);
+ if (facep)
+ {
+ facep->setVertexBuffer(NULL);
+ }
return TRUE ;
}
- if (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer())
+ if (mDrawable->getFace(0) &&
+ (mReferenceBuffer.isNull() || !mDrawable->getFace(0)->getVertexBuffer()))
{
const F32 SRR3 = 0.577350269f; // sqrt(1/3)
const F32 SRR2 = 0.707106781f; // sqrt(1/2)
@@ -507,6 +512,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
S32 lod;
LLFace *face = drawable->getFace(0);
+ if (!face) return TRUE;
face->mCenterAgent = getPositionAgent();
face->mCenterLocal = face->mCenterAgent;
@@ -837,10 +843,10 @@ void LLVOTree::updateMesh()
LLMatrix4 matrix;
// Translate to tree base HACK - adjustment in Z plants tree underground
- const LLVector3 &pos_agent = getPositionAgent();
+ const LLVector3 &pos_region = getPositionRegion();
//gGL.translatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
LLMatrix4 trans_mat;
- trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f);
+ trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY], pos_region.mV[VZ] - 0.1f);
trans_mat *= matrix;
// Rotate to tree position and bend for current trunk/wind
@@ -879,6 +885,7 @@ void LLVOTree::updateMesh()
calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, mBranches);
LLFace* facep = mDrawable->getFace(0);
+ if (!facep) return;
LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
buff->allocateBuffer(vert_count, index_count, TRUE);
facep->setVertexBuffer(buff);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index e7c35d8220..082818b112 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -520,6 +520,7 @@ void LLVOVolume::animateTextures()
for (S32 i = start; i <= end; i++)
{
LLFace* facep = mDrawable->getFace(i);
+ if (!facep) continue;
if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
const LLTextureEntry* te = facep->getTextureEntry();
@@ -638,8 +639,8 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
LLViewerObject::idleUpdate(agent, world, time);
- static LLFastTimer::DeclareTimer ftm("Volume");
- LLFastTimer t(ftm);
+ //static LLFastTimer::DeclareTimer ftm("Volume Idle");
+ //LLFastTimer t(ftm);
if (mDead || mDrawable.isNull())
{
@@ -682,7 +683,21 @@ void LLVOVolume::updateTextures()
const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
{
- updateTextureVirtualSize();
+ updateTextureVirtualSize();
+
+ if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
+ { //delete vertex buffer to free up some VRAM
+ LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->destroyGL(true);
+
+ //flag the group as having changed geometry so it gets a rebuild next time
+ //it becomes visible
+ group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
+ }
+ }
+
}
}
@@ -715,7 +730,18 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
if(!forced)
{
if(!isVisible())
- {
+ { //don't load textures for non-visible faces
+ const S32 num_faces = mDrawable->getNumFaces();
+ for (S32 i = 0; i < num_faces; i++)
+ {
+ LLFace* face = mDrawable->getFace(i);
+ if (face)
+ {
+ face->setPixelArea(0.f);
+ face->setVirtualSize(0.f);
+ }
+ }
+
return ;
}
@@ -743,6 +769,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
for (S32 i = 0; i < num_faces; i++)
{
LLFace* face = mDrawable->getFace(i);
+ if (!face) continue;
const LLTextureEntry *te = face->getTextureEntry();
LLViewerTexture *imagep = face->getTexture();
if (!imagep || !te ||
@@ -1062,9 +1089,33 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
+
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+ bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject &&
+ (!mVolumeImpl || !mVolumeImpl->isVolumeUnique());
+
+ if (cache_in_vram)
+ { //this volume might be used as source data for a transform object, put it in vram
+ LLVolume* volume = getVolume();
+ for (S32 i = 0; i < volume->getNumFaces(); ++i)
+ {
+ const LLVolumeFace& face = volume->getVolumeFace(i);
+ if (face.mVertexBuffer.notNull())
+ { //already cached
+ break;
+ }
+ volume->genBinormals(i);
+ LLFace::cacheFaceInVRAM(face);
+ }
+ }
+
+
return TRUE;
}
+
+
return FALSE;
}
@@ -1246,7 +1297,8 @@ BOOL LLVOVolume::calcLOD()
llround(radius, 0.01f));
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO))
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
+ mDrawable->getFace(0))
{
//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail));
@@ -1325,25 +1377,23 @@ void LLVOVolume::updateFaceFlags()
for (S32 i = 0; i < getVolume()->getNumFaces(); i++)
{
LLFace *face = mDrawable->getFace(i);
- if (!face)
+ if (face)
{
- return;
- }
+ BOOL fullbright = getTE(i)->getFullbright();
+ face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
- BOOL fullbright = getTE(i)->getFullbright();
- face->clearState(LLFace::FULLBRIGHT | LLFace::HUD_RENDER | LLFace::LIGHT);
-
- if (fullbright || (mMaterial == LL_MCODE_LIGHT))
- {
- face->setState(LLFace::FULLBRIGHT);
- }
- if (mDrawable->isLight())
- {
- face->setState(LLFace::LIGHT);
- }
- if (isHUDAttachment())
- {
- face->setState(LLFace::HUD_RENDER);
+ if (fullbright || (mMaterial == LL_MCODE_LIGHT))
+ {
+ face->setState(LLFace::FULLBRIGHT);
+ }
+ if (mDrawable->isLight())
+ {
+ face->setState(LLFace::LIGHT);
+ }
+ if (isHUDAttachment())
+ {
+ face->setState(LLFace::HUD_RENDER);
+ }
}
}
}
@@ -1380,6 +1430,8 @@ void LLVOVolume::regenFaces()
for (S32 i = 0; i < mNumFaces; i++)
{
LLFace* facep = count_changed ? addFace(i) : mDrawable->getFace(i);
+ if (!facep) continue;
+
facep->setTEOffset(i);
facep->setTexture(getTEImage(i));
facep->setViewerObject(this);
@@ -1416,7 +1468,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
BOOL rebuild = mDrawable->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED);
-// bool rigged = false;
+ // bool rigged = false;
LLVolume* volume = mRiggedVolume;
if (!volume)
{
@@ -1471,11 +1523,11 @@ void LLVOVolume::preRebuild()
}
}
-void LLVOVolume::updateRelativeXform()
+void LLVOVolume::updateRelativeXform(bool force_identity)
{
if (mVolumeImpl)
{
- mVolumeImpl->updateRelativeXform();
+ mVolumeImpl->updateRelativeXform(force_identity);
return;
}
@@ -1495,15 +1547,16 @@ void LLVOVolume::updateRelativeXform()
mRelativeXform.invert();
mRelativeXformInvTrans.transpose();
}
- else if (drawable->isActive())
+ else if (drawable->isActive() || force_identity)
{
// setup relative transforms
LLQuaternion delta_rot;
LLVector3 delta_pos, delta_scale;
//matrix from local space to parent relative/global space
- delta_rot = drawable->isSpatialRoot() ? LLQuaternion() : mDrawable->getRotation();
- delta_pos = drawable->isSpatialRoot() ? LLVector3(0,0,0) : mDrawable->getPosition();
+ bool use_identity = force_identity || drawable->isSpatialRoot();
+ delta_rot = use_identity ? LLQuaternion() : mDrawable->getRotation();
+ delta_pos = use_identity ? LLVector3(0,0,0) : mDrawable->getPosition();
delta_scale = mDrawable->getScale();
// Vertex transform (4x4)
@@ -1604,7 +1657,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
return res;
}
- dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+ LLSpatialGroup* group = drawable->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyMesh();
+ }
BOOL compiled = FALSE;
@@ -1617,6 +1674,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mVolumeChanged || mFaceMappingChanged )
{
+ dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
compiled = TRUE;
if (mVolumeChanged)
@@ -1635,6 +1694,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
}
else if ((mLODChanged) || (mSculptChanged))
{
+ dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
LLVolume *old_volumep, *new_volumep;
F32 old_lod, new_lod;
S32 old_num_faces, new_num_faces ;
@@ -1716,16 +1777,19 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
void LLVOVolume::updateFaceSize(S32 idx)
{
LLFace* facep = mDrawable->getFace(idx);
- if (idx >= getVolume()->getNumVolumeFaces())
+ if (facep)
{
- facep->setSize(0,0, true);
- }
- else
- {
- const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
- facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
- true); // <--- volume faces should be padded for 16-byte alignment
+ if (idx >= getVolume()->getNumVolumeFaces())
+ {
+ facep->setSize(0,0, true);
+ }
+ else
+ {
+ const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
+ facep->setSize(vol_face.mNumVertices, vol_face.mNumIndices,
+ true); // <--- volume faces should be padded for 16-byte alignment
+ }
}
}
@@ -3098,6 +3162,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
for (S32 i = 0; i < num_faces; ++i)
{
const LLFace* face = drawablep->getFace(i);
+ if (!face) continue;
const LLTextureEntry* te = face->getTextureEntry();
const LLViewerTexture* img = face->getTexture();
@@ -3369,6 +3434,7 @@ F32 LLVOVolume::getBinRadius()
for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
{
LLFace* face = mDrawable->getFace(i);
+ if (!face) continue;
if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
!face->canRenderAsMask())
{
@@ -3450,9 +3516,12 @@ LLVector3 LLVOVolume::agentPositionToVolume(const LLVector3& pos) const
{
LLVector3 ret = pos - getRenderPosition();
ret = ret * ~getRenderRotation();
- LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
- LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
- ret.scaleVec(invObjScale);
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ LLVector3 invObjScale(1.f / objScale.mV[VX], 1.f / objScale.mV[VY], 1.f / objScale.mV[VZ]);
+ ret.scaleVec(invObjScale);
+ }
return ret;
}
@@ -3470,8 +3539,12 @@ LLVector3 LLVOVolume::agentDirectionToVolume(const LLVector3& dir) const
LLVector3 LLVOVolume::volumePositionToAgent(const LLVector3& dir) const
{
LLVector3 ret = dir;
- LLVector3 objScale = isVolumeGlobal() ? LLVector3(1,1,1) : getScale();
- ret.scaleVec(objScale);
+ if (!isVolumeGlobal())
+ {
+ LLVector3 objScale = getScale();
+ ret.scaleVec(objScale);
+ }
+
ret = ret * getRenderRotation();
ret += getRenderPosition();
@@ -3592,7 +3665,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
{
LLFace* face = mDrawable->getFace(face_hit);
- if (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n)))
+ if (face &&
+ (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
{
v_end = p;
if (face_hitp != NULL)
@@ -3902,8 +3976,11 @@ bool can_batch_texture(LLFace* facep)
return true;
}
+static LLFastTimer::DeclareTimer FTM_REGISTER_FACE("Register Face");
+
void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 type)
{
+ LLFastTimer t(FTM_REGISTER_FACE);
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
@@ -3935,9 +4012,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
const LLMatrix4* model_mat = NULL;
LLDrawable* drawable = facep->getDrawable();
- if (drawable->isActive())
+
+ if (drawable->isState(LLDrawable::ANIMATED_CHILD))
{
- model_mat = &(drawable->getRenderMatrix());
+ model_mat = &drawable->getWorldMatrix();
+ }
+ else if (drawable->isActive())
+ {
+ model_mat = &drawable->getRenderMatrix();
}
else
{
@@ -3948,6 +4030,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
+ //drawable->getVObj()->setDebugText(llformat("%d", drawable->isState(LLDrawable::ANIMATED_CHILD)));
+
U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
LLViewerTexture* tex = facep->getTexture();
@@ -4041,8 +4125,9 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
-static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume VB");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_FACE_LIST("Build Face List");
+static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_GEN_DRAW_INFO("Gen Draw Info");
static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
{
@@ -4073,6 +4158,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
+
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -4084,19 +4171,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
{
- LLFastTimer ftm(FTM_REBUILD_VBO);
- LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
-
rebuildMesh(group);
}
return;
}
- group->mBuilt = 1.f;
- LLFastTimer ftm(FTM_REBUILD_VBO);
-
- LLFastTimer ftm2(FTM_REBUILD_VOLUME_VB);
+ LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
+ group->mBuilt = 1.f;
+
LLVOAvatar* pAvatarVO = NULL;
LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
@@ -4123,6 +4206,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
group->mGeometryBytes = 0;
group->mSurfaceArea = 0;
+ //cache object box size since it might be used for determining visibility
+ group->mObjectBoxSize = group->mObjectBounds[1].getLength3().getF32();
+
group->clearDrawMap();
mFaceList.clear();
@@ -4142,359 +4228,375 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
bool emissive = false;
- //get all the faces into a list
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
{
- LLDrawable* drawablep = *drawable_iter;
-
- if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+ LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST);
+
+ //get all the faces into a list
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- continue;
- }
+ LLDrawable* drawablep = *drawable_iter;
+
+ if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
+ {
+ continue;
+ }
- if (drawablep->isAnimating())
- { //fall back to stream draw for animating verts
- useage = GL_STREAM_DRAW_ARB;
- }
+ if (drawablep->isAnimating())
+ { //fall back to stream draw for animating verts
+ useage = GL_STREAM_DRAW_ARB;
+ }
- LLVOVolume* vobj = drawablep->getVOVolume();
+ LLVOVolume* vobj = drawablep->getVOVolume();
- if (!vobj)
- {
- continue;
- }
+ if (!vobj)
+ {
+ continue;
+ }
- if (vobj->isMesh() &&
- (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
- {
- continue;
- }
+ if (vobj->isMesh() &&
+ (vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded() || !gMeshRepo.meshRezEnabled()))
+ {
+ continue;
+ }
- LLVolume* volume = vobj->getVolume();
- if (volume)
- {
- const LLVector3& scale = vobj->getScale();
- group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
- }
+ LLVolume* volume = vobj->getVolume();
+ if (volume)
+ {
+ const LLVector3& scale = vobj->getScale();
+ group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
+ }
- llassert_always(vobj);
- vobj->updateTextureVirtualSize(true);
- vobj->preRebuild();
+ llassert_always(vobj);
+ vobj->updateTextureVirtualSize(true);
+ vobj->preRebuild();
- drawablep->clearState(LLDrawable::HAS_ALPHA);
+ drawablep->clearState(LLDrawable::HAS_ALPHA);
- bool rigged = vobj->isAttachment() &&
- vobj->isMesh() &&
- gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
+ bool rigged = vobj->isAttachment() &&
+ vobj->isMesh() &&
+ gMeshRepo.getSkinInfo(vobj->getVolume()->getParams().getSculptID(), vobj);
- bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
+ bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
- bool is_rigged = false;
+ bool is_rigged = false;
- //for each face
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace* facep = drawablep->getFace(i);
+ //for each face
+ for (S32 i = 0; i < drawablep->getNumFaces(); i++)
+ {
+ LLFace* facep = drawablep->getFace(i);
+ if (!facep)
+ {
+ continue;
+ }
- //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
- // batch, it will recover its vertex buffer reference from the spatial group
- facep->setVertexBuffer(NULL);
+ //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
+ // batch, it will recover its vertex buffer reference from the spatial group
+ facep->setVertexBuffer(NULL);
- //sum up face verts and indices
- drawablep->updateFaceSize(i);
+ //sum up face verts and indices
+ drawablep->updateFaceSize(i);
- if (rigged)
- {
- if (!facep->isState(LLFace::RIGGED))
- { //completely reset vertex buffer
- facep->clearVertexBuffer();
- }
+ if (rigged)
+ {
+ if (!facep->isState(LLFace::RIGGED))
+ { //completely reset vertex buffer
+ facep->clearVertexBuffer();
+ }
- facep->setState(LLFace::RIGGED);
- is_rigged = true;
+ facep->setState(LLFace::RIGGED);
+ is_rigged = true;
- //get drawpool of avatar with rigged face
- LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
+ //get drawpool of avatar with rigged face
+ LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
- //Determine if we've received skininfo that contains an
- //alternate bind matrix - if it does then apply the translational component
- //to the joints of the avatar.
- bool pelvisGotSet = false;
+ //Determine if we've received skininfo that contains an
+ //alternate bind matrix - if it does then apply the translational component
+ //to the joints of the avatar.
+ bool pelvisGotSet = false;
- if ( pAvatarVO )
- {
- LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
- const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
-
- if ( pSkinData )
+ if ( pAvatarVO )
{
- const int bindCnt = pSkinData->mAlternateBindMatrix.size();
- if ( bindCnt > 0 )
- {
- const int jointCnt = pSkinData->mJointNames.size();
- const F32 pelvisZOffset = pSkinData->mPelvisOffset;
- bool fullRig = (jointCnt>=20) ? true : false;
- if ( fullRig )
- {
- for ( int i=0; i<jointCnt; ++i )
+ LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
+
+ if ( pSkinData )
+ {
+ const int bindCnt = pSkinData->mAlternateBindMatrix.size();
+ if ( bindCnt > 0 )
+ {
+ const int jointCnt = pSkinData->mJointNames.size();
+ const F32 pelvisZOffset = pSkinData->mPelvisOffset;
+ bool fullRig = (jointCnt>=20) ? true : false;
+ if ( fullRig )
{
- std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
- //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
- LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
- if ( pJoint && pJoint->getId() != currentId )
- {
- pJoint->setId( currentId );
- const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
- //Set the joint position
- pJoint->storeCurrentXform( jointPos );
- //If joint is a pelvis then handle old/new pelvis to foot values
- if ( lookingForJoint == "mPelvis" )
- {
+ for ( int i=0; i<jointCnt; ++i )
+ {
+ std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
+ //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
+ LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
+ if ( pJoint && pJoint->getId() != currentId )
+ {
+ pJoint->setId( currentId );
+ const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
+ //Set the joint position
pJoint->storeCurrentXform( jointPos );
- if ( !pAvatarVO->hasPelvisOffset() )
- {
- pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
- //Trigger to rebuild viewer AV
- pelvisGotSet = true;
+ //If joint is a pelvis then handle old/new pelvis to foot values
+ if ( lookingForJoint == "mPelvis" )
+ {
+ pJoint->storeCurrentXform( jointPos );
+ if ( !pAvatarVO->hasPelvisOffset() )
+ {
+ pAvatarVO->setPelvisOffset( true, jointPos, pelvisZOffset );
+ //Trigger to rebuild viewer AV
+ pelvisGotSet = true;
+ }
}
- }
+ }
}
- }
- }
+ }
+ }
}
}
- }
- //If we've set the pelvis to a new position we need to also rebuild some information that the
- //viewer does at launch (e.g. body size etc.)
- if ( pelvisGotSet )
- {
- pAvatarVO->postPelvisSetRecalc();
- }
-
- if (pool)
- {
- const LLTextureEntry* te = facep->getTextureEntry();
-
- //remove face from old pool if it exists
- LLDrawPool* old_pool = facep->getPool();
- if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+ //If we've set the pelvis to a new position we need to also rebuild some information that the
+ //viewer does at launch (e.g. body size etc.)
+ if ( pelvisGotSet )
{
- ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
+ pAvatarVO->postPelvisSetRecalc();
}
- //add face to new pool
- LLViewerTexture* tex = facep->getTexture();
- U32 type = gPipeline.getPoolTypeFromTE(te, tex);
-
- if (type == LLDrawPool::POOL_ALPHA)
+ if (pool)
{
- if (te->getColor().mV[3] > 0.f)
+ const LLTextureEntry* te = facep->getTextureEntry();
+
+ //remove face from old pool if it exists
+ LLDrawPool* old_pool = facep->getPool();
+ if (old_pool && old_pool->getType() == LLDrawPool::POOL_AVATAR)
+ {
+ ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
+ }
+
+ //add face to new pool
+ LLViewerTexture* tex = facep->getTexture();
+ U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+
+ if (type == LLDrawPool::POOL_ALPHA)
+ {
+ if (te->getColor().mV[3] > 0.f)
+ {
+ if (te->getFullbright())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ }
+ }
+ }
+ else if (te->getShiny())
{
if (te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ if (LLPipeline::sRenderDeferred)
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ }
}
}
- }
- else if (te->getShiny())
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
- }
else
{
- if (LLPipeline::sRenderDeferred)
+ if (te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
}
}
- }
- else
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
- }
- else
+
+ if (te->getGlow())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
}
- }
-
- if (te->getGlow())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
- }
- if (LLPipeline::sRenderDeferred)
- {
- if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
+ if (LLPipeline::sRenderDeferred)
{
- if (te->getBumpmap())
+ if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
- }
- else
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ if (te->getBumpmap())
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ }
}
}
}
- }
- continue;
- }
- else
- {
- if (facep->isState(LLFace::RIGGED))
- { //face is not rigged but used to be, remove from rigged face pool
- LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
- if (pool)
- {
- pool->removeRiggedFace(facep);
+ continue;
+ }
+ else
+ {
+ if (facep->isState(LLFace::RIGGED))
+ { //face is not rigged but used to be, remove from rigged face pool
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool();
+ if (pool)
+ {
+ pool->removeRiggedFace(facep);
+ }
+ facep->clearState(LLFace::RIGGED);
}
- facep->clearState(LLFace::RIGGED);
}
- }
-
-
- if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
- {
- facep->clearVertexBuffer();
- continue;
- }
-
- cur_total += facep->getGeomCount();
- if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
- {
- const LLTextureEntry* te = facep->getTextureEntry();
- LLViewerTexture* tex = facep->getTexture();
- if (te->getGlow() >= 1.f/255.f)
+ if (cur_total > max_total || facep->getIndicesCount() <= 0 || facep->getGeomCount() <= 0)
{
- emissive = true;
+ facep->clearVertexBuffer();
+ continue;
}
- if (facep->isState(LLFace::TEXTURE_ANIM))
- {
- if (!vobj->mTexAnimMode)
- {
- facep->clearState(LLFace::TEXTURE_ANIM);
- }
- }
+ cur_total += facep->getGeomCount();
- BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
- U32 type = gPipeline.getPoolTypeFromTE(te, tex);
- if (type != LLDrawPool::POOL_ALPHA && force_simple)
+ if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
{
- type = LLDrawPool::POOL_SIMPLE;
- }
- facep->setPoolType(type);
+ const LLTextureEntry* te = facep->getTextureEntry();
+ LLViewerTexture* tex = facep->getTexture();
- if (vobj->isHUDAttachment())
- {
- facep->setState(LLFace::FULLBRIGHT);
- }
+ if (te->getGlow() >= 1.f/255.f)
+ {
+ emissive = true;
+ }
- if (vobj->mTextureAnimp && vobj->mTexAnimMode)
- {
- if (vobj->mTextureAnimp->mFace <= -1)
+ if (facep->isState(LLFace::TEXTURE_ANIM))
{
- S32 face;
- for (face = 0; face < vobj->getNumTEs(); face++)
+ if (!vobj->mTexAnimMode)
{
- drawablep->getFace(face)->setState(LLFace::TEXTURE_ANIM);
+ facep->clearState(LLFace::TEXTURE_ANIM);
}
}
- else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+
+ BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
+ U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+ if (type != LLDrawPool::POOL_ALPHA && force_simple)
{
- drawablep->getFace(vobj->mTextureAnimp->mFace)->setState(LLFace::TEXTURE_ANIM);
+ type = LLDrawPool::POOL_SIMPLE;
}
- }
+ facep->setPoolType(type);
- if (type == LLDrawPool::POOL_ALPHA)
- {
- if (facep->canRenderAsMask())
- { //can be treated as alpha mask
- simple_faces.push_back(facep);
- }
- else
+ if (vobj->isHUDAttachment())
{
- if (te->getColor().mV[3] > 0.f)
- { //only treat as alpha in the pipeline if < 100% transparent
- drawablep->setState(LLDrawable::HAS_ALPHA);
- }
- alpha_faces.push_back(facep);
+ facep->setState(LLFace::FULLBRIGHT);
}
- }
- else
- {
- if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+
+ if (vobj->mTextureAnimp && vobj->mTexAnimMode)
{
- facep->mLastUpdateTime = gFrameTimeSeconds;
+ if (vobj->mTextureAnimp->mFace <= -1)
+ {
+ S32 face;
+ for (face = 0; face < vobj->getNumTEs(); face++)
+ {
+ LLFace * facep = drawablep->getFace(face);
+ if (facep)
+ {
+ facep->setState(LLFace::TEXTURE_ANIM);
+ }
+ }
+ }
+ else if (vobj->mTextureAnimp->mFace < vobj->getNumTEs())
+ {
+ LLFace * facep = drawablep->getFace(vobj->mTextureAnimp->mFace);
+ if (facep)
+ {
+ facep->setState(LLFace::TEXTURE_ANIM);
+ }
+ }
}
- if (gPipeline.canUseWindLightShadersOnObjects()
- && LLPipeline::sRenderBump)
+ if (type == LLDrawPool::POOL_ALPHA)
{
- if (te->getBumpmap())
- { //needs normal + binormal
- bump_faces.push_back(facep);
- }
- else if (te->getShiny() || !te->getFullbright())
- { //needs normal
+ if (facep->canRenderAsMask())
+ { //can be treated as alpha mask
simple_faces.push_back(facep);
}
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ else
+ {
+ if (te->getColor().mV[3] > 0.f)
+ { //only treat as alpha in the pipeline if < 100% transparent
+ drawablep->setState(LLDrawable::HAS_ALPHA);
+ }
+ alpha_faces.push_back(facep);
}
}
else
{
- if (te->getBumpmap() && LLPipeline::sRenderBump)
- { //needs normal + binormal
- bump_faces.push_back(facep);
+ if (drawablep->isState(LLDrawable::REBUILD_VOLUME))
+ {
+ facep->mLastUpdateTime = gFrameTimeSeconds;
}
- else if ((te->getShiny() && LLPipeline::sRenderBump) ||
- !(te->getFullbright() || bake_sunlight))
- { //needs normal
- simple_faces.push_back(facep);
+
+ if (gPipeline.canUseWindLightShadersOnObjects()
+ && LLPipeline::sRenderBump)
+ {
+ if (te->getBumpmap())
+ { //needs normal + binormal
+ bump_faces.push_back(facep);
+ }
+ else if (te->getShiny() || !te->getFullbright())
+ { //needs normal
+ simple_faces.push_back(facep);
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
+ fullbright_faces.push_back(facep);
+ }
}
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ else
+ {
+ if (te->getBumpmap() && LLPipeline::sRenderBump)
+ { //needs normal + binormal
+ bump_faces.push_back(facep);
+ }
+ else if ((te->getShiny() && LLPipeline::sRenderBump) ||
+ !(te->getFullbright() || bake_sunlight))
+ { //needs normal
+ simple_faces.push_back(facep);
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
+ fullbright_faces.push_back(facep);
+ }
}
}
}
+ else
+ { //face has no renderable geometry
+ facep->clearVertexBuffer();
+ }
}
- else
- { //face has no renderable geometry
- facep->clearVertexBuffer();
- }
- }
- if (is_rigged)
- {
- drawablep->setState(LLDrawable::RIGGED);
- }
- else
- {
- drawablep->clearState(LLDrawable::RIGGED);
+ if (is_rigged)
+ {
+ drawablep->setState(LLDrawable::RIGGED);
+ }
+ else
+ {
+ drawablep->clearState(LLDrawable::RIGGED);
+ }
}
}
@@ -4536,7 +4638,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (!LLPipeline::sDelayVBUpdate)
{
//drawables have been rebuilt, clear rebuild status
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
drawablep->clearState(LLDrawable::REBUILD_ALL);
@@ -4561,31 +4663,35 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild");
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
llassert(group);
if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
{
- LLFastTimer tm(FTM_VOLUME_GEOM);
+ LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
+ LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
+
S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
group->mBuilt = 1.f;
std::set<LLVertexBuffer*> mapped_buffers;
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
- LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);
LLDrawable* drawablep = *drawable_iter;
- if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) )
+ if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
{
LLVOVolume* vobj = drawablep->getVOVolume();
vobj->preRebuild();
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
+
LLVolume* volume = vobj->getVolume();
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
@@ -4595,8 +4701,15 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- face->getGeometryVolume(*volume, face->getTEOffset(),
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
+ llassert(!face->isState(LLFace::RIGGED));
+
+ if (!face->getGeometryVolume(*volume, face->getTEOffset(),
+ vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
+ { //something's gone wrong with the vertex buffer accounting, rebuild this group
+ group->dirtyGeom();
+ gPipeline.markRebuild(group, TRUE);
+ }
+
if (buff->isLocked())
{
@@ -4605,6 +4718,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
}
}
}
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform();
+ }
+
drawablep->clearState(LLDrawable::REBUILD_ALL);
}
@@ -4627,16 +4746,19 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)
{
llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
{
LLFace* face = drawablep->getFace(i);
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (face && buff && buff->isLocked())
+ if (face)
{
- buff->flush();
+ LLVertexBuffer* buff = face->getVertexBuffer();
+ if (buff && buff->isLocked())
+ {
+ buff->flush();
+ }
}
}
}
@@ -4645,7 +4767,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
}
- llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
+// llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
}
struct CompareBatchBreakerModified
@@ -4671,8 +4793,20 @@ struct CompareBatchBreakerModified
}
};
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_SORT("Draw Info Face Sort");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FACE_SIZE("Face Sizing");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_ALLOCATE("Allocate VB");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_FIND_VB("Find VB");
+static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
+
+
+
+
+
void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)
{
+ LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+
U32 buffer_usage = group->mBufferUsage;
#if LL_DARWIN
@@ -4690,15 +4824,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
- if (!distance_sort)
- {
- //sort faces by things that break batches
- std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
- }
- else
{
- //sort faces by distance
- std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+ LLFastTimer t(FTM_GEN_DRAW_INFO_SORT);
+ if (!distance_sort)
+ {
+ //sort faces by things that break batches
+ std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
+ }
+ else
+ {
+ //sort faces by distance
+ std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+ }
}
bool hud_group = group->isHUDGroup() ;
@@ -4763,57 +4900,86 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
std::vector<LLViewerTexture*> texture_list;
- if (batch_textures)
{
- U8 cur_tex = 0;
- facep->setTextureIndex(cur_tex);
- texture_list.push_back(tex);
-
- //if (can_batch_texture(facep))
+ LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE);
+ if (batch_textures)
{
- while (i != faces.end())
+ U8 cur_tex = 0;
+ facep->setTextureIndex(cur_tex);
+ texture_list.push_back(tex);
+
+ //if (can_batch_texture(facep))
{
- facep = *i;
- if (facep->getTexture() != tex)
+ while (i != faces.end())
{
- if (distance_sort)
- { //textures might be out of order, see if texture exists in current batch
- bool found = false;
- for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
- {
- if (facep->getTexture() == texture_list[tex_idx])
+ facep = *i;
+ if (facep->getTexture() != tex)
+ {
+ if (distance_sort)
+ { //textures might be out of order, see if texture exists in current batch
+ bool found = false;
+ for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
{
- cur_tex = tex_idx;
- found = true;
- break;
+ if (facep->getTexture() == texture_list[tex_idx])
+ {
+ cur_tex = tex_idx;
+ found = true;
+ break;
+ }
}
- }
- if (!found)
+ if (!found)
+ {
+ cur_tex = texture_list.size();
+ }
+ }
+ else
{
- cur_tex = texture_list.size();
+ cur_tex++;
}
- }
- else
- {
- cur_tex++;
- }
- if (!can_batch_texture(facep))
- { //face is bump mapped or has an animated texture matrix -- can't
- //batch more than 1 texture at a time
- break;
+ if (!can_batch_texture(facep))
+ { //face is bump mapped or has an animated texture matrix -- can't
+ //batch more than 1 texture at a time
+ break;
+ }
+
+ if (cur_tex >= texture_index_channels)
+ { //cut batches when index channels are depleted
+ break;
+ }
+
+ tex = facep->getTexture();
+
+ texture_list.push_back(tex);
}
- if (cur_tex >= texture_index_channels)
- { //cut batches when index channels are depleted
+ if (geom_count + facep->getGeomCount() > max_vertices)
+ { //cut batches on geom count too big
break;
}
- tex = facep->getTexture();
+ ++i;
+ index_count += facep->getIndicesCount();
+ geom_count += facep->getGeomCount();
- texture_list.push_back(tex);
+ facep->setTextureIndex(cur_tex);
}
+ }
+
+ tex = texture_list[0];
+ }
+ else
+ {
+ while (i != faces.end() &&
+ (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
+ {
+ facep = *i;
+
+
+ //face has no texture index
+ facep->mDrawInfo = NULL;
+ facep->setTextureIndex(255);
if (geom_count + facep->getGeomCount() > max_vertices)
{ //cut batches on geom count too big
@@ -4823,69 +4989,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
++i;
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
-
- facep->setTextureIndex(cur_tex);
}
}
-
- tex = texture_list[0];
}
- else
- {
- while (i != faces.end() &&
- (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
- {
- facep = *i;
-
-
- //face has no texture index
- facep->mDrawInfo = NULL;
- facep->setTextureIndex(255);
- if (geom_count + facep->getGeomCount() > max_vertices)
- { //cut batches on geom count too big
- break;
- }
-
- ++i;
- index_count += facep->getIndicesCount();
- geom_count += facep->getGeomCount();
- }
- }
-
- //create/delete/resize vertex buffer if needed
+ //create vertex buffer
LLVertexBuffer* buffer = NULL;
- { //try to find a buffer to reuse
- LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(*face_iter);
-
- if (found_iter != group->mBufferMap[mask].end())
- {
- if ((U32) buffer_index < found_iter->second.size())
- {
- buffer = found_iter->second[buffer_index];
- }
- }
- }
-
- if (!buffer || !buffer->isWriteable())
- { //create new buffer if needed
+ {
+ LLFastTimer t(FTM_GEN_DRAW_INFO_ALLOCATE);
buffer = createVertexBuffer(mask, buffer_usage);
buffer->allocateBuffer(geom_count, index_count, TRUE);
}
- else
- { //resize pre-existing buffer
- if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != buffer_usage ||
- buffer->getTypeMask() != mask)
- {
- buffer = createVertexBuffer(mask, buffer_usage);
- buffer->allocateBuffer(geom_count, index_count, TRUE);
- }
- else
- {
- buffer->resizeBuffer(geom_count, index_count);
- }
- }
group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize();
@@ -4919,10 +5034,25 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
LLVOVolume* vobj = drawablep->getVOVolume();
LLVolume* volume = vobj->getVolume();
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(true);
+ }
+
U32 te_idx = facep->getTEOffset();
- facep->getGeometryVolume(*volume, te_idx,
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset);
+ llassert(!facep->isState(LLFace::RIGGED));
+
+ if (!facep->getGeometryVolume(*volume, te_idx,
+ vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset,true))
+ {
+ llwarns << "Failed to get geometry for face!" << llendl;
+ }
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform(false);
+ }
}
}
@@ -5086,7 +5216,8 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
mFaceList.clear();
//for each drawable
- for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
+
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = *drawable_iter;
@@ -5106,17 +5237,21 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
//sum up face verts and indices
drawablep->updateFaceSize(i);
LLFace* facep = drawablep->getFace(i);
- if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA)
+ if (facep)
{
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
- llassert(facep->getIndicesCount() < 65536);
- //remember face (for sorting)
- mFaceList.push_back(facep);
- }
- else
- {
- facep->clearVertexBuffer();
+ if (facep->hasGeometry() && facep->getPixelArea() > FORCE_CULL_AREA &&
+ facep->getGeomCount() + vertex_count <= 65536)
+ {
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
+ //remember face (for sorting)
+ mFaceList.push_back(facep);
+ }
+ else
+ {
+ facep->clearVertexBuffer();
+ }
}
}
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 3cf434dc26..5a0960204c 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -68,7 +68,7 @@ class LLVolumeInterface
public:
virtual ~LLVolumeInterface() { }
virtual LLVolumeInterfaceType getInterfaceType() const = 0;
- virtual BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0;
+ virtual void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) = 0;
virtual BOOL doUpdateGeometry(LLDrawable *drawable) = 0;
virtual LLVector3 getPivotPosition() const = 0;
virtual void onSetVolume(const LLVolumeParams &volume_params, const S32 detail) = 0;
@@ -79,7 +79,7 @@ public:
virtual bool isVolumeGlobal() const = 0; // Are we in global space?
virtual bool isActive() const = 0; // Is this object currently active?
virtual const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const = 0;
- virtual void updateRelativeXform() = 0;
+ virtual void updateRelativeXform(bool force_identity = false) = 0;
virtual U32 getID() const = 0;
virtual void preRebuild() = 0;
};
@@ -203,7 +203,7 @@ public:
LLAssetType::EType type,
void* user_data, S32 status, LLExtStat ext_status);
- void updateRelativeXform();
+ void updateRelativeXform(bool force_identity = false);
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
/*virtual*/ void updateFaceSize(S32 idx);
/*virtual*/ BOOL updateLOD();
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index cd78157944..942eff6171 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -146,6 +146,10 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
drawable->addFace(poolp, NULL);
}
face = drawable->getFace(0);
+ if (!face)
+ {
+ return TRUE;
+ }
// LLVector2 uvs[4];
// LLVector3 vtx[4];
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 3d971e738e..78ee3e4fd9 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -657,7 +657,10 @@ void LLWorld::updateRegions(F32 max_update_time)
if (did_one && max_time <= 0.f)
break;
max_time = llmin(max_time, max_update_time*.1f);
- did_one |= regionp->idleUpdate(max_update_time);
+ if (regionp->idleUpdate(max_update_time))
+ {
+ did_one = TRUE;
+ }
}
}
@@ -837,21 +840,23 @@ void LLWorld::updateWaterObjects()
}
mHoleWaterObjects.clear();
+ // Use the water height of the region we're on for areas where there is no region
+ F32 water_height = gAgent.getRegion()->getWaterHeight();
+
// Now, get a list of the holes
S32 x, y;
- F32 water_height = gAgent.getRegion()->getWaterHeight() + 256.f;
for (x = min_x; x <= max_x; x += rwidth)
{
for (y = min_y; y <= max_y; y += rwidth)
{
U64 region_handle = to_region_handle(x, y);
if (!getRegionFromHandle(region_handle))
- {
+ { // No region at that area, so make water
LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());
waterp->setUseTexture(FALSE);
waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
y + rwidth/2,
- water_height));
+ 256.f + water_height));
waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
gPipeline.createObject(waterp);
mHoleWaterObjects.push_back(waterp);
@@ -908,7 +913,7 @@ void LLWorld::updateWaterObjects()
}
waterp->setRegion(gAgent.getRegion());
- LLVector3d water_pos(water_center_x, water_center_y, water_height) ;
+ LLVector3d water_pos(water_center_x, water_center_y, 256.f + water_height) ;
LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);
//stretch out to horizon
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ab994c71cb..c195f0ea14 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -51,6 +51,10 @@
// newview includes
#include "llagent.h"
#include "llagentcamera.h"
+#include "llappviewer.h"
+#include "lltexturecache.h"
+#include "lltexturefetch.h"
+#include "llimageworker.h"
#include "lldrawable.h"
#include "lldrawpoolalpha.h"
#include "lldrawpoolavatar.h"
@@ -113,6 +117,8 @@
//#define DEBUG_INDICES
#endif
+bool gShiftFrame = false;
+
//cached settings
BOOL LLPipeline::RenderAvatarVP;
BOOL LLPipeline::VertexShaderEnable;
@@ -187,6 +193,7 @@ F32 LLPipeline::RenderShadowFOVCutoff;
BOOL LLPipeline::CameraOffset;
F32 LLPipeline::CameraMaxCoF;
F32 LLPipeline::CameraDoFResScale;
+F32 LLPipeline::RenderAutoHideSurfaceAreaLimit;
const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;
const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f;
@@ -209,7 +216,7 @@ BOOL gDebugPipeline = FALSE;
LLPipeline gPipeline;
const LLMatrix4* gGLLastMatrix = NULL;
-LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Geometry");
+LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Render Geometry");
LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass");
LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible");
LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion");
@@ -226,8 +233,13 @@ LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
+LLFastTimer::DeclareTimer FTM_PIPELINE_CREATE("Pipeline Create");
LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool");
LLFastTimer::DeclareTimer FTM_POOLS("Pools");
+LLFastTimer::DeclareTimer FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)");
+LLFastTimer::DeclareTimer FTM_DEFERRED_POOLS("Pools (Deferred)");
+LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)");
+LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLS("Pools (Post)");
LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO");
LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State");
LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline");
@@ -263,6 +275,7 @@ std::string gPoolNames[] =
void drawBox(const LLVector3& c, const LLVector3& r);
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v);
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
glh::matrix4f glh_copy_matrix(F32* src)
{
@@ -402,9 +415,11 @@ LLPipeline::LLPipeline() :
mInitialized(FALSE),
mVertexShadersEnabled(FALSE),
mVertexShadersLoaded(0),
+ mTransformFeedbackPrimitives(0),
mRenderDebugFeatureMask(0),
mRenderDebugMask(0),
mOldRenderDebugMask(0),
+ mMeshDirtyQueryObject(0),
mGroupQ1Locked(false),
mGroupQ2Locked(false),
mResetVertexBuffers(false),
@@ -503,6 +518,11 @@ void LLPipeline::init()
mSpotLightFade[i] = 1.f;
}
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+
mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
mDeferredVB->allocateBuffer(8, 0, true);
setLightingDetail(-1);
@@ -592,6 +612,7 @@ void LLPipeline::init()
gSavedSettings.getControl("CameraOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
gSavedSettings.getControl("CameraMaxCoF")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
gSavedSettings.getControl("CameraDoFResScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
+ gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
}
LLPipeline::~LLPipeline()
@@ -691,6 +712,12 @@ void LLPipeline::destroyGL()
{
LLVertexBuffer::sEnableVBOs = FALSE;
}
+
+ if (mMeshDirtyQueryObject)
+ {
+ glDeleteQueriesARB(1, &mMeshDirtyQueryObject);
+ mMeshDirtyQueryObject = 0;
+ }
}
static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
@@ -938,6 +965,7 @@ void LLPipeline::refreshCachedSettings()
LLPipeline::sUseOcclusion =
(!gUseWireframe
+ && LLGLSLShader::sNoFixedFunction
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
&& gSavedSettings.getBOOL("UseOcclusion")
&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
@@ -1015,6 +1043,7 @@ void LLPipeline::refreshCachedSettings()
CameraOffset = gSavedSettings.getBOOL("CameraOffset");
CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF");
CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale");
+ RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");
updateRenderDeferred();
}
@@ -1025,13 +1054,13 @@ void LLPipeline::releaseGLBuffers()
if (mNoiseMap)
{
- LLImageGL::deleteTextures(1, &mNoiseMap);
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mNoiseMap);
mNoiseMap = 0;
}
if (mTrueNoiseMap)
{
- LLImageGL::deleteTextures(1, &mTrueNoiseMap);
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mTrueNoiseMap);
mTrueNoiseMap = 0;
}
@@ -1055,7 +1084,7 @@ void LLPipeline::releaseLUTBuffers()
{
if (mLightFunc)
{
- LLImageGL::deleteTextures(1, &mLightFunc);
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc);
mLightFunc = 0;
}
}
@@ -1133,10 +1162,10 @@ void LLPipeline::createGLBuffers()
noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
}
- LLImageGL::generateTextures(1, &mNoiseMap);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -1149,9 +1178,9 @@ void LLPipeline::createGLBuffers()
noise[i] = ll_frand()*2.0-1.0;
}
- LLImageGL::generateTextures(1, &mTrueNoiseMap);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -1205,9 +1234,9 @@ void LLPipeline::createLUTBuffers()
}
}
- LLImageGL::generateTextures(1, &mLightFunc);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
@@ -1344,7 +1373,7 @@ public:
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
- if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->getData().empty())
+ if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
{
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
{
@@ -1653,7 +1682,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)
void LLPipeline::createObjects(F32 max_dtime)
{
- LLFastTimer ftm(FTM_GEO_UPDATE);
+ LLFastTimer ftm(FTM_PIPELINE_CREATE);
LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS);
LLTimer update_timer;
@@ -1815,6 +1844,16 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
if (done)
{
drawablep->clearState(LLDrawable::ON_MOVE_LIST);
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ { //will likely not receive any future world matrix updates
+ // -- this keeps attachments from getting stuck in space and falling off your avatar
+ drawablep->clearState(LLDrawable::ANIMATED_CHILD);
+ markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, TRUE);
+ if (drawablep->getVObj())
+ {
+ drawablep->getVObj()->dirtySpatialGroup(TRUE);
+ }
+ }
iter = moved_list.erase(curiter);
}
}
@@ -1939,7 +1978,7 @@ void LLPipeline::clearReferences()
void check_references(LLSpatialGroup* group, LLDrawable* drawable)
{
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
if (drawable == *i)
{
@@ -1961,7 +2000,7 @@ void check_references(LLDrawable* drawable, LLFace* face)
void check_references(LLSpatialGroup* group, LLFace* face)
{
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawable = *i;
check_references(drawable, face);
@@ -1973,25 +2012,25 @@ void LLPipeline::checkReferences(LLFace* face)
#if 0
if (sCull)
{
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, face);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, face);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, face);
}
- for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
{
LLDrawable* drawable = *iter;
check_references(drawable, face);
@@ -2005,25 +2044,25 @@ void LLPipeline::checkReferences(LLDrawable* drawable)
#if 0
if (sCull)
{
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, drawable);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, drawable);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, drawable);
}
- for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
{
if (drawable == *iter)
{
@@ -2056,19 +2095,19 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info)
#if 0
if (sCull)
{
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, draw_info);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, draw_info);
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
check_references(group, draw_info);
@@ -2082,7 +2121,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
#if 0
if (sCull)
{
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
if (group == *iter)
{
@@ -2090,7 +2129,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
}
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
{
if (group == *iter)
{
@@ -2098,7 +2137,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
}
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
if (group == *iter)
{
@@ -2209,8 +2248,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLLastModelView);
-
- LLVertexBuffer::unbind();
LLGLDisable blend(GL_BLEND);
LLGLDisable test(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -2254,7 +2291,16 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
{ //if no shader is currently bound, use the occlusion shader instead of fixed function if we can
// (shadow render uses a special shader that clamps to clip planes)
bound_shader = true;
- gOcclusionProgram.bind();
+ gOcclusionCubeProgram.bind();
+ }
+
+ if (sUseOcclusion > 1)
+ {
+ if (mCubeVB.isNull())
+ { //cube VB will be used for issuing occlusion queries
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
}
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
@@ -2286,7 +2332,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (bound_shader)
{
- gOcclusionProgram.unbind();
+ gOcclusionCubeProgram.unbind();
}
camera.disableUserClipPlane();
@@ -2330,7 +2376,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
{
- if (group->getData().empty())
+ if (group->isEmpty())
{
return;
}
@@ -2419,15 +2465,21 @@ void LLPipeline::doOcclusion(LLCamera& camera)
{
if (LLPipeline::sShadowRender)
{
- gDeferredShadowProgram.bind();
+ gDeferredShadowCubeProgram.bind();
}
else
{
- gOcclusionProgram.bind();
+ gOcclusionCubeProgram.bind();
}
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
+ if (mCubeVB.isNull())
+ { //cube VB will be used for issuing occlusion queries
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
group->doOcclusion(&camera);
@@ -2438,11 +2490,11 @@ void LLPipeline::doOcclusion(LLCamera& camera)
{
if (LLPipeline::sShadowRender)
{
- gDeferredShadowProgram.unbind();
+ gDeferredShadowCubeProgram.unbind();
}
else
{
- gOcclusionProgram.unbind();
+ gOcclusionCubeProgram.unbind();
}
}
@@ -2461,22 +2513,36 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
return update_complete;
}
+static LLFastTimer::DeclareTimer FTM_SEED_VBO_POOLS("Seed VBO Pool");
+
+static LLFastTimer::DeclareTimer FTM_UPDATE_GL("Update GL");
+
void LLPipeline::updateGL()
{
- while (!LLGLUpdate::sGLQ.empty())
{
- LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
- glu->updateGL();
- glu->mInQ = FALSE;
- LLGLUpdate::sGLQ.pop_front();
+ LLFastTimer t(FTM_UPDATE_GL);
+ while (!LLGLUpdate::sGLQ.empty())
+ {
+ LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
+ glu->updateGL();
+ glu->mInQ = FALSE;
+ LLGLUpdate::sGLQ.pop_front();
+ }
+ }
+
+ { //seed VBO Pools
+ LLFastTimer t(FTM_SEED_VBO_POOLS);
+ LLVertexBuffer::seedPools();
}
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups");
+
void LLPipeline::rebuildPriorityGroups()
{
+ LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS);
LLTimer update_timer;
LLMemType mt(LLMemType::MTYPE_PIPELINE);
-
assertInitialized();
gMeshRepo.notifyLoadedMeshes();
@@ -2495,7 +2561,9 @@ void LLPipeline::rebuildPriorityGroups()
mGroupQ1Locked = false;
}
-
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_GROUPS("Rebuild Groups");
+
void LLPipeline::rebuildGroups()
{
if (mGroupQ2.empty())
@@ -2503,6 +2571,7 @@ void LLPipeline::rebuildGroups()
return;
}
+ LLFastTimer t(FTM_REBUILD_GROUPS);
mGroupQ2Locked = true;
// Iterate through some drawables on the non-priority build queue
S32 size = (S32) mGroupQ2.size();
@@ -2744,6 +2813,10 @@ void LLPipeline::markShift(LLDrawable *drawablep)
}
}
+static LLFastTimer::DeclareTimer FTM_SHIFT_DRAWABLE("Shift Drawable");
+static LLFastTimer::DeclareTimer FTM_SHIFT_OCTREE("Shift Octree");
+static LLFastTimer::DeclareTimer FTM_SHIFT_HUD("Shift HUD");
+
void LLPipeline::shiftObjects(const LLVector3 &offset)
{
LLMemType mt(LLMemType::MTYPE_PIPELINE_SHIFT_OBJECTS);
@@ -2756,35 +2829,46 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
LLVector4a offseta;
offseta.load3(offset.mV);
- for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
- iter != mShiftList.end(); iter++)
{
- LLDrawable *drawablep = *iter;
- if (drawablep->isDead())
+ LLFastTimer t(FTM_SHIFT_DRAWABLE);
+
+ for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
+ iter != mShiftList.end(); iter++)
{
- continue;
- }
- drawablep->shiftPos(offseta);
- drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
+ LLDrawable *drawablep = *iter;
+ if (drawablep->isDead())
+ {
+ continue;
+ }
+ drawablep->shiftPos(offseta);
+ drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
+ }
+ mShiftList.resize(0);
}
- mShiftList.resize(0);
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+
{
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ LLFastTimer t(FTM_SHIFT_OCTREE);
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
{
- part->shift(offseta);
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ part->shift(offseta);
+ }
}
}
}
- LLHUDText::shiftAll(offset);
- LLHUDNameTag::shiftAll(offset);
+ {
+ LLFastTimer t(FTM_SHIFT_HUD);
+ LLHUDText::shiftAll(offset);
+ LLHUDNameTag::shiftAll(offset);
+ }
display_update_camera();
}
@@ -2817,8 +2901,10 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable)
}
}
+static LLFastTimer::DeclareTimer FTM_PROCESS_PARTITIONQ("PartitionQ");
void LLPipeline::processPartitionQ()
{
+ LLFastTimer t(FTM_PROCESS_PARTITIONQ);
for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter)
{
LLDrawable* drawable = *iter;
@@ -2833,6 +2919,11 @@ void LLPipeline::processPartitionQ()
mPartitionQ.clear();
}
+void LLPipeline::markMeshDirty(LLSpatialGroup* group)
+{
+ mMeshDirtyGroup.push_back(group);
+}
+
void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
{
LLMemType mt(LLMemType::MTYPE_PIPELINE);
@@ -2929,7 +3020,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
//LLVertexBuffer::unbind();
grabReferences(result);
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
group->checkOcclusion();
@@ -2940,7 +3031,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
else
{
group->setVisible();
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
markVisible(*i, camera);
}
@@ -2955,9 +3046,9 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
{
LLSpatialGroup* last_group = NULL;
- for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
+ for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
{
- LLCullResult::bridge_list_t::iterator cur_iter = i;
+ LLCullResult::bridge_iterator cur_iter = i;
LLSpatialBridge* bridge = *cur_iter;
LLSpatialGroup* group = bridge->getSpatialGroup();
@@ -2987,7 +3078,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
}
}
- for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
group->checkOcclusion();
@@ -3009,7 +3100,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
LLFastTimer ftm(FTM_STATESORT_DRAWABLE);
- for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList();
+ for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList();
iter != sCull->endVisibleList(); ++iter)
{
LLDrawable *drawablep = *iter;
@@ -3028,7 +3119,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT);
if (group->changeLOD())
{
- for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
LLDrawable* drawablep = *i;
stateSort(drawablep, camera);
@@ -3145,13 +3236,13 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
}
-void forAllDrawables(LLCullResult::sg_list_t::iterator begin,
- LLCullResult::sg_list_t::iterator end,
+void forAllDrawables(LLCullResult::sg_iterator begin,
+ LLCullResult::sg_iterator end,
void (*func)(LLDrawable*))
{
- for (LLCullResult::sg_list_t::iterator i = begin; i != end; ++i)
+ for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
- for (LLSpatialGroup::element_iter j = (*i)->getData().begin(); j != (*i)->getData().end(); ++j)
+ for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)
{
func(*j);
}
@@ -3184,7 +3275,11 @@ void renderScriptedBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
}
}
}
@@ -3210,7 +3305,11 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
}
}
}
@@ -3235,7 +3334,11 @@ void renderPhysicalBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
}
}
}
@@ -3271,7 +3374,11 @@ void renderMOAPBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
}
}
}
@@ -3296,7 +3403,11 @@ void renderParticleBeacons(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
}
}
}
@@ -3314,7 +3425,11 @@ void renderSoundHighlights(LLDrawable* drawablep)
S32 count = drawablep->getNumFaces();
for (face_id = 0; face_id < count; face_id++)
{
- gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) );
+ LLFace * facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
}
}
}
@@ -3329,7 +3444,7 @@ void LLPipeline::postSort(LLCamera& camera)
llpushcallstacks ;
//rebuild drawable geometry
- for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
+ for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (!sUseOcclusion ||
@@ -3345,27 +3460,15 @@ void LLPipeline::postSort(LLCamera& camera)
rebuildPriorityGroups();
llpushcallstacks ;
- const S32 bin_count = 1024*8;
-
- static LLCullResult::drawinfo_list_t alpha_bins[bin_count];
- static U32 bin_size[bin_count];
-
- //clear one bin per frame to avoid memory bloat
- static S32 clear_idx = 0;
- clear_idx = (1+clear_idx)%bin_count;
- alpha_bins[clear_idx].clear();
-
- for (U32 j = 0; j < bin_count; j++)
- {
- bin_size[j] = 0;
- }
-
+
//build render map
- for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
+ for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (sUseOcclusion &&
- group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED) ||
+ (RenderAutoHideSurfaceAreaLimit > 0.f &&
+ group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))
{
continue;
}
@@ -3429,11 +3532,43 @@ void LLPipeline::postSort(LLCamera& camera)
}
}
}
+
+ //flush particle VB
+ LLVOPartGroup::sVB->flush();
+
+ /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty();
+
+ if (use_transform_feedback)
+ { //place a query around potential transform feedback code for synchronization
+ mTransformFeedbackPrimitives = 0;
+
+ if (!mMeshDirtyQueryObject)
+ {
+ glGenQueriesARB(1, &mMeshDirtyQueryObject);
+ }
+
+ glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
+ }*/
+
+ //pack vertex buffers for groups that chose to delay their updates
+ for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
+ {
+ (*iter)->rebuildMesh();
+ }
+
+ /*if (use_transform_feedback)
+ {
+ glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ }*/
+
+ mMeshDirtyGroup.clear();
+
if (!sShadowRender)
{
std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
}
+
llpushcallstacks ;
// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender)
@@ -3507,7 +3642,11 @@ void LLPipeline::postSort(LLCamera& camera)
{
if (object->mDrawable)
{
- gPipeline.mSelectedFaces.push_back(object->mDrawable->getFace(te));
+ LLFace * facep = object->mDrawable->getFace(te);
+ if (facep)
+ {
+ gPipeline.mSelectedFaces.push_back(facep);
+ }
}
return true;
}
@@ -3516,6 +3655,33 @@ void LLPipeline::postSort(LLCamera& camera)
}
}
+ /*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence");
+ static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work");
+ if (use_transform_feedback)
+ { //using transform feedback, wait for transform feedback to complete
+ LLFastTimer t(FTM_TRANSFORM_WAIT);
+
+ S32 done = 0;
+ //glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count);
+
+ glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
+
+ while (!done)
+ {
+ {
+ LLFastTimer t(FTM_TRANSFORM_DO_WORK);
+ F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+ //do some useful work while we wait
+ LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+ LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+ LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+ }
+ glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
+ }
+
+ mTransformFeedbackPrimitives = 0;
+ }*/
+
//LLSpatialGroup::sNoDelete = FALSE;
llpushcallstacks ;
}
@@ -3998,7 +4164,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
LLMemType mt_rgd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_DEFFERRED);
LLFastTimer t(FTM_RENDER_GEOMETRY);
- LLFastTimer t2(FTM_POOLS);
+ LLFastTimer t2(FTM_DEFERRED_POOLS);
LLGLEnable cull(GL_CULL_FACE);
@@ -4040,7 +4206,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
{
- LLFastTimer t(FTM_POOLRENDER);
+ LLFastTimer t(FTM_DEFERRED_POOLRENDER);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4093,7 +4259,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
LLMemType mt_rgpd(LLMemType::MTYPE_PIPELINE_RENDER_GEOM_POST_DEF);
- LLFastTimer t(FTM_POOLS);
+ LLFastTimer t(FTM_POST_DEFERRED_POOLS);
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -4127,7 +4293,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
{
- LLFastTimer t(FTM_POOLRENDER);
+ LLFastTimer t(FTM_POST_DEFERRED_POOLRENDER);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4317,7 +4483,7 @@ void LLPipeline::renderPhysicsDisplay()
}
}
- for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
+ for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
{
LLSpatialBridge* bridge = *i;
if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
@@ -4412,7 +4578,7 @@ void LLPipeline::renderDebug()
}
}
- for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
+ for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
{
LLSpatialBridge* bridge = *i;
if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
@@ -4664,8 +4830,11 @@ void LLPipeline::renderDebug()
}
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools");
+
void LLPipeline::rebuildPools()
{
+ LLFastTimer t(FTM_REBUILD_POOLS);
LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS);
assertInitialized();
@@ -6212,7 +6381,10 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
for (S32 i = 0; i < drawable->getNumFaces(); i++)
{
LLFace* facep = drawable->getFace(i);
- facep->clearVertexBuffer();
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
}
}
@@ -6221,15 +6393,20 @@ void LLPipeline::resetVertexBuffers()
mResetVertexBuffers = true;
}
+static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB");
+
void LLPipeline::doResetVertexBuffers()
{
if (!mResetVertexBuffers)
{
return;
}
-
+
+ LLFastTimer t(FTM_RESET_VB);
mResetVertexBuffers = false;
+ mCubeVB = NULL;
+
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
@@ -6248,11 +6425,15 @@ void LLPipeline::doResetVertexBuffers()
gSky.resetVertexBuffers();
+ LLVOPartGroup::destroyGL();
+
LLVertexBuffer::cleanupClass();
//delete all name pool caches
LLGLNamePool::cleanupPools();
+
+
if (LLVertexBuffer::sGLCount > 0)
{
llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl;
@@ -6272,6 +6453,8 @@ void LLPipeline::doResetVertexBuffers()
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+
+ LLVOPartGroup::restoreGL();
}
void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)
@@ -7459,12 +7642,17 @@ void LLPipeline::renderDeferredLighting()
std::list<LLVector4> light_colors;
LLVertexBuffer::unbind();
- LLVector4a* v = (LLVector4a*) vert.get();
{
bindDeferredShader(gDeferredLightProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
{
@@ -7510,25 +7698,7 @@ void LLPipeline::renderDeferredLighting()
}
sVisibleLightCount++;
-
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
- //vertex positions are encoded so the 3 bits of their vertex index
- //correspond to their axis facing, with bit position 3,2,1 matching
- //axis facing x,y,z, bit set meaning positive facing, bit clear
- //meaning negative facing
- mDeferredVB->getVertexStrider(vert);
- v[0].set(c[0]-s,c[1]-s,c[2]-s); // 0 - 0000
- v[1].set(c[0]-s,c[1]-s,c[2]+s); // 1 - 0001
- v[2].set(c[0]-s,c[1]+s,c[2]-s); // 2 - 0010
- v[3].set(c[0]-s,c[1]+s,c[2]+s); // 3 - 0011
-
- v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100
- v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101
- v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110
- v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111
-
+
if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
@@ -7546,16 +7716,13 @@ void LLPipeline::renderDeferredLighting()
}
LLFastTimer ftm(FTM_LOCAL_LIGHTS);
- //glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
- gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- //gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center));
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
stop_glerror();
}
}
@@ -7568,6 +7735,9 @@ void LLPipeline::renderDeferredLighting()
continue;
}
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
}
@@ -7580,7 +7750,7 @@ void LLPipeline::renderDeferredLighting()
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bindDeferredShader(gDeferredSpotLightProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
@@ -7598,36 +7768,17 @@ void LLPipeline::renderDeferredLighting()
sVisibleLightCount++;
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
setupSpotLight(gDeferredSpotLightProgram, drawablep);
LLColor3 col = volume->getLightColor();
- //vertex positions are encoded so the 3 bits of their vertex index
- //correspond to their axis facing, with bit position 3,2,1 matching
- //axis facing x,y,z, bit set meaning positive facing, bit clear
- //meaning negative facing
- mDeferredVB->getVertexStrider(vert);
- v[0].set(c[0]-s,c[1]-s,c[2]-s); // 0 - 0000
- v[1].set(c[0]-s,c[1]-s,c[2]+s); // 1 - 0001
- v[2].set(c[0]-s,c[1]+s,c[2]-s); // 2 - 0010
- v[3].set(c[0]-s,c[1]+s,c[2]+s); // 3 - 0011
-
- v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100
- v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101
- v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110
- v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111
-
- gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center));
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
}
gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
unbindDeferredShader(gDeferredSpotLightProgram);
@@ -7659,8 +7810,6 @@ void LLPipeline::renderDeferredLighting()
LLVector4 light[max_count];
LLVector4 col[max_count];
-// glVertexPointer(2, GL_FLOAT, 0, vert);
-
F32 far_z = 0.f;
while (!fullscreen_lights.empty())
@@ -8317,7 +8466,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
if (use_shader)
{
- gDeferredShadowProgram.bind();
+ gDeferredShadowCubeProgram.bind();
}
updateCull(shadow_cam, result);
@@ -8334,17 +8483,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
stop_glerror();
gGLLastMatrix = NULL;
- {
- //LLGLDepthTest depth(GL_TRUE);
- //glClear(GL_DEPTH_BUFFER_BIT);
- }
-
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
stop_glerror();
- //glCullFace(GL_FRONT);
-
LLVertexBuffer::unbind();
{
@@ -8352,6 +8494,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{ //occlusion program is general purpose depth-only no-textures
gOcclusionProgram.bind();
}
+ else
+ {
+ gDeferredShadowProgram.bind();
+ }
gGL.diffuseColor4f(1,1,1,1);
gGL.setColorMask(false, false);
@@ -8400,7 +8546,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
//glCullFace(GL_BACK);
- gDeferredShadowProgram.bind();
+ gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
doOcclusion(shadow_cam);
@@ -8675,6 +8821,8 @@ void LLPipeline::generateHighlight(LLCamera& camera)
}
+static LLFastTimer::DeclareTimer FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
+
void LLPipeline::generateSunShadow(LLCamera& camera)
{
if (!sRenderDeferred || RenderShadowDetail <= 0)
@@ -8682,6 +8830,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
return;
}
+ LLFastTimer t(FTM_GEN_SUN_SHADOW);
+
BOOL skip_avatar_update = FALSE;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
{
@@ -9427,7 +9577,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)
{
- for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
+ for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (!group->isDead() &&
@@ -9440,6 +9590,12 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu
}
}
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_SETUP("Impostor Setup");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_BACKGROUND("Impostor Background");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_ALLOCATE("Impostor Allocate");
+static LLFastTimer::DeclareTimer FTM_IMPOSTOR_RESIZE("Impostor Resize");
+
void LLPipeline::generateImpostor(LLVOAvatar* avatar)
{
LLMemType mt_gi(LLMemType::MTYPE_PIPELINE_GENERATE_IMPOSTOR);
@@ -9495,101 +9651,114 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
sImpostorRender = TRUE;
LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
- markVisible(avatar->mDrawable, *viewer_camera);
- LLVOAvatar::sUseImpostors = FALSE;
- LLVOAvatar::attachment_map_t::iterator iter;
- for (iter = avatar->mAttachmentPoints.begin();
- iter != avatar->mAttachmentPoints.end();
- ++iter)
{
- LLViewerJointAttachment *attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
+ LLFastTimer t(FTM_IMPOSTOR_MARK_VISIBLE);
+ markVisible(avatar->mDrawable, *viewer_camera);
+ LLVOAvatar::sUseImpostors = FALSE;
+
+ LLVOAvatar::attachment_map_t::iterator iter;
+ for (iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end();
+ ++iter)
{
- if (LLViewerObject* attached_object = (*attachment_iter))
+ LLViewerJointAttachment *attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ if (LLViewerObject* attached_object = (*attachment_iter))
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
}
}
}
stateSort(*LLViewerCamera::getInstance(), result);
- const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
- LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
-
LLCamera camera = *viewer_camera;
-
- camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
-
LLVector2 tdim;
+ U32 resY = 0;
+ U32 resX = 0;
+ {
+ LLFastTimer t(FTM_IMPOSTOR_SETUP);
+ const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
+ LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
- LLVector4a half_height;
- half_height.setSub(ext[1], ext[0]);
- half_height.mul(0.5f);
+ camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis());
+
+ LLVector4a half_height;
+ half_height.setSub(ext[1], ext[0]);
+ half_height.mul(0.5f);
- LLVector4a left;
- left.load3(camera.getLeftAxis().mV);
- left.mul(left);
- left.normalize3fast();
+ LLVector4a left;
+ left.load3(camera.getLeftAxis().mV);
+ left.mul(left);
+ left.normalize3fast();
- LLVector4a up;
- up.load3(camera.getUpAxis().mV);
- up.mul(up);
- up.normalize3fast();
+ LLVector4a up;
+ up.load3(camera.getUpAxis().mV);
+ up.mul(up);
+ up.normalize3fast();
- tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
- tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
+ tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
+ tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
- F32 distance = (pos-camera.getOrigin()).length();
- F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
- F32 aspect = tdim.mV[0]/tdim.mV[1];
- glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
- glh_set_current_projection(persp);
- gGL.loadMatrix(persp.m);
+ F32 distance = (pos-camera.getOrigin()).length();
+ F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
+ F32 aspect = tdim.mV[0]/tdim.mV[1];
+ glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
+ glh_set_current_projection(persp);
+ gGL.loadMatrix(persp.m);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- glh::matrix4f mat;
- camera.getOpenGLTransform(mat.m);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ glh::matrix4f mat;
+ camera.getOpenGLTransform(mat.m);
- mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
+ mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
- gGL.loadMatrix(mat.m);
- glh_set_current_modelview(mat);
+ gGL.loadMatrix(mat.m);
+ glh_set_current_modelview(mat);
- glClearColor(0.0f,0.0f,0.0f,0.0f);
- gGL.setColorMask(true, true);
+ glClearColor(0.0f,0.0f,0.0f,0.0f);
+ gGL.setColorMask(true, true);
- // get the number of pixels per angle
- F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
+ // get the number of pixels per angle
+ F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView());
- //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
- U32 resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
- U32 resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
+ //get resolution based on angle width and height of impostor (double desired resolution to prevent aliasing)
+ resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
+ resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
- if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() ||
- resY != avatar->mImpostor.getHeight())
- {
- avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+ if (!avatar->mImpostor.isComplete())
+ {
+ LLFastTimer t(FTM_IMPOSTOR_ALLOCATE);
+ avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ addDeferredAttachments(avatar->mImpostor);
+ }
- if (LLPipeline::sRenderDeferred)
+ gGL.getTexUnit(0)->bind(&avatar->mImpostor);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ else if(resX != avatar->mImpostor.getWidth() ||
+ resY != avatar->mImpostor.getHeight())
{
- addDeferredAttachments(avatar->mImpostor);
+ LLFastTimer t(FTM_IMPOSTOR_RESIZE);
+ avatar->mImpostor.resize(resX,resY,GL_RGBA);
}
-
- gGL.getTexUnit(0)->bind(&avatar->mImpostor);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- avatar->mImpostor.bindTarget();
+ avatar->mImpostor.bindTarget();
+ }
if (LLPipeline::sRenderDeferred)
{
@@ -9606,6 +9775,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
}
{ //create alpha mask based on depth buffer (grey out if muted)
+ LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
@@ -9691,22 +9861,22 @@ BOOL LLPipeline::hasRenderBatches(const U32 type) const
return sCull->getRenderMapSize(type) > 0;
}
-LLCullResult::drawinfo_list_t::iterator LLPipeline::beginRenderMap(U32 type)
+LLCullResult::drawinfo_iterator LLPipeline::beginRenderMap(U32 type)
{
return sCull->beginRenderMap(type);
}
-LLCullResult::drawinfo_list_t::iterator LLPipeline::endRenderMap(U32 type)
+LLCullResult::drawinfo_iterator LLPipeline::endRenderMap(U32 type)
{
return sCull->endRenderMap(type);
}
-LLCullResult::sg_list_t::iterator LLPipeline::beginAlphaGroups()
+LLCullResult::sg_iterator LLPipeline::beginAlphaGroups()
{
return sCull->beginAlphaGroups();
}
-LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
+LLCullResult::sg_iterator LLPipeline::endAlphaGroups()
{
return sCull->endAlphaGroups();
}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index b8b4f164fe..ed707551ec 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -163,6 +163,7 @@ public:
void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE);
void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE);
void markPartitionMove(LLDrawable* drawablep);
+ void markMeshDirty(LLSpatialGroup* group);
//get the object between start and end that's closest to start.
LLViewerObject* lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
@@ -293,10 +294,10 @@ public:
void setLight(LLDrawable *drawablep, BOOL is_light);
BOOL hasRenderBatches(const U32 type) const;
- LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type);
- LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type);
- LLCullResult::sg_list_t::iterator beginAlphaGroups();
- LLCullResult::sg_list_t::iterator endAlphaGroups();
+ LLCullResult::drawinfo_iterator beginRenderMap(U32 type);
+ LLCullResult::drawinfo_iterator endRenderMap(U32 type);
+ LLCullResult::sg_iterator beginAlphaGroups();
+ LLCullResult::sg_iterator endAlphaGroups();
void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);
@@ -543,6 +544,9 @@ public:
//utility buffer for rendering post effects, gets abused by renderDeferredLighting
LLPointer<LLVertexBuffer> mDeferredVB;
+ //utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
+ LLPointer<LLVertexBuffer> mCubeVB;
+
//sun shadow map
LLRenderTarget mShadow[6];
std::vector<LLVector3> mShadowFrustPoints[4];
@@ -594,6 +598,7 @@ public:
BOOL mVertexShadersEnabled;
S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed
+ U32 mTransformFeedbackPrimitives; //number of primitives expected to be generated by transform feedback
protected:
BOOL mRenderTypeEnabled[NUM_RENDER_TYPES];
std::stack<std::string> mRenderTypeEnableStack;
@@ -651,6 +656,9 @@ protected:
LLSpatialGroup::sg_vector_t mGroupQ1; //priority
LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority
+ LLSpatialGroup::sg_vector_t mMeshDirtyGroup; //groups that need rebuildMesh called
+ U32 mMeshDirtyQueryObject;
+
LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius
bool mGroupQ2Locked;
@@ -851,6 +859,7 @@ public:
static BOOL CameraOffset;
static F32 CameraMaxCoF;
static F32 CameraDoFResScale;
+ static F32 RenderAutoHideSurfaceAreaLimit;
};
void render_bbox(const LLVector3 &min, const LLVector3 &max);
diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index d011c7295c..c875b8c652 100644
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -21,7 +21,6 @@
<menu_item_call label="Beschäftigt" name="Set Busy"/>
</menu>
<menu_item_call label="L$ kaufen..." name="Buy and Sell L$"/>
- <menu_item_call label="Händler-Outbox..." name="MerchantOutbox"/>
<menu_item_call label="Kontoübersicht..." name="Manage My Account">
<menu_item_call.on_click name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/index.php?lang=de"/>
</menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml
index 66bb9d3cea..9deb0d2030 100644
--- a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml
@@ -132,6 +132,28 @@
name="vbo"
tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled."
width="315" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="tc label"
+ top_pad="10"
+ width="188">
+ Enable S3TC:
+ </text>
+ <check_box
+ control_name="RenderCompressTextures"
+ height="16"
+ initial_value="true"
+ label="Enable Texture Compression (requires restart)"
+ layout="topleft"
+ left_pad="10"
+ name="texture compression"
+ tool_tip="Compresses textures in video memory, allowing for higher resolution textures to be loaded at the cost of some color quality."
+ width="315" />
<slider
control_name="TextureMemory"
decimal_digits="0"
diff --git a/indra/newview/skins/default/xui/en/floater_my_inventory.xml b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
index 184f296255..ea44fd493e 100644
--- a/indra/newview/skins/default/xui/en/floater_my_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
@@ -6,7 +6,7 @@
height="570"
help_topic="sidebar_inventory"
min_width="333"
- min_height="440"
+ min_height="560"
name="floater_my_inventory"
save_rect="true"
save_visibility="true"
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index e6d749a3f0..9561f67941 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -155,6 +155,7 @@
name="object_name"
top_delta="0"
translate="false"
+ parse_urls="false"
use_ellipses="true"
width="185">
Consetetur Sadipscing
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index ffb8b842f0..2e29c61cb2 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -134,6 +134,26 @@
top_delta="-25"
name="Pipette"
width="28" />
+ <check_box
+ follows="left|bottom"
+ height="20"
+ initial_value="true"
+ label="Live Preview"
+ layout="topleft"
+ left="4"
+ name="apply_immediate_check"
+ top="262"
+ width="120" />
+ <text
+ follows="left|bottom"
+ height="20"
+ layout="topleft"
+ left="8"
+ name="preview_disabled"
+ top="266"
+ value="Preview Disabled"
+ visible="false"
+ width="120" />
<filter_editor
follows="left|top|right"
height="23"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index afc5b916e7..d956a7225d 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1245,6 +1245,25 @@ Visit [_URL] for more information?
<notification
icon="alertmodal.tga"
+ name="IntelOldDriver"
+ type="alertmodal">
+ There is likely a newer driver for your graphics chip. Updating graphics drivers can substantially improve performance.
+
+ Visit [_URL] to check for driver updates?
+ <tag>confirm</tag>
+ <url option="0" name="url">
+ http://www.intel.com/p/en_US/support/detect/graphics
+ </url>
+ <usetemplate
+ ignoretext="My graphics driver is out of date"
+ name="okcancelignore"
+ notext="No"
+ yestext="Yes"/>
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="UnknownGPU"
type="alertmodal">
Your system contains a graphics card that [APP_NAME] doesn't recognize.
@@ -7181,6 +7200,18 @@ You locally updated a [RESOLUTION] baked texture for '[BODYREGION]' after [TIME]
<notification
icon="alertmodal.tga"
+ name="LivePreviewUnavailable"
+ type="alert">
+
+We cannot display a preview of this texture because it is no-copy and/or no-transfer.
+ <usetemplate
+ ignoretext="Warn me that Live Preview mode is not available for no-copy and/or no-transfer textures"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="ConfirmLeaveCall"
type="alert">
Are you sure you want to leave this call?
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index 54a312bd59..c5dfb703e5 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -11,6 +11,10 @@
name="unknown">
(unknown)
</panel.string>
+ <panel.string
+ name="unknown_multiple">
+ (unknown / multiple)
+ </panel.string>
<panel.string
name="public">
(public)
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index 6600339ad7..bf2e6bc2d9 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -267,19 +267,19 @@
<combo_box.item
label="Touch (default)"
name="Touch/grab(default)"
- value="Touch/grab (default)" />
+ value="Touch" />
<combo_box.item
label="Sit on object"
name="Sitonobject"
- value="Sit on object" />
+ value="Sit" />
<combo_box.item
label="Buy object"
name="Buyobject"
- value="Buy object" />
+ value="Buy" />
<combo_box.item
label="Pay object"
name="Payobject"
- value="Pay object" />
+ value="Pay" />
<combo_box.item
label="Open"
name="Open"