Merge up from 24496 / a656486925e8 (FS tip) to 25952 / 931cb0061118 (V/Dev FUI tip)
Observations and broken stuff so far: - LLSideTray is gone. - LLBottomTray is gone. - LLFloaterSnapshot was changed and gave lots of merge conflicts. Flickr upload will be broken. - LLNearbyChat is derived from LLPanel now. That broke quite some stuff rearding autohiding and docking of chatbar. - Profile floaters are gone and all web based now. - Russian translation gave huge mere conflicts with the new russian xml files from LL. Unmergeable. I took the LL files. - XUI files in general will need some love and testing.master
commit
161c1b019f
|
|
@ -77,4 +77,5 @@ glob:indra/newview/search_history.txt
|
|||
glob:indra/newview/filters.xml
|
||||
glob:indra/newview/avatar_icons_cache.txt
|
||||
glob:indra/newview/avatar_lad.log
|
||||
glob:*.diff
|
||||
glob:fmod*
|
||||
|
|
|
|||
40
.hgtags
40
.hgtags
|
|
@ -1,3 +1,4 @@
|
|||
bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2.1.1-release
|
||||
003dd9461bfa479049afcc34545ab3431b147c7c v2start
|
||||
08398e650c222336bb2b6de0cd3bba944aef11b4 2-1rn1
|
||||
0962101bfa7df0643a6e625786025fe7f8a6dc97 2-1-beta-2
|
||||
|
|
@ -199,6 +200,45 @@ dbaaef19266478a20654c46395300640163e98e3 3.1.0-beta2
|
|||
bc01ee26fd0f1866e266429e85f76340523e91f1 3.1.0-beta2
|
||||
ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 DRTVWR-92_3.1.0-release
|
||||
ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 3.1.0-release
|
||||
a8230590e28e4f30f5105549e0e43211d9d55711 3.2.0-start
|
||||
e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
|
||||
e440cd1dfbd128d7d5467019e497f7f803640ad6 3.2.0-beta1
|
||||
9bcc2b7176634254e501e3fb4c5b56c1f637852e DRTVWR-97_3.2.0-beta2
|
||||
9bcc2b7176634254e501e3fb4c5b56c1f637852e 3.2.0-beta2
|
||||
2a13d30ee50ccfed50268238e36bb90d738ccc9e DRTVWR-98_3.2.0-beta3
|
||||
2a13d30ee50ccfed50268238e36bb90d738ccc9e 3.2.0-beta3
|
||||
3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
|
||||
3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
|
||||
c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
|
||||
3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
|
||||
3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
|
||||
40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
|
||||
3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
|
||||
3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
|
||||
9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
|
||||
9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
|
||||
523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
|
||||
523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
|
||||
80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
|
||||
a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
|
||||
a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
|
||||
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
|
||||
a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
|
||||
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
|
||||
a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
|
||||
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
|
||||
3fe994349fae64fc40874bb59db387131eb35a41 DRTVWR-104_3.2.4-beta1
|
||||
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
|
||||
8a44ff3d2104269ce76145c2772cf1bdff2a2abe 3.2.5-start
|
||||
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
|
||||
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
|
||||
bd6bcde2584491fd9228f1fa51c4575f4e764e19 DRTVWR-103_3.2.4-release
|
||||
bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
|
||||
3d2d5d244c6398a4214c666d5dd3965b0918709a DRTVWR-106_3.2.5-beta1
|
||||
3d2d5d244c6398a4214c666d5dd3965b0918709a 3.2.5-beta1
|
||||
65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d DRTVWR-107_3.2.5-beta2
|
||||
65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d 3.2.5-beta2
|
||||
2174ed1c7129562428a5cfe8651ed77b8d26ae18 3.2.6-start
|
||||
425f96b1e81e01644bf5e951961e7d1023bffb89 RLVa-1.2.0
|
||||
fc0cbb86f5bd6e7737159e35aea2c4cf9f619b62 RLVa-1.2.1
|
||||
43cb7dc1804de1a25c0b2b3f0715584af1f8b470 RLVa-1.2.2
|
||||
|
|
|
|||
41
BuildParams
41
BuildParams
|
|
@ -136,14 +136,6 @@ viewer-mesh.login_channel = "Project Viewer - Mesh"
|
|||
viewer-mesh.viewer_grid = aditi
|
||||
viewer-mesh.email = shining@lists.lindenlab.com
|
||||
|
||||
|
||||
# ========================================
|
||||
# CG
|
||||
# ========================================
|
||||
|
||||
cg_viewer-development_lenny.show_changes_since = 4b140ce7839d
|
||||
cg_viewer-development_lenny.email = cg@lindenlab.com
|
||||
|
||||
# ================
|
||||
# oz
|
||||
# ================
|
||||
|
|
@ -151,20 +143,31 @@ cg_viewer-development_lenny.email = cg@lindenlab.com
|
|||
oz_viewer-devreview.build_debug_release_separately = true
|
||||
oz_viewer-devreview.codeticket_add_context = false
|
||||
oz_viewer-devreview.build_enforce_coding_policy = true
|
||||
oz_viewer-devreview.email = oz@lindenlab.com
|
||||
|
||||
oz_project-1.build_debug_release_separately = true
|
||||
oz_project-1.codeticket_add_context = false
|
||||
oz_project-2.build_debug_release_separately = true
|
||||
oz_project-2.codeticket_add_context = false
|
||||
oz_project-3.build_debug_release_separately = true
|
||||
oz_project-3.codeticket_add_context = false
|
||||
oz_project-4.build_debug_release_separately = true
|
||||
oz_project-4.codeticket_add_context = false
|
||||
oz_viewer-trial.build_debug_release_separately = true
|
||||
oz_viewer-trial.codeticket_add_context = false
|
||||
oz_viewer-trial.build_enforce_coding_policy = true
|
||||
oz_viewer-trial.email = oz@lindenlab.com
|
||||
|
||||
oz_viewer-beta-review.build_debug_release_separately = true
|
||||
oz_viewer-beta-review.codeticket_add_context = false
|
||||
oz_viewer-beta-review.viewer_channel = "Second Life Beta Viewer"
|
||||
oz_viewer-beta-review.login_channel = "Second Life Beta Viewer"
|
||||
oz_viewer-beta-review.email = oz@lindenlab.com
|
||||
|
||||
oz_project-1.build_debug_release_separately = true
|
||||
oz_project-1.codeticket_add_context = false
|
||||
oz_project-1.email = oz@lindenlab.com
|
||||
oz_project-2.build_debug_release_separately = true
|
||||
oz_project-2.codeticket_add_context = false
|
||||
oz_project-2.email = oz@lindenlab.com
|
||||
oz_project-3.build_debug_release_separately = true
|
||||
oz_project-3.codeticket_add_context = false
|
||||
oz_project-3.email = oz@lindenlab.com
|
||||
oz_project-4.build_debug_release_separately = true
|
||||
oz_project-4.codeticket_add_context = false
|
||||
oz_project-4.email = oz@lindenlab.com
|
||||
|
||||
# =================================================================
|
||||
# asset delivery 2010 projects
|
||||
|
|
@ -190,4 +193,10 @@ simon_viewer-dev-private.public_build = false
|
|||
simon_viewer-dev-private.email_status_this_is_os = false
|
||||
|
||||
|
||||
# ========================================
|
||||
# Vir
|
||||
# ========================================
|
||||
vir-project-1.viewer_channel = "Second Life Release"
|
||||
vir-project-1.login_channel = "Second Life Release"
|
||||
|
||||
# eof
|
||||
|
|
|
|||
|
|
@ -1206,9 +1206,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>1b92a69f5eba7cd8b017180659076db5</string>
|
||||
<string>26aa7c367ffadd573f61a6a96f820f80</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/roxie_3p-llqtwebkit/rev/242182/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20111003.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/245988/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20111201.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin</string>
|
||||
|
|
@ -1230,9 +1230,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>1e7f24b69b0fc751c7e86efe7c621882</string>
|
||||
<string>270db8568a0c4bab266d98e1a820aec4</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/roxie_3p-llqtwebkit/rev/242182/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20111003.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/245988/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20111201.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ Ansariel Hiller
|
|||
STORM-1101
|
||||
VWR-25480
|
||||
VWR-26150
|
||||
STORM-1685
|
||||
STORM-1713
|
||||
Aralara Rajal
|
||||
Ardy Lay
|
||||
STORM-859
|
||||
|
|
@ -483,6 +485,7 @@ Ima Mechanique
|
|||
OPEN-76
|
||||
STORM-959
|
||||
STORM-1175
|
||||
STORM-1708
|
||||
Imnotgoing Sideways
|
||||
Inma Rau
|
||||
Innula Zenovka
|
||||
|
|
@ -578,9 +581,34 @@ Jonathan Yap
|
|||
STORM-1572
|
||||
STORM-1574
|
||||
STORM-1579
|
||||
STORM-1638
|
||||
STORM-976
|
||||
STORM-1639
|
||||
STORM-910
|
||||
STORM-1653
|
||||
STORM-1642
|
||||
STORM-591
|
||||
STORM-1105
|
||||
STORM-1679
|
||||
STORM-1222
|
||||
STORM-1659
|
||||
STORM-1674
|
||||
STORM-1685
|
||||
STORM-1721
|
||||
STORM-1727
|
||||
STORM-1725
|
||||
STORM-1719
|
||||
STORM-1712
|
||||
STORM-1728
|
||||
STORM-1736
|
||||
STORM-1734
|
||||
STORM-1731
|
||||
STORM-653
|
||||
STORM-1737
|
||||
STORM-1733
|
||||
STORM-1790
|
||||
Kadah Coba
|
||||
STORM-1060
|
||||
STORM-1060
|
||||
Jondan Lundquist
|
||||
Josef Munster
|
||||
Josette Windlow
|
||||
|
|
@ -913,6 +941,7 @@ Robin Cornelius
|
|||
SNOW-599
|
||||
SNOW-747
|
||||
STORM-422
|
||||
STORM-591
|
||||
STORM-960
|
||||
STORM-1019
|
||||
STORM-1095
|
||||
|
|
@ -1107,6 +1136,9 @@ Tofu Buzzard
|
|||
CTS-411
|
||||
STORM-546
|
||||
VWR-24509
|
||||
STORM-1684
|
||||
SH-2477
|
||||
STORM-1684
|
||||
Tony Kembia
|
||||
Torben Trautman
|
||||
TouchaHoney Perhaps
|
||||
|
|
@ -1140,6 +1172,7 @@ Vector Hastings
|
|||
VWR-8726
|
||||
Veritas Raymaker
|
||||
Vex Streeter
|
||||
STORM-1642
|
||||
Viaticus Speculaas
|
||||
Vick Forcella
|
||||
Villain Baroque
|
||||
|
|
@ -1225,6 +1258,7 @@ Zi Ree
|
|||
VWR-1140
|
||||
VWR-24017
|
||||
VWR-25588
|
||||
STORM-1790
|
||||
Zipherius Turas
|
||||
VWR-76
|
||||
VWR-77
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# -*- cmake -*-
|
||||
|
||||
# cmake_minimum_required should appear before any
|
||||
|
|
@ -70,6 +69,9 @@ if (VIEWER)
|
|||
add_subdirectory(${LIBS_OPEN_PREFIX}llxuixml)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
|
||||
|
||||
# Legacy C++ tests. Build always, run if LL_TESTS is true.
|
||||
add_subdirectory(${VIEWER_PREFIX}test)
|
||||
|
||||
# viewer media plugins
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ if (WINDOWS)
|
|||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP -D_SCL_SECURE_NO_WARNINGS=1"
|
||||
CACHE STRING "C++ compiler debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /Ob2 /Gm -D_SECURE_STL=0"
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /Ob0 -D_SECURE_STL=0"
|
||||
CACHE STRING "C++ compiler release-with-debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2 /Oi /Ot /GF /Gy /arch:SSE2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||
|
|
@ -64,7 +64,7 @@ if (WINDOWS)
|
|||
/D_UNICODE
|
||||
/GS
|
||||
/TP
|
||||
/W2
|
||||
/W3
|
||||
/c
|
||||
/Zc:forScope
|
||||
/nologo
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ endif (DARWIN)
|
|||
# Sort by high-level to low-level
|
||||
target_link_libraries(llui_libtest
|
||||
llui
|
||||
llinventory
|
||||
llmessage
|
||||
${LLRENDER_LIBRARIES}
|
||||
${LLIMAGE_LIBRARIES}
|
||||
|
|
|
|||
|
|
@ -133,6 +133,12 @@ bool LLCrashLoggerLinux::mainLoop()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool LLCrashLoggerLinux::cleanup()
|
||||
{
|
||||
commonCleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLCrashLoggerLinux::updateApplication(const std::string& message)
|
||||
{
|
||||
LLCrashLogger::updateApplication(message);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
virtual bool mainLoop();
|
||||
virtual void updateApplication(const std::string& = LLStringUtil::null);
|
||||
virtual void gatherPlatformSpecificFiles();
|
||||
virtual bool cleanup();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1269,6 +1269,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
|
|||
mSyncSlave(false),
|
||||
mQueueSounds(false),
|
||||
mPlayedOnce(false),
|
||||
mCorrupted(false),
|
||||
mType(type),
|
||||
mChannelp(NULL),
|
||||
mCurrentDatap(NULL),
|
||||
|
|
@ -1301,16 +1302,25 @@ void LLAudioSource::setChannel(LLAudioChannel *channelp)
|
|||
|
||||
void LLAudioSource::update()
|
||||
{
|
||||
if(mCorrupted)
|
||||
{
|
||||
return ; //no need to update
|
||||
}
|
||||
|
||||
if (!getCurrentBuffer())
|
||||
{
|
||||
if (getCurrentData())
|
||||
{
|
||||
// Hack - try and load the sound. Will do this as a callback
|
||||
// on decode later.
|
||||
if (getCurrentData()->load())
|
||||
if (getCurrentData()->load() && getCurrentData()->getBuffer())
|
||||
{
|
||||
play(getCurrentData()->getID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mCorrupted = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1426,6 +1436,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
|
|||
|
||||
bool LLAudioSource::isDone() const
|
||||
{
|
||||
if(mCorrupted)
|
||||
{
|
||||
return true ;
|
||||
}
|
||||
|
||||
const F32 MAX_AGE = 60.f;
|
||||
const F32 MAX_UNPLAYED_AGE = 15.f;
|
||||
const F32 MAX_MUTED_AGE = 11.f;
|
||||
|
|
@ -1741,7 +1756,7 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//return false when the audio file is corrupted.
|
||||
bool LLAudioData::load()
|
||||
{
|
||||
// For now, just assume we're going to use one buffer per audiodata.
|
||||
|
|
@ -1757,7 +1772,7 @@ bool LLAudioData::load()
|
|||
{
|
||||
// No free buffers, abort.
|
||||
llinfos << "Not able to allocate a new audio buffer, aborting." << llendl;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string uuid_str;
|
||||
|
|
|
|||
|
|
@ -334,6 +334,7 @@ protected:
|
|||
bool mSyncSlave;
|
||||
bool mQueueSounds;
|
||||
bool mPlayedOnce;
|
||||
bool mCorrupted;
|
||||
S32 mType;
|
||||
LLVector3d mPositionGlobal;
|
||||
LLVector3 mVelocity;
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@ LLAssetDictionary::LLAssetDictionary()
|
|||
|
||||
addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true));
|
||||
addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
|
||||
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
|
||||
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
|
||||
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
|
||||
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -108,9 +108,13 @@ public:
|
|||
|
||||
AT_LINK_FOLDER = 25,
|
||||
// Inventory folder link
|
||||
|
||||
AT_WIDGET = 40,
|
||||
// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
|
||||
|
||||
AT_MESH = 49,
|
||||
// Mesh data in our proprietary SLM format
|
||||
|
||||
// Mesh data in our proprietary SLM format
|
||||
|
||||
AT_COUNT = 50,
|
||||
|
||||
// +*********************************************************+
|
||||
|
|
|
|||
|
|
@ -620,6 +620,12 @@ namespace LLError
|
|||
s.defaultLevel = level;
|
||||
}
|
||||
|
||||
ELevel getDefaultLevel()
|
||||
{
|
||||
Settings& s = Settings::get();
|
||||
return s.defaultLevel;
|
||||
}
|
||||
|
||||
void setFunctionLevel(const std::string& function_name, ELevel level)
|
||||
{
|
||||
Globals& g = Globals::get();
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ namespace LLError
|
|||
|
||||
LL_COMMON_API void setPrintLocation(bool);
|
||||
LL_COMMON_API void setDefaultLevel(LLError::ELevel);
|
||||
LL_COMMON_API ELevel getDefaultLevel();
|
||||
LL_COMMON_API void setFunctionLevel(const std::string& function_name, LLError::ELevel);
|
||||
LL_COMMON_API void setClassLevel(const std::string& class_name, LLError::ELevel);
|
||||
LL_COMMON_API void setFileLevel(const std::string& file_name, LLError::ELevel);
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@
|
|||
|
||||
#pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class
|
||||
#pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class
|
||||
#pragma warning (disable : 4018) // '<' : signed/unsigned mismatch
|
||||
#endif // LL_MSVC
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Must turn on conditional declarations in header file so definitions end up
|
||||
// with proper linkage.
|
||||
#define LLSD_DEBUG_INFO
|
||||
#include "linden_common.h"
|
||||
#include "llsd.h"
|
||||
|
||||
|
|
@ -31,6 +34,7 @@
|
|||
#include "../llmath/llmath.h"
|
||||
#include "llformat.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "stringize.h"
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
#define NAME_UNNAMED_NAMESPACE
|
||||
|
|
@ -50,6 +54,18 @@ namespace
|
|||
using namespace LLSDUnnamedNamespace;
|
||||
#endif
|
||||
|
||||
namespace llsd
|
||||
{
|
||||
|
||||
// statics
|
||||
S32 sLLSDAllocationCount = 0;
|
||||
S32 sLLSDNetObjects = 0;
|
||||
|
||||
} // namespace llsd
|
||||
|
||||
#define ALLOC_LLSD_OBJECT { llsd::sLLSDNetObjects++; llsd::sLLSDAllocationCount++; }
|
||||
#define FREE_LLSD_OBJECT { llsd::sLLSDNetObjects--; }
|
||||
|
||||
class LLSD::Impl
|
||||
/**< This class is the abstract base class of the implementation of LLSD
|
||||
It provides the reference counting implementation, and the default
|
||||
|
|
@ -58,13 +74,10 @@ class LLSD::Impl
|
|||
|
||||
*/
|
||||
{
|
||||
private:
|
||||
U32 mUseCount;
|
||||
|
||||
protected:
|
||||
Impl();
|
||||
|
||||
enum StaticAllocationMarker { STATIC };
|
||||
enum StaticAllocationMarker { STATIC_USAGE_COUNT = 0xFFFFFFFF };
|
||||
Impl(StaticAllocationMarker);
|
||||
///< This constructor is used for static objects and causes the
|
||||
// suppresses adjusting the debugging counters when they are
|
||||
|
|
@ -72,8 +85,10 @@ protected:
|
|||
|
||||
virtual ~Impl();
|
||||
|
||||
bool shared() const { return mUseCount > 1; }
|
||||
bool shared() const { return (mUseCount > 1) && (mUseCount != STATIC_USAGE_COUNT); }
|
||||
|
||||
U32 mUseCount;
|
||||
|
||||
public:
|
||||
static void reset(Impl*& var, Impl* impl);
|
||||
///< safely set var to refer to the new impl (possibly shared)
|
||||
|
|
@ -128,6 +143,18 @@ public:
|
|||
virtual LLSD::array_const_iterator beginArray() const { return endArray(); }
|
||||
virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); }
|
||||
|
||||
virtual void dumpStats() const;
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
// Container subclasses contain LLSD objects, rather than directly
|
||||
// containing Impl objects. This helper forwards through LLSD.
|
||||
void calcStats(const LLSD& llsd, S32 type_counts[], S32 share_counts[]) const
|
||||
{
|
||||
safe(llsd.impl).calcStats(type_counts, share_counts);
|
||||
}
|
||||
|
||||
static const Impl& getImpl(const LLSD& llsd) { return safe(llsd.impl); }
|
||||
static Impl& getImpl(LLSD& llsd) { return safe(llsd.impl); }
|
||||
|
||||
static const LLSD& undef();
|
||||
|
||||
static U32 sAllocationCount;
|
||||
|
|
@ -360,6 +387,9 @@ namespace
|
|||
LLSD::map_iterator endMap() { return mData.end(); }
|
||||
virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
|
||||
virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
|
||||
|
||||
virtual void dumpStats() const;
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
};
|
||||
|
||||
ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
|
||||
|
|
@ -414,6 +444,34 @@ namespace
|
|||
return i->second;
|
||||
}
|
||||
|
||||
void ImplMap::dumpStats() const
|
||||
{
|
||||
std::cout << "Map size: " << mData.size() << std::endl;
|
||||
|
||||
std::cout << "LLSD Net Objects: " << llsd::sLLSDNetObjects << std::endl;
|
||||
std::cout << "LLSD allocations: " << llsd::sLLSDAllocationCount << std::endl;
|
||||
|
||||
std::cout << "LLSD::Impl Net Objects: " << sOutstandingCount << std::endl;
|
||||
std::cout << "LLSD::Impl allocations: " << sAllocationCount << std::endl;
|
||||
|
||||
Impl::dumpStats();
|
||||
}
|
||||
|
||||
void ImplMap::calcStats(S32 type_counts[], S32 share_counts[]) const
|
||||
{
|
||||
LLSD::map_const_iterator iter = beginMap();
|
||||
while (iter != endMap())
|
||||
{
|
||||
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
|
||||
Impl::calcStats((*iter).second, type_counts, share_counts);
|
||||
iter++;
|
||||
}
|
||||
|
||||
// Add in the values for this map
|
||||
Impl::calcStats(type_counts, share_counts);
|
||||
}
|
||||
|
||||
|
||||
class ImplArray : public LLSD::Impl
|
||||
{
|
||||
private:
|
||||
|
|
@ -449,6 +507,8 @@ namespace
|
|||
LLSD::array_iterator endArray() { return mData.end(); }
|
||||
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
|
||||
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
|
||||
|
||||
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
|
||||
};
|
||||
|
||||
ImplArray& ImplArray::makeArray(Impl*& var)
|
||||
|
|
@ -490,12 +550,13 @@ namespace
|
|||
|
||||
void ImplArray::insert(LLSD::Integer i, const LLSD& v)
|
||||
{
|
||||
if (i < 0) {
|
||||
if (i < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DataVector::size_type index = i;
|
||||
|
||||
if (index >= mData.size())
|
||||
if (index >= mData.size()) // tbd - sanity check limit for index ?
|
||||
{
|
||||
mData.resize(index + 1);
|
||||
}
|
||||
|
|
@ -543,6 +604,19 @@ namespace
|
|||
|
||||
return mData[index];
|
||||
}
|
||||
|
||||
void ImplArray::calcStats(S32 type_counts[], S32 share_counts[]) const
|
||||
{
|
||||
LLSD::array_const_iterator iter = beginArray();
|
||||
while (iter != endArray())
|
||||
{ // Add values for all items held in the array
|
||||
Impl::calcStats((*iter), type_counts, share_counts);
|
||||
iter++;
|
||||
}
|
||||
|
||||
// Add in the values for this array
|
||||
Impl::calcStats(type_counts, share_counts);
|
||||
}
|
||||
}
|
||||
|
||||
LLSD::Impl::Impl()
|
||||
|
|
@ -564,8 +638,11 @@ LLSD::Impl::~Impl()
|
|||
|
||||
void LLSD::Impl::reset(Impl*& var, Impl* impl)
|
||||
{
|
||||
if (impl) ++impl->mUseCount;
|
||||
if (var && --var->mUseCount == 0)
|
||||
if (impl && impl->mUseCount != STATIC_USAGE_COUNT)
|
||||
{
|
||||
++impl->mUseCount;
|
||||
}
|
||||
if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0)
|
||||
{
|
||||
delete var;
|
||||
}
|
||||
|
|
@ -574,13 +651,13 @@ void LLSD::Impl::reset(Impl*& var, Impl* impl)
|
|||
|
||||
LLSD::Impl& LLSD::Impl::safe(Impl* impl)
|
||||
{
|
||||
static Impl theUndefined(STATIC);
|
||||
static Impl theUndefined(STATIC_USAGE_COUNT);
|
||||
return impl ? *impl : theUndefined;
|
||||
}
|
||||
|
||||
const LLSD::Impl& LLSD::Impl::safe(const Impl* impl)
|
||||
{
|
||||
static Impl theUndefined(STATIC);
|
||||
static Impl theUndefined(STATIC_USAGE_COUNT);
|
||||
return impl ? *impl : theUndefined;
|
||||
}
|
||||
|
||||
|
|
@ -656,6 +733,43 @@ const LLSD& LLSD::Impl::undef()
|
|||
return immutableUndefined;
|
||||
}
|
||||
|
||||
void LLSD::Impl::dumpStats() const
|
||||
{
|
||||
S32 type_counts[LLSD::TypeLLSDNumTypes + 1];
|
||||
memset(&type_counts, 0, sizeof(type_counts));
|
||||
|
||||
S32 share_counts[LLSD::TypeLLSDNumTypes + 1];
|
||||
memset(&share_counts, 0, sizeof(share_counts));
|
||||
|
||||
// Add info from all the values this object has
|
||||
calcStats(type_counts, share_counts);
|
||||
|
||||
S32 type_index = LLSD::TypeLLSDTypeBegin;
|
||||
while (type_index != LLSD::TypeLLSDTypeEnd)
|
||||
{
|
||||
std::cout << LLSD::typeString((LLSD::Type)type_index) << " type "
|
||||
<< type_counts[type_index] << " objects, "
|
||||
<< share_counts[type_index] << " shared"
|
||||
<< std::endl;
|
||||
type_index++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const
|
||||
{
|
||||
S32 tp = S32(type());
|
||||
if (0 <= tp && tp < LLSD::TypeLLSDNumTypes)
|
||||
{
|
||||
type_counts[tp]++;
|
||||
if (shared())
|
||||
{
|
||||
share_counts[tp]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U32 LLSD::Impl::sAllocationCount = 0;
|
||||
U32 LLSD::Impl::sOutstandingCount = 0;
|
||||
|
||||
|
|
@ -681,10 +795,10 @@ namespace
|
|||
}
|
||||
|
||||
|
||||
LLSD::LLSD() : impl(0) { }
|
||||
LLSD::~LLSD() { Impl::reset(impl, 0); }
|
||||
LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; }
|
||||
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); }
|
||||
|
||||
LLSD::LLSD(const LLSD& other) : impl(0) { assign(other); }
|
||||
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
|
||||
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
|
||||
|
||||
|
||||
|
|
@ -692,18 +806,18 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
|
|||
|
||||
LLSD::Type LLSD::type() const { return safe(impl).type(); }
|
||||
|
||||
// Scaler Constructors
|
||||
LLSD::LLSD(Boolean v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(Integer v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(Real v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const UUID& v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const String& v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const Date& v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const URI& v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const Binary& v) : impl(0) { assign(v); }
|
||||
// Scalar Constructors
|
||||
LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
|
||||
// Convenience Constructors
|
||||
LLSD::LLSD(F32 v) : impl(0) { assign((Real)v); }
|
||||
LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); }
|
||||
|
||||
// Scalar Assignment
|
||||
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
|
||||
|
|
@ -726,7 +840,7 @@ LLSD::URI LLSD::asURI() const { return safe(impl).asURI(); }
|
|||
LLSD::Binary LLSD::asBinary() const { return safe(impl).asBinary(); }
|
||||
|
||||
// const char * helpers
|
||||
LLSD::LLSD(const char* v) : impl(0) { assign(v); }
|
||||
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
|
||||
void LLSD::assign(const char* v)
|
||||
{
|
||||
if(v) assign(std::string(v));
|
||||
|
|
@ -784,9 +898,6 @@ LLSD& LLSD::operator[](Integer i)
|
|||
const LLSD& LLSD::operator[](Integer i) const
|
||||
{ return safe(impl).ref(i); }
|
||||
|
||||
U32 LLSD::allocationCount() { return Impl::sAllocationCount; }
|
||||
U32 LLSD::outstandingCount() { return Impl::sOutstandingCount; }
|
||||
|
||||
static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
|
||||
{
|
||||
// sStorage is used to hold the string representation of the llsd last
|
||||
|
|
@ -801,15 +912,9 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
|
|||
{
|
||||
std::ostringstream out;
|
||||
if (useXMLFormat)
|
||||
{
|
||||
LLSDXMLStreamer xml_streamer(llsd);
|
||||
out << xml_streamer;
|
||||
}
|
||||
out << LLSDXMLStreamer(llsd);
|
||||
else
|
||||
{
|
||||
LLSDNotationStreamer notation_streamer(llsd);
|
||||
out << notation_streamer;
|
||||
}
|
||||
out << LLSDNotationStreamer(llsd);
|
||||
out_string = out.str();
|
||||
}
|
||||
int len = out_string.length();
|
||||
|
|
@ -840,3 +945,38 @@ LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray();
|
|||
LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); }
|
||||
LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); }
|
||||
LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); }
|
||||
|
||||
namespace llsd
|
||||
{
|
||||
|
||||
U32 allocationCount() { return LLSD::Impl::sAllocationCount; }
|
||||
U32 outstandingCount() { return LLSD::Impl::sOutstandingCount; }
|
||||
|
||||
// Diagnostic dump of contents in an LLSD object
|
||||
void dumpStats(const LLSD& llsd) { LLSD::Impl::getImpl(llsd).dumpStats(); }
|
||||
|
||||
} // namespace llsd
|
||||
|
||||
// static
|
||||
std::string LLSD::typeString(Type type)
|
||||
{
|
||||
static const char * sTypeNameArray[] = {
|
||||
"Undefined",
|
||||
"Boolean",
|
||||
"Integer",
|
||||
"Real",
|
||||
"String",
|
||||
"UUID",
|
||||
"Date",
|
||||
"URI",
|
||||
"Binary",
|
||||
"Map",
|
||||
"Array"
|
||||
};
|
||||
|
||||
if (0 <= type && type < LL_ARRAY_SIZE(sTypeNameArray))
|
||||
{
|
||||
return sTypeNameArray[type];
|
||||
}
|
||||
return STRINGIZE("** invalid type value " << type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,10 +40,10 @@
|
|||
/**
|
||||
LLSD provides a flexible data system similar to the data facilities of
|
||||
dynamic languages like Perl and Python. It is created to support exchange
|
||||
of structured data between loosly coupled systems. (Here, "loosly coupled"
|
||||
of structured data between loosely coupled systems. (Here, "loosely coupled"
|
||||
means not compiled together into the same module.)
|
||||
|
||||
Data in such exchanges must be highly tollerant of changes on either side
|
||||
Data in such exchanges must be highly tolerant of changes on either side
|
||||
such as:
|
||||
- recompilation
|
||||
- implementation in a different langauge
|
||||
|
|
@ -51,19 +51,19 @@
|
|||
- execution of older versions (with fewer parameters)
|
||||
|
||||
To this aim, the C++ API of LLSD strives to be very easy to use, and to
|
||||
default to "the right thing" whereever possible. It is extremely tollerant
|
||||
default to "the right thing" wherever possible. It is extremely tolerant
|
||||
of errors and unexpected situations.
|
||||
|
||||
The fundimental class is LLSD. LLSD is a value holding object. It holds
|
||||
The fundamental class is LLSD. LLSD is a value holding object. It holds
|
||||
one value that is either undefined, one of the scalar types, or a map or an
|
||||
array. LLSD objects have value semantics (copying them copies the value,
|
||||
though it can be considered efficient, due to shareing.), and mutable.
|
||||
though it can be considered efficient, due to sharing), and mutable.
|
||||
|
||||
Undefined is the singular value given to LLSD objects that are not
|
||||
initialized with any data. It is also used as the return value for
|
||||
operations that return an LLSD,
|
||||
operations that return an LLSD.
|
||||
|
||||
The sclar data types are:
|
||||
The scalar data types are:
|
||||
- Boolean - true or false
|
||||
- Integer - a 32 bit signed integer
|
||||
- Real - a 64 IEEE 754 floating point value
|
||||
|
|
@ -80,9 +80,73 @@
|
|||
|
||||
An array is a sequence of zero or more LLSD values.
|
||||
|
||||
Thread Safety
|
||||
|
||||
In general, these LLSD classes offer *less* safety than STL container
|
||||
classes. Implementations prior to this one were unsafe even when
|
||||
completely unrelated LLSD trees were in two threads due to reference
|
||||
sharing of special 'undefined' values that participated in the reference
|
||||
counting mechanism.
|
||||
|
||||
The dereference-before-refcount and aggressive tree sharing also make
|
||||
it impractical to share an LLSD across threads. A strategy of passing
|
||||
ownership or a copy to another thread is still difficult due to a lack
|
||||
of a cloning interface but it can be done with some care.
|
||||
|
||||
One way of transferring ownership is as follows:
|
||||
|
||||
void method(const LLSD input) {
|
||||
...
|
||||
LLSD * xfer_tree = new LLSD();
|
||||
{
|
||||
// Top-level values
|
||||
(* xfer_tree)['label'] = "Some text";
|
||||
(* xfer_tree)['mode'] = APP_MODE_CONSTANT;
|
||||
|
||||
// There will be a second-level
|
||||
LLSD subtree(LLSD::emptyMap());
|
||||
(* xfer_tree)['subtree'] = subtree;
|
||||
|
||||
// Do *not* copy from LLSD objects via LLSD
|
||||
// intermediaries. Only use plain-old-data
|
||||
// types as intermediaries to prevent reference
|
||||
// sharing.
|
||||
subtree['value1'] = input['value1'].asInteger();
|
||||
subtree['value2'] = input['value2'].asString();
|
||||
|
||||
// Close scope and drop 'subtree's reference.
|
||||
// Only xfer_tree has a reference to the second
|
||||
// level data.
|
||||
}
|
||||
...
|
||||
// Transfer the LLSD pointer to another thread. Ownership
|
||||
// transfers, this thread no longer has a reference to any
|
||||
// part of the xfer_tree and there's nothing to free or
|
||||
// release here. Receiving thread does need to delete the
|
||||
// pointer when it is done with the LLSD. Transfer
|
||||
// mechanism must perform correct data ordering operations
|
||||
// as dictated by architecture.
|
||||
other_thread.sendMessageAndPointer("Take This", xfer_tree);
|
||||
xfer_tree = NULL;
|
||||
|
||||
|
||||
Avoid this pattern which provides half of a race condition:
|
||||
|
||||
void method(const LLSD input) {
|
||||
...
|
||||
LLSD xfer_tree(LLSD::emptyMap());
|
||||
xfer_tree['label'] = "Some text";
|
||||
xfer_tree['mode'] = APP_MODE_CONSTANT;
|
||||
...
|
||||
other_thread.sendMessageAndPointer("Take This", xfer_tree);
|
||||
|
||||
|
||||
@nosubgrouping
|
||||
*/
|
||||
|
||||
// Normally undefined, used for diagnostics
|
||||
//#define LLSD_DEBUG_INFO 1
|
||||
|
||||
class LL_COMMON_API LLSD
|
||||
{
|
||||
public:
|
||||
|
|
@ -202,7 +266,7 @@ public:
|
|||
//@}
|
||||
|
||||
/** @name Character Pointer Helpers
|
||||
These are helper routines to make working with char* the same as easy as
|
||||
These are helper routines to make working with char* as easy as
|
||||
working with strings.
|
||||
*/
|
||||
//@{
|
||||
|
|
@ -266,7 +330,7 @@ public:
|
|||
/** @name Type Testing */
|
||||
//@{
|
||||
enum Type {
|
||||
TypeUndefined,
|
||||
TypeUndefined = 0,
|
||||
TypeBoolean,
|
||||
TypeInteger,
|
||||
TypeReal,
|
||||
|
|
@ -276,7 +340,10 @@ public:
|
|||
TypeURI,
|
||||
TypeBinary,
|
||||
TypeMap,
|
||||
TypeArray
|
||||
TypeArray,
|
||||
TypeLLSDTypeEnd,
|
||||
TypeLLSDTypeBegin = TypeUndefined,
|
||||
TypeLLSDNumTypes = (TypeLLSDTypeEnd - TypeLLSDTypeBegin)
|
||||
};
|
||||
|
||||
Type type() const;
|
||||
|
|
@ -302,7 +369,7 @@ public:
|
|||
If you get a linker error about these being missing, you have made
|
||||
mistake in your code. DO NOT IMPLEMENT THESE FUNCTIONS as a fix.
|
||||
|
||||
All of thse problems stem from trying to support char* in LLSD or in
|
||||
All of these problems stem from trying to support char* in LLSD or in
|
||||
std::string. There are too many automatic casts that will lead to
|
||||
using an arbitrary pointer or scalar type to std::string.
|
||||
*/
|
||||
|
|
@ -311,7 +378,7 @@ public:
|
|||
void assign(const void*); ///< assign from arbitrary pointers
|
||||
LLSD& operator=(const void*); ///< assign from arbitrary pointers
|
||||
|
||||
bool has(Integer) const; ///< has only works for Maps
|
||||
bool has(Integer) const; ///< has() only works for Maps
|
||||
//@}
|
||||
|
||||
/** @name Implementation */
|
||||
|
|
@ -320,13 +387,7 @@ public:
|
|||
class Impl;
|
||||
private:
|
||||
Impl* impl;
|
||||
//@}
|
||||
|
||||
/** @name Unit Testing Interface */
|
||||
//@{
|
||||
public:
|
||||
static U32 allocationCount(); ///< how many Impls have been made
|
||||
static U32 outstandingCount(); ///< how many Impls are still alive
|
||||
friend class LLSD::Impl;
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
|
@ -338,6 +399,10 @@ private:
|
|||
/// Returns Notation version of llsd -- only to be called from debugger
|
||||
static const char *dump(const LLSD &llsd);
|
||||
//@}
|
||||
|
||||
public:
|
||||
|
||||
static std::string typeString(Type type); // Return human-readable type as a string
|
||||
};
|
||||
|
||||
struct llsd_select_bool : public std::unary_function<LLSD, LLSD::Boolean>
|
||||
|
|
@ -385,9 +450,32 @@ struct llsd_select_string : public std::unary_function<LLSD, LLSD::String>
|
|||
|
||||
LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd);
|
||||
|
||||
namespace llsd
|
||||
{
|
||||
|
||||
#ifdef LLSD_DEBUG_INFO
|
||||
/** @name Unit Testing Interface */
|
||||
//@{
|
||||
LL_COMMON_API void dumpStats(const LLSD&); ///< Output information on object and usage
|
||||
|
||||
/// @warn THE FOLLOWING COUNTS WILL NOT BE ACCURATE IN A MULTI-THREADED
|
||||
/// ENVIRONMENT.
|
||||
///
|
||||
/// These counts track LLSD::Impl (hidden) objects.
|
||||
LL_COMMON_API U32 allocationCount(); ///< how many Impls have been made
|
||||
LL_COMMON_API U32 outstandingCount(); ///< how many Impls are still alive
|
||||
|
||||
/// These counts track LLSD (public) objects.
|
||||
LL_COMMON_API extern S32 sLLSDAllocationCount; ///< Number of LLSD objects ever created
|
||||
LL_COMMON_API extern S32 sLLSDNetObjects; ///< Number of LLSD objects that exist
|
||||
#endif
|
||||
//@}
|
||||
|
||||
} // namespace llsd
|
||||
|
||||
/** QUESTIONS & TO DOS
|
||||
- Would Binary be more convenient as usigned char* buffer semantics?
|
||||
- Should Binary be convertable to/from String, and if so how?
|
||||
- Would Binary be more convenient as unsigned char* buffer semantics?
|
||||
- Should Binary be convertible to/from String, and if so how?
|
||||
- as UTF8 encoded strings (making not like UUID<->String)
|
||||
- as Base64 or Base96 encoded (making like UUID<->String)
|
||||
- Conversions to std::string and LLUUID do not result in easy assignment
|
||||
|
|
|
|||
|
|
@ -611,6 +611,7 @@ LLCPUInfo::LLCPUInfo()
|
|||
out << " (" << mCPUMHz << " MHz)";
|
||||
}
|
||||
mCPUString = out.str();
|
||||
LLStringUtil::trim(mCPUString);
|
||||
}
|
||||
|
||||
bool LLCPUInfo::hasAltivec() const
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
const S32 LL_VERSION_MAJOR = 3;
|
||||
const S32 LL_VERSION_MINOR = 2;
|
||||
const S32 LL_VERSION_PATCH = 1;
|
||||
const S32 LL_VERSION_PATCH = 7;
|
||||
const S32 LL_VERSION_BUILD = 0;
|
||||
|
||||
const char * const LL_CHANNEL = "Firestorm-private";
|
||||
|
|
|
|||
|
|
@ -49,8 +49,9 @@ enum EDragAndDropType
|
|||
DAD_ANIMATION = 12,
|
||||
DAD_GESTURE = 13,
|
||||
DAD_LINK = 14,
|
||||
DAD_MESH = 15,
|
||||
DAD_COUNT = 16, // number of types in this enum
|
||||
DAD_MESH = 15,
|
||||
DAD_WIDGET = 16,
|
||||
DAD_COUNT = 17, // number of types in this enum
|
||||
};
|
||||
|
||||
// Reasons for drags to be denied.
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "llpumpio.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llproxy.h"
|
||||
|
||||
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
|
||||
#ifdef LL_WINDOWS
|
||||
|
|
@ -596,3 +597,9 @@ bool LLCrashLogger::init()
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
// For cleanup code common to all platforms.
|
||||
void LLCrashLogger::commonCleanup()
|
||||
{
|
||||
LLProxy::cleanupClass();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ public:
|
|||
virtual void updateApplication(const std::string& message = LLStringUtil::null);
|
||||
virtual bool init();
|
||||
virtual bool mainLoop() = 0;
|
||||
virtual bool cleanup() { return true; }
|
||||
virtual bool cleanup() = 0;
|
||||
void commonCleanup();
|
||||
void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; }
|
||||
S32 getCrashBehavior() { return mCrashBehavior; }
|
||||
bool runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,31 @@ LLGlobalEconomy::LLGlobalEconomy()
|
|||
LLGlobalEconomy::~LLGlobalEconomy()
|
||||
{ }
|
||||
|
||||
void LLGlobalEconomy::addObserver(LLEconomyObserver* observer)
|
||||
{
|
||||
mObservers.push_back(observer);
|
||||
}
|
||||
|
||||
void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer)
|
||||
{
|
||||
std::list<LLEconomyObserver*>::iterator it =
|
||||
std::find(mObservers.begin(), mObservers.end(), observer);
|
||||
if (it != mObservers.end())
|
||||
{
|
||||
mObservers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGlobalEconomy::notifyObservers()
|
||||
{
|
||||
for (std::list<LLEconomyObserver*>::iterator it = mObservers.begin();
|
||||
it != mObservers.end();
|
||||
++it)
|
||||
{
|
||||
(*it)->onEconomyDataChange();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data)
|
||||
{
|
||||
|
|
@ -88,6 +113,8 @@ void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy*
|
|||
econ_data->setTeleportPriceExponent(f);
|
||||
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceGroupCreate, i);
|
||||
econ_data->setPriceGroupCreate(i);
|
||||
|
||||
econ_data->notifyObservers();
|
||||
}
|
||||
|
||||
S32 LLGlobalEconomy::calculateTeleportCost(F32 distance) const
|
||||
|
|
|
|||
|
|
@ -31,6 +31,16 @@
|
|||
class LLMessageSystem;
|
||||
class LLVector3;
|
||||
|
||||
/**
|
||||
* Register an observer to be notified of economy data updates coming from server.
|
||||
*/
|
||||
class LLEconomyObserver
|
||||
{
|
||||
public:
|
||||
virtual ~LLEconomyObserver() {}
|
||||
virtual void onEconomyDataChange() = 0;
|
||||
};
|
||||
|
||||
class LLGlobalEconomy
|
||||
{
|
||||
public:
|
||||
|
|
@ -46,6 +56,10 @@ public:
|
|||
|
||||
virtual void print();
|
||||
|
||||
void addObserver(LLEconomyObserver* observer);
|
||||
void removeObserver(LLEconomyObserver* observer);
|
||||
void notifyObservers();
|
||||
|
||||
static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data);
|
||||
|
||||
S32 calculateTeleportCost(F32 distance) const;
|
||||
|
|
@ -89,6 +103,8 @@ private:
|
|||
S32 mTeleportMinPrice;
|
||||
F32 mTeleportPriceExponent;
|
||||
S32 mPriceGroupCreate;
|
||||
|
||||
std::list<LLEconomyObserver*> mObservers;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ LLInventoryDictionary::LLInventoryDictionary()
|
|||
addEntry(LLInventoryType::IT_ANIMATION, new InventoryEntry("animation", "animation", 1, LLAssetType::AT_ANIMATION));
|
||||
addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE));
|
||||
addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH));
|
||||
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -134,7 +135,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
|
|||
LLInventoryType::IT_NONE, // 37 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 38 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 39 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 40 AT_NONE
|
||||
LLInventoryType::IT_WIDGET, // 40 AT_WIDGET
|
||||
LLInventoryType::IT_NONE, // 41 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 42 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 43 AT_NONE
|
||||
|
|
@ -143,7 +144,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
|
|||
LLInventoryType::IT_NONE, // 46 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 47 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 48 AT_NONE
|
||||
LLInventoryType::IT_MESH // 49 AT_MESH
|
||||
LLInventoryType::IT_MESH, // 49 AT_MESH
|
||||
};
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -62,7 +62,8 @@ public:
|
|||
IT_ANIMATION = 19,
|
||||
IT_GESTURE = 20,
|
||||
IT_MESH = 22,
|
||||
IT_COUNT = 23,
|
||||
IT_WIDGET = 23,
|
||||
IT_COUNT = 24,
|
||||
|
||||
IT_NONE = -1
|
||||
};
|
||||
|
|
|
|||
|
|
@ -75,10 +75,6 @@ set(llmath_HEADER_FILES
|
|||
llvector4a.h
|
||||
llvector4a.inl
|
||||
llvector4logical.h
|
||||
llv4math.h
|
||||
llv4matrix3.h
|
||||
llv4matrix4.h
|
||||
llv4vector3.h
|
||||
llvolume.h
|
||||
llvolumemgr.h
|
||||
llvolumeoctree.h
|
||||
|
|
|
|||
|
|
@ -685,7 +685,7 @@ public:
|
|||
|
||||
if (lt != 0x7)
|
||||
{
|
||||
OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl;
|
||||
//OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,141 +0,0 @@
|
|||
/**
|
||||
* @file llv4math.h
|
||||
* @brief LLV4* class header file - vector processor enabled math
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLV4MATH_H
|
||||
#define LL_LLV4MATH_H
|
||||
|
||||
// *NOTE: We do not support SSE acceleration on Windows builds.
|
||||
// Our minimum specification for the viewer includes 1 GHz Athlon processors,
|
||||
// which covers the Athlon Thunderbird series that does not support SSE.
|
||||
//
|
||||
// Our header files include statements like this
|
||||
// const F32 HAVOK_TIMESTEP = 1.f / 45.f;
|
||||
// This creates "globals" that are included in each .obj file. If a single
|
||||
// .cpp file has SSE code generation turned on (eg, llviewerjointmesh_sse.cpp)
|
||||
// these globals will be initialized using SSE instructions. This causes SL
|
||||
// to crash before main() on processors without SSE. Untangling all these
|
||||
// headers/variables is too much work for the small performance gains of
|
||||
// vectorization.
|
||||
//
|
||||
// Therefore we only support vectorization on builds where the everything is
|
||||
// built with SSE or Altivec. See https://jira.secondlife.com/browse/VWR-1610
|
||||
// and https://jira.lindenlab.com/browse/SL-47720 for details.
|
||||
//
|
||||
// Sorry the code is such a mess. JC
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4MATH - GNUC
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if LL_GNUC && __GNUC__ >= 4 && __SSE__
|
||||
|
||||
#define LL_VECTORIZE 1
|
||||
|
||||
#if LL_DARWIN
|
||||
|
||||
#include <Accelerate/Accelerate.h>
|
||||
#include <xmmintrin.h>
|
||||
typedef vFloat V4F32;
|
||||
|
||||
#else
|
||||
|
||||
#include <xmmintrin.h>
|
||||
typedef float V4F32 __attribute__((vector_size(16)));
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#if LL_GNUC
|
||||
|
||||
#define LL_LLV4MATH_ALIGN_PREFIX
|
||||
#define LL_LLV4MATH_ALIGN_POSTFIX __attribute__((aligned(16)))
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4MATH - MSVC
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Only vectorize if the entire Windows build uses SSE.
|
||||
// _M_IX86_FP is set when SSE code generation is turned on, and I have
|
||||
// confirmed this in VS2003, VS2003 SP1, and VS2005. JC
|
||||
#if LL_MSVC && _M_IX86_FP
|
||||
|
||||
#define LL_VECTORIZE 1
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
typedef __m128 V4F32;
|
||||
|
||||
#endif
|
||||
#if LL_MSVC
|
||||
|
||||
#define LL_LLV4MATH_ALIGN_PREFIX __declspec(align(16))
|
||||
#define LL_LLV4MATH_ALIGN_POSTFIX
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4MATH - default - no vectorization
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if !LL_VECTORIZE
|
||||
|
||||
#define LL_VECTORIZE 0
|
||||
|
||||
struct V4F32 { F32 __pad__[4]; };
|
||||
|
||||
inline F32 llv4lerp(F32 a, F32 b, F32 w) { return ( b - a ) * w + a; }
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef LL_LLV4MATH_ALIGN_PREFIX
|
||||
# define LL_LLV4MATH_ALIGN_PREFIX
|
||||
#endif
|
||||
#ifndef LL_LLV4MATH_ALIGN_POSTFIX
|
||||
# define LL_LLV4MATH_ALIGN_POSTFIX
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4MATH
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#define LLV4_NUM_AXIS 4
|
||||
|
||||
class LLV4Vector3;
|
||||
class LLV4Matrix3;
|
||||
class LLV4Matrix4;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
/**
|
||||
* @file llviewerjointmesh.cpp
|
||||
* @brief LLV4* class header file - vector processor enabled math
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLV4MATRIX3_H
|
||||
#define LL_LLV4MATRIX3_H
|
||||
|
||||
#include "llv4math.h"
|
||||
#include "llv4vector3.h"
|
||||
#include "m3math.h" // for operator LLMatrix3()
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Matrix3
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LL_LLV4MATH_ALIGN_PREFIX
|
||||
|
||||
class LLV4Matrix3
|
||||
{
|
||||
public:
|
||||
union {
|
||||
F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
|
||||
V4F32 mV[LLV4_NUM_AXIS];
|
||||
};
|
||||
|
||||
void lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w);
|
||||
void multiply(const LLVector3 &a, LLVector3& out) const;
|
||||
void multiply(const LLVector4 &a, LLV4Vector3& out) const;
|
||||
void multiply(const LLVector3 &a, LLV4Vector3& out) const;
|
||||
|
||||
const LLV4Matrix3& transpose();
|
||||
const LLV4Matrix3& operator=(const LLMatrix3& a);
|
||||
|
||||
operator LLMatrix3() const { return (reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0])))->getMat3(); }
|
||||
|
||||
friend LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b);
|
||||
}
|
||||
|
||||
LL_LLV4MATH_ALIGN_POSTFIX;
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Matrix3 - SSE
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if LL_VECTORIZE
|
||||
|
||||
inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
|
||||
{
|
||||
__m128 vw = _mm_set1_ps(w);
|
||||
mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
|
||||
mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
|
||||
mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
|
||||
{
|
||||
LLV4Vector3 j;
|
||||
j.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
|
||||
j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
|
||||
j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
|
||||
o.setVec(j.mV);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
|
||||
{
|
||||
o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
|
||||
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
|
||||
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
|
||||
}
|
||||
|
||||
inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
|
||||
{
|
||||
o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
|
||||
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
|
||||
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Matrix3
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#else
|
||||
|
||||
inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
|
||||
{
|
||||
mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
|
||||
mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
|
||||
mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
|
||||
|
||||
mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
|
||||
mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
|
||||
mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
|
||||
|
||||
mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
|
||||
mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
|
||||
mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
|
||||
{
|
||||
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
|
||||
a.mV[VY] * mMatrix[VY][VX] +
|
||||
a.mV[VZ] * mMatrix[VZ][VX],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VY] +
|
||||
a.mV[VY] * mMatrix[VY][VY] +
|
||||
a.mV[VZ] * mMatrix[VZ][VY],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VZ] +
|
||||
a.mV[VY] * mMatrix[VY][VZ] +
|
||||
a.mV[VZ] * mMatrix[VZ][VZ]);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
|
||||
{
|
||||
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
|
||||
a.mV[VY] * mMatrix[VY][VX] +
|
||||
a.mV[VZ] * mMatrix[VZ][VX],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VY] +
|
||||
a.mV[VY] * mMatrix[VY][VY] +
|
||||
a.mV[VZ] * mMatrix[VZ][VY],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VZ] +
|
||||
a.mV[VY] * mMatrix[VY][VZ] +
|
||||
a.mV[VZ] * mMatrix[VZ][VZ]);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
|
||||
{
|
||||
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
|
||||
a.mV[VY] * mMatrix[VY][VX] +
|
||||
a.mV[VZ] * mMatrix[VZ][VX],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VY] +
|
||||
a.mV[VY] * mMatrix[VY][VY] +
|
||||
a.mV[VZ] * mMatrix[VZ][VY],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VZ] +
|
||||
a.mV[VY] * mMatrix[VY][VZ] +
|
||||
a.mV[VZ] * mMatrix[VZ][VZ]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Matrix3
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
||||
inline const LLV4Matrix3& LLV4Matrix3::transpose()
|
||||
{
|
||||
#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
|
||||
_MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
|
||||
return *this;
|
||||
#else
|
||||
F32 temp;
|
||||
temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
|
||||
temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
|
||||
temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const LLV4Matrix3& LLV4Matrix3::operator=(const LLMatrix3& a)
|
||||
{
|
||||
memcpy(mMatrix[VX], a.mMatrix[VX], sizeof(F32) * 3 );
|
||||
memcpy(mMatrix[VY], a.mMatrix[VY], sizeof(F32) * 3 );
|
||||
memcpy(mMatrix[VZ], a.mMatrix[VZ], sizeof(F32) * 3 );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b)
|
||||
{
|
||||
return LLVector3(
|
||||
a.mV[VX] * b.mMatrix[VX][VX] +
|
||||
a.mV[VY] * b.mMatrix[VY][VX] +
|
||||
a.mV[VZ] * b.mMatrix[VZ][VX],
|
||||
|
||||
a.mV[VX] * b.mMatrix[VX][VY] +
|
||||
a.mV[VY] * b.mMatrix[VY][VY] +
|
||||
a.mV[VZ] * b.mMatrix[VZ][VY],
|
||||
|
||||
a.mV[VX] * b.mMatrix[VX][VZ] +
|
||||
a.mV[VY] * b.mMatrix[VY][VZ] +
|
||||
a.mV[VZ] * b.mMatrix[VZ][VZ] );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,249 +0,0 @@
|
|||
/**
|
||||
* @file llviewerjointmesh.cpp
|
||||
* @brief LLV4* class header file - vector processor enabled math
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLV4MATRIX4_H
|
||||
#define LL_LLV4MATRIX4_H
|
||||
|
||||
#include "llv4math.h"
|
||||
#include "llv4matrix3.h" // just for operator LLV4Matrix3()
|
||||
#include "llv4vector3.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Matrix4
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LL_LLV4MATH_ALIGN_PREFIX
|
||||
|
||||
class LLV4Matrix4
|
||||
{
|
||||
public:
|
||||
union {
|
||||
F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
|
||||
V4F32 mV[LLV4_NUM_AXIS];
|
||||
};
|
||||
|
||||
void lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w);
|
||||
void multiply(const LLVector3 &a, LLVector3& o) const;
|
||||
void multiply(const LLVector3 &a, LLV4Vector3& o) const;
|
||||
|
||||
const LLV4Matrix4& transpose();
|
||||
const LLV4Matrix4& translate(const LLVector3 &vec);
|
||||
const LLV4Matrix4& translate(const LLV4Vector3 &vec);
|
||||
const LLV4Matrix4& operator=(const LLMatrix4& a);
|
||||
|
||||
operator LLMatrix4() const { return *(reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0]))); }
|
||||
operator LLV4Matrix3() const { return *(reinterpret_cast<const LLV4Matrix3*>(const_cast<const F32*>(&mMatrix[0][0]))); }
|
||||
|
||||
friend LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b);
|
||||
}
|
||||
|
||||
LL_LLV4MATH_ALIGN_POSTFIX;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Matrix4 - SSE
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if LL_VECTORIZE
|
||||
|
||||
inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
|
||||
{
|
||||
__m128 vw = _mm_set1_ps(w);
|
||||
mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
|
||||
mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
|
||||
mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
|
||||
mV[VW] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VW], a.mV[VW]), vw), a.mV[VW]);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
|
||||
{
|
||||
LLV4Vector3 j;
|
||||
j.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
|
||||
j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
|
||||
j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
|
||||
o.setVec(j.mV);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
|
||||
{
|
||||
o.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
|
||||
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
|
||||
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
|
||||
}
|
||||
|
||||
inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
|
||||
{
|
||||
mV[VW] = _mm_add_ps(mV[VW], vec.v);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Matrix4
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#else
|
||||
|
||||
inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
|
||||
{
|
||||
mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
|
||||
mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
|
||||
mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
|
||||
|
||||
mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
|
||||
mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
|
||||
mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
|
||||
|
||||
mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
|
||||
mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
|
||||
mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
|
||||
|
||||
mMatrix[VW][VX] = llv4lerp(a.mMatrix[VW][VX], b.mMatrix[VW][VX], w);
|
||||
mMatrix[VW][VY] = llv4lerp(a.mMatrix[VW][VY], b.mMatrix[VW][VY], w);
|
||||
mMatrix[VW][VZ] = llv4lerp(a.mMatrix[VW][VZ], b.mMatrix[VW][VZ], w);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
|
||||
{
|
||||
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
|
||||
a.mV[VY] * mMatrix[VY][VX] +
|
||||
a.mV[VZ] * mMatrix[VZ][VX] +
|
||||
mMatrix[VW][VX],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VY] +
|
||||
a.mV[VY] * mMatrix[VY][VY] +
|
||||
a.mV[VZ] * mMatrix[VZ][VY] +
|
||||
mMatrix[VW][VY],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VZ] +
|
||||
a.mV[VY] * mMatrix[VY][VZ] +
|
||||
a.mV[VZ] * mMatrix[VZ][VZ] +
|
||||
mMatrix[VW][VZ]);
|
||||
}
|
||||
|
||||
inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
|
||||
{
|
||||
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
|
||||
a.mV[VY] * mMatrix[VY][VX] +
|
||||
a.mV[VZ] * mMatrix[VZ][VX] +
|
||||
mMatrix[VW][VX],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VY] +
|
||||
a.mV[VY] * mMatrix[VY][VY] +
|
||||
a.mV[VZ] * mMatrix[VZ][VY] +
|
||||
mMatrix[VW][VY],
|
||||
|
||||
a.mV[VX] * mMatrix[VX][VZ] +
|
||||
a.mV[VY] * mMatrix[VY][VZ] +
|
||||
a.mV[VZ] * mMatrix[VZ][VZ] +
|
||||
mMatrix[VW][VZ]);
|
||||
}
|
||||
|
||||
inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
|
||||
{
|
||||
mMatrix[3][0] += vec.mV[0];
|
||||
mMatrix[3][1] += vec.mV[1];
|
||||
mMatrix[3][2] += vec.mV[2];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Matrix4
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
||||
inline const LLV4Matrix4& LLV4Matrix4::operator=(const LLMatrix4& a)
|
||||
{
|
||||
memcpy(mMatrix, a.mMatrix, sizeof(F32) * 16 );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const LLV4Matrix4& LLV4Matrix4::transpose()
|
||||
{
|
||||
#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
|
||||
_MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
|
||||
#else
|
||||
LLV4Matrix4 mat;
|
||||
mat.mMatrix[0][0] = mMatrix[0][0];
|
||||
mat.mMatrix[1][0] = mMatrix[0][1];
|
||||
mat.mMatrix[2][0] = mMatrix[0][2];
|
||||
mat.mMatrix[3][0] = mMatrix[0][3];
|
||||
|
||||
mat.mMatrix[0][1] = mMatrix[1][0];
|
||||
mat.mMatrix[1][1] = mMatrix[1][1];
|
||||
mat.mMatrix[2][1] = mMatrix[1][2];
|
||||
mat.mMatrix[3][1] = mMatrix[1][3];
|
||||
|
||||
mat.mMatrix[0][2] = mMatrix[2][0];
|
||||
mat.mMatrix[1][2] = mMatrix[2][1];
|
||||
mat.mMatrix[2][2] = mMatrix[2][2];
|
||||
mat.mMatrix[3][2] = mMatrix[2][3];
|
||||
|
||||
mat.mMatrix[0][3] = mMatrix[3][0];
|
||||
mat.mMatrix[1][3] = mMatrix[3][1];
|
||||
mat.mMatrix[2][3] = mMatrix[3][2];
|
||||
mat.mMatrix[3][3] = mMatrix[3][3];
|
||||
|
||||
*this = mat;
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const LLV4Matrix4& LLV4Matrix4::translate(const LLVector3 &vec)
|
||||
{
|
||||
mMatrix[3][0] += vec.mV[0];
|
||||
mMatrix[3][1] += vec.mV[1];
|
||||
mMatrix[3][2] += vec.mV[2];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b)
|
||||
{
|
||||
return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] +
|
||||
a.mV[VY] * b.mMatrix[VY][VX] +
|
||||
a.mV[VZ] * b.mMatrix[VZ][VX] +
|
||||
b.mMatrix[VW][VX],
|
||||
|
||||
a.mV[VX] * b.mMatrix[VX][VY] +
|
||||
a.mV[VY] * b.mMatrix[VY][VY] +
|
||||
a.mV[VZ] * b.mMatrix[VZ][VY] +
|
||||
b.mMatrix[VW][VY],
|
||||
|
||||
a.mV[VX] * b.mMatrix[VX][VZ] +
|
||||
a.mV[VY] * b.mMatrix[VY][VZ] +
|
||||
a.mV[VZ] * b.mMatrix[VZ][VZ] +
|
||||
b.mMatrix[VW][VZ]);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/**
|
||||
* @file llviewerjointmesh.cpp
|
||||
* @brief LLV4* class header file - vector processor enabled math
|
||||
*
|
||||
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLV4VECTOR3_H
|
||||
#define LL_LLV4VECTOR3_H
|
||||
|
||||
#include "llv4math.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Vector3
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LL_LLV4MATH_ALIGN_PREFIX
|
||||
|
||||
class LLV4Vector3
|
||||
{
|
||||
public:
|
||||
union {
|
||||
F32 mV[LLV4_NUM_AXIS];
|
||||
V4F32 v;
|
||||
};
|
||||
|
||||
enum {
|
||||
ALIGNMENT = 16
|
||||
};
|
||||
|
||||
void setVec(F32 x, F32 y, F32 z);
|
||||
void setVec(F32 a);
|
||||
}
|
||||
|
||||
LL_LLV4MATH_ALIGN_POSTFIX;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLV4Vector3
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void LLV4Vector3::setVec(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
}
|
||||
|
||||
inline void LLV4Vector3::setVec(F32 a)
|
||||
{
|
||||
#if LL_VECTORIZE
|
||||
v = _mm_set1_ps(a);
|
||||
#else
|
||||
setVec(a, a, a);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -4313,15 +4313,25 @@ S32 LLVolume::getNumTriangleIndices() const
|
|||
}
|
||||
|
||||
|
||||
S32 LLVolume::getNumTriangles() const
|
||||
S32 LLVolume::getNumTriangles(S32* vcount) const
|
||||
{
|
||||
U32 triangle_count = 0;
|
||||
U32 vertex_count = 0;
|
||||
|
||||
for (S32 i = 0; i < getNumVolumeFaces(); ++i)
|
||||
{
|
||||
triangle_count += getVolumeFace(i).mNumIndices/3;
|
||||
const LLVolumeFace& face = getVolumeFace(i);
|
||||
triangle_count += face.mNumIndices/3;
|
||||
|
||||
vertex_count += face.mNumVertices;
|
||||
}
|
||||
|
||||
|
||||
if (vcount)
|
||||
{
|
||||
*vcount = vertex_count;
|
||||
}
|
||||
|
||||
return triangle_count;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -993,7 +993,7 @@ public:
|
|||
S32 getNumTriangleIndices() const;
|
||||
static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
|
||||
|
||||
S32 getNumTriangles() const;
|
||||
S32 getNumTriangles(S32* vcount = NULL) const;
|
||||
|
||||
void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
|
||||
std::vector<LLVector3> &normals,
|
||||
|
|
|
|||
|
|
@ -592,7 +592,6 @@ void LLCurl::Multi::cleanup()
|
|||
{
|
||||
return ; //nothing to clean.
|
||||
}
|
||||
|
||||
// Clean up active
|
||||
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
|
||||
iter != mEasyActiveList.end(); ++iter)
|
||||
|
|
|
|||
|
|
@ -291,9 +291,10 @@ S32 getElementSize(const LLSD& llsd)
|
|||
case LLSD::TypeMap:
|
||||
case LLSD::TypeArray:
|
||||
case LLSD::TypeUndefined:
|
||||
default: // TypeLLSDTypeEnd, TypeLLSDNumTypes, etc.
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
//return 0;
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
|
|||
|
|
@ -1239,6 +1239,14 @@ void LLPluginClassMedia::focus(bool focused)
|
|||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::set_page_zoom_factor( double factor )
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_page_zoom_factor");
|
||||
|
||||
message.setValueReal("factor", factor);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::clear_cache()
|
||||
{
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cache");
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
|
|||
LOG_CLASS(LLPluginClassMedia);
|
||||
public:
|
||||
LLPluginClassMedia(LLPluginClassMediaOwner *owner);
|
||||
~LLPluginClassMedia();
|
||||
virtual ~LLPluginClassMedia();
|
||||
|
||||
// local initialization, called by the media manager when creating a source
|
||||
bool init(const std::string &launcher_filename,
|
||||
|
|
@ -202,6 +202,7 @@ public:
|
|||
bool pluginSupportsMediaBrowser(void);
|
||||
|
||||
void focus(bool focused);
|
||||
void set_page_zoom_factor( double factor );
|
||||
void clear_cache();
|
||||
void clear_cookies();
|
||||
void set_cookies(const std::string &cookies);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
class LLPluginInstanceMessageListener
|
||||
{
|
||||
public:
|
||||
~LLPluginInstanceMessageListener();
|
||||
virtual ~LLPluginInstanceMessageListener();
|
||||
/** Plugin receives message from plugin loader shell. */
|
||||
virtual void receivePluginMessage(const std::string &message) = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
|
|||
LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
|
||||
mInputMutex(gAPRPoolp),
|
||||
mOutputMutex(gAPRPoolp),
|
||||
mOutputStartIndex(0),
|
||||
mOwner(owner),
|
||||
mSocket(socket)
|
||||
{
|
||||
|
||||
mOwner->setMessagePipe(this);
|
||||
}
|
||||
|
||||
|
|
@ -113,6 +113,14 @@ bool LLPluginMessagePipe::addMessage(const std::string &message)
|
|||
{
|
||||
// queue the message for later output
|
||||
LLMutexLock lock(&mOutputMutex);
|
||||
|
||||
// If we're starting to use up too much memory, clear
|
||||
if (mOutputStartIndex > 1024 * 1024)
|
||||
{
|
||||
mOutput = mOutput.substr(mOutputStartIndex);
|
||||
mOutputStartIndex = 0;
|
||||
}
|
||||
|
||||
mOutput += message;
|
||||
mOutput += MESSAGE_DELIMITER; // message separator
|
||||
|
||||
|
|
@ -165,35 +173,44 @@ bool LLPluginMessagePipe::pumpOutput()
|
|||
if(mSocket)
|
||||
{
|
||||
apr_status_t status;
|
||||
apr_size_t size;
|
||||
apr_size_t in_size, out_size;
|
||||
|
||||
LLMutexLock lock(&mOutputMutex);
|
||||
if(!mOutput.empty())
|
||||
|
||||
const char * output_data = &(mOutput.data()[mOutputStartIndex]);
|
||||
if(*output_data != '\0')
|
||||
{
|
||||
// write any outgoing messages
|
||||
size = (apr_size_t)mOutput.size();
|
||||
in_size = (apr_size_t) (mOutput.size() - mOutputStartIndex);
|
||||
out_size = in_size;
|
||||
|
||||
setSocketTimeout(0);
|
||||
|
||||
// LL_INFOS("Plugin") << "before apr_socket_send, size = " << size << LL_ENDL;
|
||||
|
||||
status = apr_socket_send(
|
||||
mSocket->getSocket(),
|
||||
(const char*)mOutput.data(),
|
||||
&size);
|
||||
status = apr_socket_send(mSocket->getSocket(),
|
||||
output_data,
|
||||
&out_size);
|
||||
|
||||
// LL_INFOS("Plugin") << "after apr_socket_send, size = " << size << LL_ENDL;
|
||||
|
||||
if(status == APR_SUCCESS)
|
||||
if((status == APR_SUCCESS) || APR_STATUS_IS_EAGAIN(status))
|
||||
{
|
||||
// success
|
||||
mOutput = mOutput.substr(size);
|
||||
}
|
||||
else if(APR_STATUS_IS_EAGAIN(status))
|
||||
{
|
||||
// Socket buffer is full...
|
||||
// remove the written part from the buffer and try again later.
|
||||
mOutput = mOutput.substr(size);
|
||||
// Success or Socket buffer is full...
|
||||
|
||||
// If we've pumped the entire string, clear it
|
||||
if (out_size == in_size)
|
||||
{
|
||||
mOutputStartIndex = 0;
|
||||
mOutput.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
llassert(in_size > out_size);
|
||||
|
||||
// Remove the written part from the buffer and try again later.
|
||||
mOutputStartIndex += out_size;
|
||||
}
|
||||
}
|
||||
else if(APR_STATUS_IS_EOF(status))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class LLPluginMessagePipeOwner
|
|||
LOG_CLASS(LLPluginMessagePipeOwner);
|
||||
public:
|
||||
LLPluginMessagePipeOwner();
|
||||
~LLPluginMessagePipeOwner();
|
||||
virtual ~LLPluginMessagePipeOwner();
|
||||
|
||||
// called with incoming messages
|
||||
virtual void receiveMessageRaw(const std::string &message) = 0;
|
||||
|
|
@ -86,6 +86,7 @@ protected:
|
|||
std::string mInput;
|
||||
LLMutex mOutputMutex;
|
||||
std::string mOutput;
|
||||
std::string::size_type mOutputStartIndex;
|
||||
|
||||
LLPluginMessagePipeOwner *mOwner;
|
||||
LLSocket::ptr_t mSocket;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
class LLPluginProcessParentOwner
|
||||
{
|
||||
public:
|
||||
~LLPluginProcessParentOwner();
|
||||
virtual ~LLPluginProcessParentOwner();
|
||||
virtual void receivePluginMessage(const LLPluginMessage &message) = 0;
|
||||
virtual bool receivePluginMessageEarly(const LLPluginMessage &message) {return false;};
|
||||
// This will only be called when the plugin has died unexpectedly
|
||||
|
|
|
|||
|
|
@ -31,11 +31,18 @@
|
|||
#include "llconvexdecomposition.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llvector4a.h"
|
||||
|
||||
#if LL_MSVC
|
||||
#pragma warning (disable : 4263)
|
||||
#pragma warning (disable : 4264)
|
||||
#endif
|
||||
#include "dae.h"
|
||||
#include "dae/daeErrorHandler.h"
|
||||
#include "dom/domConstants.h"
|
||||
#include "dom/domMesh.h"
|
||||
#if LL_MSVC
|
||||
#pragma warning (default : 4263)
|
||||
#pragma warning (default : 4264)
|
||||
#endif
|
||||
|
||||
#ifdef LL_STANDALONE
|
||||
# include <zlib.h>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "m4math.h"
|
||||
|
||||
#include "llrender.h"
|
||||
#include "llglslshader.h"
|
||||
|
||||
#include "llglheaders.h"
|
||||
|
||||
|
|
@ -195,7 +196,7 @@ void LLCubeMap::enableTexture(S32 stage)
|
|||
void LLCubeMap::enableTextureCoords(S32 stage)
|
||||
{
|
||||
mTextureCoordStage = stage;
|
||||
if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
|
||||
if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
|
||||
{
|
||||
if (stage > 0)
|
||||
{
|
||||
|
|
@ -237,7 +238,7 @@ void LLCubeMap::disableTexture(void)
|
|||
|
||||
void LLCubeMap::disableTextureCoords(void)
|
||||
{
|
||||
if (gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
|
||||
if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
|
||||
{
|
||||
if (mTextureCoordStage > 0)
|
||||
{
|
||||
|
|
@ -264,19 +265,19 @@ void LLCubeMap::setMatrix(S32 stage)
|
|||
gGL.getTexUnit(stage)->activate();
|
||||
}
|
||||
|
||||
LLVector3 x(LLVector3d(gGLModelView+0));
|
||||
LLVector3 y(LLVector3d(gGLModelView+4));
|
||||
LLVector3 z(LLVector3d(gGLModelView+8));
|
||||
LLVector3 x(gGLModelView+0);
|
||||
LLVector3 y(gGLModelView+4);
|
||||
LLVector3 z(gGLModelView+8);
|
||||
|
||||
LLMatrix3 mat3;
|
||||
mat3.setRows(x,y,z);
|
||||
LLMatrix4 trans(mat3);
|
||||
trans.transpose();
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPushMatrix();
|
||||
glLoadMatrixf((F32 *)trans.mMatrix);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
gGL.pushMatrix();
|
||||
gGL.loadMatrix((F32 *)trans.mMatrix);
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
||||
/*if (stage > 0)
|
||||
{
|
||||
|
|
@ -292,9 +293,9 @@ void LLCubeMap::restoreMatrix()
|
|||
{
|
||||
gGL.getTexUnit(mMatrixStage)->activate();
|
||||
}
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
||||
/*if (mMatrixStage > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -55,7 +55,10 @@ FT_Library gFTLibrary = NULL;
|
|||
//static
|
||||
void LLFontManager::initClass()
|
||||
{
|
||||
gFontManagerp = new LLFontManager;
|
||||
if (!gFontManagerp)
|
||||
{
|
||||
gFontManagerp = new LLFontManager;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -136,7 +139,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
|
|||
FT_Done_Face(mFTFace);
|
||||
mFTFace = NULL;
|
||||
}
|
||||
|
||||
|
||||
int error;
|
||||
|
||||
error = FT_New_Face( gFTLibrary,
|
||||
|
|
|
|||
|
|
@ -67,6 +67,36 @@ static const std::string HEADLESS_VERSION_STRING("1.0");
|
|||
|
||||
std::ofstream gFailLog;
|
||||
|
||||
#if GL_ARB_debug_output
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
|
||||
void APIENTRY gl_debug_callback(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
GLvoid* userParam)
|
||||
{
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
|
||||
{
|
||||
llwarns << "----- GL ERROR --------" << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "----- GL WARNING -------" << llendl;
|
||||
}
|
||||
llwarns << "Type: " << std::hex << type << llendl;
|
||||
llwarns << "ID: " << std::hex << id << llendl;
|
||||
llwarns << "Severity: " << std::hex << severity << llendl;
|
||||
llwarns << "Message: " << message << llendl;
|
||||
llwarns << "-----------------------" << llendl;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ll_init_fail_log(std::string filename)
|
||||
{
|
||||
gFailLog.open(filename.c_str());
|
||||
|
|
@ -110,6 +140,11 @@ std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
|
|||
|
||||
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
|
||||
// ATI prototypes
|
||||
|
||||
#if LL_WINDOWS
|
||||
PFNGLGETSTRINGIPROC glGetStringi = NULL;
|
||||
#endif
|
||||
|
||||
// vertex blending prototypes
|
||||
PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB = NULL;
|
||||
PFNGLVERTEXBLENDARBPROC glVertexBlendARB = NULL;
|
||||
|
|
@ -128,6 +163,12 @@ PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
|
|||
PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL;
|
||||
PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
|
||||
|
||||
//GL_ARB_vertex_array_object
|
||||
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
|
||||
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
|
||||
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
|
||||
PFNGLISVERTEXARRAYPROC glIsVertexArray = NULL;
|
||||
|
||||
// GL_ARB_map_buffer_range
|
||||
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = NULL;
|
||||
PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange = NULL;
|
||||
|
|
@ -197,10 +238,16 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL;
|
|||
PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL;
|
||||
|
||||
//GL_ARB_texture_multisample
|
||||
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
|
||||
PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
|
||||
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
|
||||
PFNGLSAMPLEMASKIPROC glSampleMaski;
|
||||
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample = NULL;
|
||||
PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;
|
||||
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;
|
||||
PFNGLSAMPLEMASKIPROC glSampleMaski = NULL;
|
||||
|
||||
//GL_ARB_debug_output
|
||||
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
|
||||
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
|
||||
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB = NULL;
|
||||
PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = NULL;
|
||||
|
||||
// GL_EXT_blend_func_separate
|
||||
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
|
||||
|
|
@ -249,6 +296,10 @@ PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
|
|||
PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
|
||||
PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
|
||||
|
||||
#if LL_WINDOWS
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
|
||||
#endif
|
||||
|
||||
// vertex shader prototypes
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
|
||||
|
|
@ -349,6 +400,7 @@ LLGLManager::LLGLManager() :
|
|||
mHasBlendFuncSeparate(FALSE),
|
||||
mHasSync(FALSE),
|
||||
mHasVertexBufferObject(FALSE),
|
||||
mHasVertexArrayObject(FALSE),
|
||||
mHasMapBufferRange(FALSE),
|
||||
mHasFlushBufferRange(FALSE),
|
||||
mHasPBuffer(FALSE),
|
||||
|
|
@ -370,6 +422,7 @@ LLGLManager::LLGLManager() :
|
|||
mHasAnisotropic(FALSE),
|
||||
mHasARBEnvCombine(FALSE),
|
||||
mHasCubeMap(FALSE),
|
||||
mHasDebugOutput(FALSE),
|
||||
|
||||
mIsATI(FALSE),
|
||||
mIsNVIDIA(FALSE),
|
||||
|
|
@ -409,6 +462,15 @@ void LLGLManager::initWGL()
|
|||
LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
|
||||
}
|
||||
|
||||
if (ExtensionExists("WGL_ARB_create_context",gGLHExts.mSysExts))
|
||||
{
|
||||
GLH_EXT_NAME(wglCreateContextAttribsARB) = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
|
||||
}
|
||||
|
||||
if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
|
||||
{
|
||||
GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
|
||||
|
|
@ -438,13 +500,45 @@ bool LLGLManager::initGL()
|
|||
LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
|
||||
}
|
||||
|
||||
GLint alpha_bits;
|
||||
glGetIntegerv( GL_ALPHA_BITS, &alpha_bits );
|
||||
if( 8 != alpha_bits )
|
||||
stop_glerror();
|
||||
|
||||
#if LL_WINDOWS
|
||||
if (!glGetStringi)
|
||||
{
|
||||
LL_WARNS("RenderInit") << "Frame buffer has less than 8 bits of alpha. Avatar texture compositing will fail." << LL_ENDL;
|
||||
glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
|
||||
}
|
||||
|
||||
//reload extensions string (may have changed after using wglCreateContextAttrib)
|
||||
if (glGetStringi)
|
||||
{
|
||||
std::stringstream str;
|
||||
|
||||
GLint count = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||
for (GLint i = 0; i < count; ++i)
|
||||
{
|
||||
std::string ext((const char*) glGetStringi(GL_EXTENSIONS, i));
|
||||
str << ext << " ";
|
||||
LL_DEBUGS("GLExtensions") << ext << llendl;
|
||||
}
|
||||
|
||||
{
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
|
||||
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
if(wglGetExtensionsStringARB)
|
||||
{
|
||||
str << (const char*) wglGetExtensionsStringARB(wglGetCurrentDC());
|
||||
}
|
||||
}
|
||||
|
||||
free(gGLHExts.mSysExts);
|
||||
std::string extensions = str.str();
|
||||
gGLHExts.mSysExts = strdup(extensions.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
stop_glerror();
|
||||
|
||||
// Extract video card strings and convert to upper case to
|
||||
// work around driver-to-driver variation in capitalization.
|
||||
mGLVendor = std::string((const char *)glGetString(GL_VENDOR));
|
||||
|
|
@ -459,7 +553,7 @@ bool LLGLManager::initGL()
|
|||
&mDriverVersionVendorString );
|
||||
|
||||
mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
|
||||
|
||||
|
||||
// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
|
||||
// from being recognized as ATI.
|
||||
if (mGLVendor.substr(0,4) == "ATI ")
|
||||
|
|
@ -531,8 +625,12 @@ bool LLGLManager::initGL()
|
|||
mGLVendorShort = "MISC";
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
|
||||
initExtensions();
|
||||
stop_glerror();
|
||||
|
||||
S32 old_vram = mVRAM;
|
||||
|
||||
if (mHasATIMemInfo)
|
||||
{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
|
||||
|
|
@ -548,7 +646,27 @@ bool LLGLManager::initGL()
|
|||
mVRAM = dedicated_memory/1024;
|
||||
}
|
||||
|
||||
if (mHasMultitexture)
|
||||
if (mVRAM < 256)
|
||||
{ //something likely went wrong using the above extensions, fall back to old method
|
||||
mVRAM = old_vram;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (mHasFragmentShader)
|
||||
{
|
||||
GLint num_tex_image_units;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
|
||||
mNumTextureImageUnits = llmin(num_tex_image_units, 32);
|
||||
}
|
||||
|
||||
if (LLRender::sGLCoreProfile)
|
||||
{
|
||||
mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS);
|
||||
}
|
||||
else if (mHasMultitexture)
|
||||
{
|
||||
GLint num_tex_units;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
|
||||
|
|
@ -567,12 +685,7 @@ bool LLGLManager::initGL()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (mHasFragmentShader)
|
||||
{
|
||||
GLint num_tex_image_units;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
|
||||
mNumTextureImageUnits = llmin(num_tex_image_units, 32);
|
||||
}
|
||||
stop_glerror();
|
||||
|
||||
if (mHasTextureMultisample)
|
||||
{
|
||||
|
|
@ -582,6 +695,21 @@ bool LLGLManager::initGL()
|
|||
glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
#if LL_WINDOWS
|
||||
if (mHasDebugOutput && gDebugGL)
|
||||
{ //setup debug output callback
|
||||
//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
|
||||
glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
}
|
||||
#endif
|
||||
|
||||
stop_glerror();
|
||||
|
||||
//HACK always disable texture multisample, use FXAA instead
|
||||
mHasTextureMultisample = FALSE;
|
||||
#if LL_WINDOWS
|
||||
if (mIsATI)
|
||||
{ //using multisample textures on ATI results in black screen for some reason
|
||||
|
|
@ -593,10 +721,17 @@ bool LLGLManager::initGL()
|
|||
{
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
setToDebugGPU();
|
||||
|
||||
stop_glerror();
|
||||
|
||||
initGLStates();
|
||||
|
||||
stop_glerror();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -700,14 +835,6 @@ std::string LLGLManager::getRawGLString()
|
|||
return gl_string;
|
||||
}
|
||||
|
||||
U32 LLGLManager::getNumFBOFSAASamples(U32 samples)
|
||||
{
|
||||
samples = llmin(samples, (U32) mMaxColorTextureSamples);
|
||||
samples = llmin(samples, (U32) mMaxDepthTextureSamples);
|
||||
samples = llmin(samples, (U32) 4);
|
||||
return samples;
|
||||
}
|
||||
|
||||
void LLGLManager::shutdownGL()
|
||||
{
|
||||
if (mInited)
|
||||
|
|
@ -774,7 +901,7 @@ void LLGLManager::initExtensions()
|
|||
mHasVertexShader = FALSE;
|
||||
mHasFragmentShader = FALSE;
|
||||
mHasTextureRectangle = FALSE;
|
||||
#else // LL_MESA_HEADLESS
|
||||
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
|
||||
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
|
||||
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
|
||||
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
|
||||
|
|
@ -788,6 +915,7 @@ void LLGLManager::initExtensions()
|
|||
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
|
||||
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
|
||||
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
|
||||
mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
|
||||
mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
|
||||
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
|
||||
mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
|
||||
|
|
@ -806,13 +934,14 @@ void LLGLManager::initExtensions()
|
|||
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);
|
||||
#if !LL_DARWIN
|
||||
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
|
||||
#endif
|
||||
mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
|
||||
mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
|
||||
mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
|
||||
&& ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
|
||||
mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
|
||||
&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
|
||||
mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
|
||||
#endif
|
||||
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
|
|
@ -985,6 +1114,13 @@ void LLGLManager::initExtensions()
|
|||
mHasVertexBufferObject = FALSE;
|
||||
}
|
||||
}
|
||||
if (mHasVertexArrayObject)
|
||||
{
|
||||
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glBindVertexArray");
|
||||
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteVertexArrays");
|
||||
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenVertexArrays");
|
||||
glIsVertexArray = (PFNGLISVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glIsVertexArray");
|
||||
}
|
||||
if (mHasSync)
|
||||
{
|
||||
glFenceSync = (PFNGLFENCESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
|
||||
|
|
@ -1039,6 +1175,13 @@ void LLGLManager::initExtensions()
|
|||
glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
|
||||
glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
|
||||
}
|
||||
if (mHasDebugOutput)
|
||||
{
|
||||
glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
|
||||
glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageInsertARB");
|
||||
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallbackARB");
|
||||
glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLogARB");
|
||||
}
|
||||
#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
|
||||
// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
|
||||
glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
|
||||
|
|
@ -1193,7 +1336,7 @@ void rotate_quat(LLQuaternion& rotation)
|
|||
{
|
||||
F32 angle_radians, x, y, z;
|
||||
rotation.getAngleAxis(&angle_radians, &x, &y, &z);
|
||||
glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
|
||||
gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
|
||||
}
|
||||
|
||||
void flush_glerror()
|
||||
|
|
@ -1230,10 +1373,6 @@ void log_glerror()
|
|||
|
||||
void do_assert_glerror()
|
||||
{
|
||||
if (LL_UNLIKELY(!gGLManager.mInited))
|
||||
{
|
||||
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
|
||||
}
|
||||
// Create or update texture to be used with this data
|
||||
GLenum error;
|
||||
error = glGetError();
|
||||
|
|
@ -1326,11 +1465,6 @@ void LLGLState::initClass()
|
|||
//make sure multisample defaults to disabled
|
||||
sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
|
||||
glDisable(GL_MULTISAMPLE_ARB);
|
||||
|
||||
sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
|
||||
glDisable(GL_MULTISAMPLE_ARB);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -1604,7 +1738,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
|||
|
||||
void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
if (!gDebugGL)
|
||||
if (!gDebugGL || LLGLSLShader::sNoFixedFunction)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1625,7 +1759,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
|||
error = TRUE;
|
||||
}
|
||||
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
|
||||
/*glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
|
||||
if (active_texture != GL_TEXTURE0_ARB)
|
||||
{
|
||||
llwarns << "Active texture corrupted: " << active_texture << llendl;
|
||||
|
|
@ -1634,7 +1768,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
|||
gFailLog << "Active texture corrupted: " << active_texture << std::endl;
|
||||
}
|
||||
error = TRUE;
|
||||
}
|
||||
}*/
|
||||
|
||||
static const char* label[] =
|
||||
{
|
||||
|
|
@ -1661,7 +1795,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
|||
};
|
||||
|
||||
|
||||
for (S32 j = 0; j < 4; j++)
|
||||
for (S32 j = 1; j < 4; j++)
|
||||
{
|
||||
if (glIsEnabled(value[j]))
|
||||
{
|
||||
|
|
@ -1783,17 +1917,26 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
|
|||
mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
|
||||
{
|
||||
if (LLGLSLShader::sNoFixedFunction)
|
||||
{ //always disable state that's deprecated post GL 3.0
|
||||
{ //always ignore state that's deprecated post GL 3.0
|
||||
switch (state)
|
||||
{
|
||||
case GL_ALPHA_TEST:
|
||||
enabled = 0;
|
||||
case GL_NORMALIZE:
|
||||
case GL_TEXTURE_GEN_R:
|
||||
case GL_TEXTURE_GEN_S:
|
||||
case GL_TEXTURE_GEN_T:
|
||||
case GL_TEXTURE_GEN_Q:
|
||||
case GL_LIGHTING:
|
||||
case GL_COLOR_MATERIAL:
|
||||
case GL_FOG:
|
||||
case GL_LINE_STIPPLE:
|
||||
mState = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
if (state)
|
||||
if (mState)
|
||||
{
|
||||
mWasEnabled = sStateMap[state];
|
||||
llassert(mWasEnabled == glIsEnabled(state));
|
||||
|
|
@ -1875,79 +2018,6 @@ void LLGLManager::initGLStates()
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void enable_vertex_weighting(const S32 index)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0) glEnableVertexAttribArrayARB(index); // vertex weights
|
||||
#endif
|
||||
}
|
||||
|
||||
void disable_vertex_weighting(const S32 index)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0) glDisableVertexAttribArrayARB(index); // vertex weights
|
||||
#endif
|
||||
}
|
||||
|
||||
void enable_binormals(const S32 index)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0)
|
||||
{
|
||||
glEnableVertexAttribArrayARB(index); // binormals
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void disable_binormals(const S32 index)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0)
|
||||
{
|
||||
glDisableVertexAttribArrayARB(index); // binormals
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void enable_cloth_weights(const S32 index)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0) glEnableVertexAttribArrayARB(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
void disable_cloth_weights(const S32 index)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0) glDisableVertexAttribArrayARB(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, stride, weights);
|
||||
stop_glerror();
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0) glVertexAttribPointerARB(index, 4, GL_FLOAT, TRUE, stride, weights);
|
||||
stop_glerror();
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_binormals(const S32 index, const U32 stride,const LLVector3 *binormals)
|
||||
{
|
||||
#if GL_ARB_vertex_program
|
||||
if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, binormals);
|
||||
stop_glerror();
|
||||
#endif
|
||||
}
|
||||
|
||||
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )
|
||||
{
|
||||
// GL_VERSION returns a null-terminated string with the format:
|
||||
|
|
@ -2060,20 +2130,20 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
|
|||
glh::matrix4f suffix;
|
||||
suffix.set_row(2, cplane);
|
||||
glh::matrix4f newP = suffix * P;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadMatrixf(newP.m);
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
gGL.loadMatrix(newP.m);
|
||||
gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
|
||||
LLGLUserClipPlane::~LLGLUserClipPlane()
|
||||
{
|
||||
if (mApply)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2263,16 +2333,16 @@ LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer)
|
|||
P.element(2, i) = P.element(3, i) * depth;
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadMatrixf(P.m);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
gGL.loadMatrix(P.m);
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
|
||||
LLGLSquashToFarClip::~LLGLSquashToFarClip()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ public:
|
|||
|
||||
// ARB Extensions
|
||||
BOOL mHasVertexBufferObject;
|
||||
BOOL mHasVertexArrayObject;
|
||||
BOOL mHasSync;
|
||||
BOOL mHasMapBufferRange;
|
||||
BOOL mHasFlushBufferRange;
|
||||
|
|
@ -112,6 +113,7 @@ public:
|
|||
BOOL mHasAnisotropic;
|
||||
BOOL mHasARBEnvCombine;
|
||||
BOOL mHasCubeMap;
|
||||
BOOL mHasDebugOutput;
|
||||
|
||||
// Vendor-specific extensions
|
||||
BOOL mIsATI;
|
||||
|
|
@ -148,7 +150,6 @@ public:
|
|||
void printGLInfoString();
|
||||
void getGLInfo(LLSD& info);
|
||||
|
||||
U32 getNumFBOFSAASamples(U32 desired_samples = 32);
|
||||
// In ALL CAPS
|
||||
std::string mGLVendor;
|
||||
std::string mGLVendorShort;
|
||||
|
|
@ -252,7 +253,7 @@ public:
|
|||
static void dumpStates();
|
||||
static void checkStates(const std::string& msg = "");
|
||||
static void checkTextureChannels(const std::string& msg = "");
|
||||
static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0x0001);
|
||||
static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0);
|
||||
|
||||
protected:
|
||||
static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
|
||||
|
|
@ -419,15 +420,7 @@ extern LLMatrix4 gGLObliqueProjectionInverse;
|
|||
#include "llglstates.h"
|
||||
|
||||
void init_glstates();
|
||||
void enable_vertex_weighting(const S32 index);
|
||||
void disable_vertex_weighting(const S32 index);
|
||||
void enable_binormals(const S32 index);
|
||||
void disable_binormals(const S32 index);
|
||||
void enable_cloth_weights(const S32 index);
|
||||
void disable_cloth_weights(const S32 index);
|
||||
void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights);
|
||||
void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights);
|
||||
void set_binormals(const S32 index, const U32 stride, const LLVector3 *binormals);
|
||||
|
||||
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
|
||||
|
||||
extern BOOL gClothRipple;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,12 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
|
|||
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
|
||||
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
|
||||
|
||||
// GL_ARB_vertex_array_object
|
||||
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
|
||||
|
||||
// GL_ARB_sync
|
||||
extern PFNGLFENCESYNCPROC glFenceSync;
|
||||
extern PFNGLISSYNCPROC glIsSync;
|
||||
|
|
@ -310,6 +316,12 @@ extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
|
|||
extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements;
|
||||
#endif // LL_LINUX_NV_GL_HEADERS
|
||||
|
||||
// GL_ARB_vertex_array_object
|
||||
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
|
||||
|
||||
// GL_ARB_vertex_buffer_object
|
||||
extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
|
||||
extern PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB;
|
||||
|
|
@ -531,6 +543,9 @@ extern PFNGLSAMPLEMASKIPROC glSampleMaski;
|
|||
#include "GL/glext.h"
|
||||
#include "GL/glh_extensions.h"
|
||||
|
||||
// WGL_ARB_create_context
|
||||
extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
|
||||
extern PFNGLGETSTRINGIPROC glGetStringi;
|
||||
|
||||
// GL_ARB_vertex_buffer_object
|
||||
extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
|
||||
|
|
@ -545,6 +560,12 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
|
|||
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
|
||||
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
|
||||
|
||||
// GL_ARB_vertex_array_object
|
||||
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
|
||||
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
|
||||
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
|
||||
|
||||
// GL_ARB_sync
|
||||
extern PFNGLFENCESYNCPROC glFenceSync;
|
||||
extern PFNGLISSYNCPROC glIsSync;
|
||||
|
|
@ -735,6 +756,12 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
|
|||
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
|
||||
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
|
||||
|
||||
//GL_ARB_debug_output
|
||||
extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
|
||||
extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
|
||||
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
|
||||
extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB;
|
||||
|
||||
#elif LL_DARWIN
|
||||
//----------------------------------------------------------------------------
|
||||
// LL_DARWIN
|
||||
|
|
@ -899,6 +926,31 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
|
|||
#endif /* GL_GLEXT_FUNCTION_POINTERS */
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_texture_rg
|
||||
#define GL_RG 0x8227
|
||||
#define GL_RG_INTEGER 0x8228
|
||||
#define GL_R8 0x8229
|
||||
#define GL_R16 0x822A
|
||||
#define GL_RG8 0x822B
|
||||
#define GL_RG16 0x822C
|
||||
#define GL_R16F 0x822D
|
||||
#define GL_R32F 0x822E
|
||||
#define GL_RG16F 0x822F
|
||||
#define GL_RG32F 0x8230
|
||||
#define GL_R8I 0x8231
|
||||
#define GL_R8UI 0x8232
|
||||
#define GL_R16I 0x8233
|
||||
#define GL_R16UI 0x8234
|
||||
#define GL_R32I 0x8235
|
||||
#define GL_R32UI 0x8236
|
||||
#define GL_RG8I 0x8237
|
||||
#define GL_RG8UI 0x8238
|
||||
#define GL_RG16I 0x8239
|
||||
#define GL_RG16UI 0x823A
|
||||
#define GL_RG32I 0x823B
|
||||
#define GL_RG32UI 0x823C
|
||||
#endif
|
||||
|
||||
// May be needed for DARWIN...
|
||||
// #ifndef GL_ARB_compressed_tex_image
|
||||
// #define GL_ARB_compressed_tex_image 1
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llshadermgr.h"
|
||||
#include "llfile.h"
|
||||
#include "llrender.h"
|
||||
#include "llvertexbuffer.h"
|
||||
|
||||
#if LL_DARWIN
|
||||
#include "OpenGL/OpenGL.h"
|
||||
|
|
@ -50,6 +51,7 @@ using std::string;
|
|||
|
||||
GLhandleARB LLGLSLShader::sCurBoundShader = 0;
|
||||
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
|
||||
S32 LLGLSLShader::sIndexedTextureChannels = 0;
|
||||
bool LLGLSLShader::sNoFixedFunction = false;
|
||||
|
||||
//UI shader -- declared here so llui_libtest will link properly
|
||||
|
|
@ -75,6 +77,7 @@ hasAlphaMask(false)
|
|||
LLGLSLShader::LLGLSLShader()
|
||||
: mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLGLSLShader::unload()
|
||||
|
|
@ -110,17 +113,19 @@ void LLGLSLShader::unload()
|
|||
BOOL LLGLSLShader::createShader(vector<string> * attributes,
|
||||
vector<string> * uniforms)
|
||||
{
|
||||
//reloading, reset matrix hash values
|
||||
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
|
||||
{
|
||||
mMatHash[i] = 0xFFFFFFFF;
|
||||
}
|
||||
mLightHash = 0xFFFFFFFF;
|
||||
|
||||
llassert_always(!mShaderFiles.empty());
|
||||
BOOL success = TRUE;
|
||||
|
||||
// Create program
|
||||
mProgramObject = glCreateProgramObjectARB();
|
||||
|
||||
if (gGLManager.mGLVersion < 3.1f)
|
||||
{ //force indexed texture channels to 1 if GL version is old (performance improvement for drivers with poor branching shader model support)
|
||||
mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
|
||||
}
|
||||
|
||||
//compile new source
|
||||
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
|
||||
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
|
||||
|
|
@ -235,6 +240,13 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
|
|||
|
||||
BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
|
||||
{
|
||||
//before linking, make sure reserved attributes always have consistent locations
|
||||
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
|
||||
{
|
||||
const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
|
||||
glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name);
|
||||
}
|
||||
|
||||
//link the program
|
||||
BOOL res = link();
|
||||
|
||||
|
|
@ -308,7 +320,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
|
|||
for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
|
||||
{
|
||||
if ( (mUniform[i] == -1)
|
||||
&& (LLShaderMgr::instance()->mReservedUniforms[i].compare(0, length, name, LLShaderMgr::instance()->mReservedUniforms[i].length()) == 0))
|
||||
&& (LLShaderMgr::instance()->mReservedUniforms[i] == name))
|
||||
{
|
||||
//found it
|
||||
mUniform[i] = location;
|
||||
|
|
@ -322,7 +334,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
|
|||
for (U32 i = 0; i < uniforms->size(); i++)
|
||||
{
|
||||
if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
|
||||
&& ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0))
|
||||
&& ((*uniforms)[i] == name))
|
||||
{
|
||||
//found it
|
||||
mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
|
||||
|
|
@ -386,6 +398,7 @@ void LLGLSLShader::bind()
|
|||
gGL.flush();
|
||||
if (gGLManager.mHasShaderObjects)
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
glUseProgramObjectARB(mProgramObject);
|
||||
sCurBoundShader = mProgramObject;
|
||||
sCurBoundShaderPtr = this;
|
||||
|
|
@ -411,6 +424,7 @@ void LLGLSLShader::unbind()
|
|||
stop_glerror();
|
||||
}
|
||||
}
|
||||
LLVertexBuffer::unbind();
|
||||
glUseProgramObjectARB(0);
|
||||
sCurBoundShader = 0;
|
||||
sCurBoundShaderPtr = NULL;
|
||||
|
|
@ -420,9 +434,13 @@ void LLGLSLShader::unbind()
|
|||
|
||||
void LLGLSLShader::bindNoShader(void)
|
||||
{
|
||||
glUseProgramObjectARB(0);
|
||||
sCurBoundShader = 0;
|
||||
sCurBoundShaderPtr = NULL;
|
||||
LLVertexBuffer::unbind();
|
||||
if (gGLManager.mHasShaderObjects)
|
||||
{
|
||||
glUseProgramObjectARB(0);
|
||||
sCurBoundShader = 0;
|
||||
sCurBoundShaderPtr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
|
||||
|
|
@ -768,13 +786,17 @@ GLint LLGLSLShader::getUniformLocation(const string& uniform)
|
|||
}
|
||||
}
|
||||
|
||||
/*if (gDebugGL)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GLint LLGLSLShader::getUniformLocation(U32 index)
|
||||
{
|
||||
GLint ret = -1;
|
||||
if (mProgramObject > 0)
|
||||
{
|
||||
if (ret == -1 && ret != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
|
||||
{
|
||||
llerrs << "Uniform map invalid." << llendl;
|
||||
}
|
||||
}*/
|
||||
llassert(index < mUniform.size());
|
||||
return mUniform[index];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -930,7 +952,9 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v
|
|||
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
|
||||
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
|
||||
{
|
||||
stop_glerror();
|
||||
glUniform4fvARB(location, count, v);
|
||||
stop_glerror();
|
||||
mValue[location] = vec;
|
||||
}
|
||||
}
|
||||
|
|
@ -985,8 +1009,8 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
|
|||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::setAlphaRange(F32 minimum, F32 maximum)
|
||||
void LLGLSLShader::setMinimumAlpha(F32 minimum)
|
||||
{
|
||||
uniform1f("minimum_alpha", minimum);
|
||||
uniform1f("maximum_alpha", maximum);
|
||||
gGL.flush();
|
||||
uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public:
|
|||
|
||||
static GLhandleARB sCurBoundShader;
|
||||
static LLGLSLShader* sCurBoundShaderPtr;
|
||||
|
||||
static S32 sIndexedTextureChannels;
|
||||
static bool sNoFixedFunction;
|
||||
|
||||
void unload();
|
||||
|
|
@ -109,16 +109,17 @@ public:
|
|||
void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
|
||||
|
||||
void setAlphaRange(F32 minimum, F32 maximum);
|
||||
void setMinimumAlpha(F32 minimum);
|
||||
|
||||
void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void vertexAttrib4fv(U32 index, GLfloat* v);
|
||||
|
||||
GLint getUniformLocation(const std::string& uniform);
|
||||
GLint getUniformLocation(U32 index);
|
||||
|
||||
GLint getAttribLocation(U32 attrib);
|
||||
GLint mapUniformTextureChannel(GLint location, GLenum type);
|
||||
|
||||
|
||||
//enable/disable texture channel for specified uniform
|
||||
//if given texture uniform is active in the shader,
|
||||
//the corresponding channel will be active upon return
|
||||
|
|
@ -133,6 +134,9 @@ public:
|
|||
// Unbinds any previously bound shader by explicitly binding no shader.
|
||||
static void bindNoShader(void);
|
||||
|
||||
U32 mMatHash[LLRender::NUM_MATRIX_MODES];
|
||||
U32 mLightHash;
|
||||
|
||||
GLhandleARB mProgramObject;
|
||||
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
|
||||
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@
|
|||
|
||||
#include "llmath.h"
|
||||
#include "llgl.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llrender.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const F32 MIN_TEXTURE_LIFETIME = 10.f;
|
||||
|
||||
|
|
@ -725,7 +727,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
{
|
||||
if (mAutoGenMips)
|
||||
{
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
|
||||
if (!gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
|
||||
}
|
||||
stop_glerror();
|
||||
{
|
||||
// LLFastTimer t2(FTM_TEMP4);
|
||||
|
|
@ -754,6 +759,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
if (gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -875,6 +885,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
|||
|
||||
BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
|
||||
{
|
||||
//not compatible with core GL profile
|
||||
llassert(!LLRender::sGLCoreProfile);
|
||||
|
||||
if (gGLManager.mIsDisabled)
|
||||
{
|
||||
llwarns << "Trying to create a texture while GL is disabled!" << llendl;
|
||||
|
|
@ -901,29 +914,29 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
|
|||
{
|
||||
switch (mComponents)
|
||||
{
|
||||
case 1:
|
||||
case 1:
|
||||
// Use luminance alpha (for fonts)
|
||||
mFormatInternal = GL_LUMINANCE8;
|
||||
mFormatPrimary = GL_LUMINANCE;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 2:
|
||||
case 2:
|
||||
// Use luminance alpha (for fonts)
|
||||
mFormatInternal = GL_LUMINANCE8_ALPHA8;
|
||||
mFormatPrimary = GL_LUMINANCE_ALPHA;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 3:
|
||||
case 3:
|
||||
mFormatInternal = GL_RGB8;
|
||||
mFormatPrimary = GL_RGB;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 4:
|
||||
case 4:
|
||||
mFormatInternal = GL_RGBA8;
|
||||
mFormatPrimary = GL_RGBA;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
|
||||
}
|
||||
}
|
||||
|
|
@ -1099,8 +1112,75 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
|
|||
// static
|
||||
void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
|
||||
{
|
||||
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
|
||||
bool use_scratch = false;
|
||||
U32* scratch = NULL;
|
||||
if (LLRender::sGLCoreProfile)
|
||||
{
|
||||
if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
|
||||
{ //GL_ALPHA is deprecated, convert to RGBA
|
||||
use_scratch = true;
|
||||
scratch = new U32[width*height];
|
||||
|
||||
U32 pixel_count = (U32) (width*height);
|
||||
for (U32 i = 0; i < pixel_count; i++)
|
||||
{
|
||||
U8* pix = (U8*) &scratch[i];
|
||||
pix[0] = pix[1] = pix[2] = 0;
|
||||
pix[3] = ((U8*) pixels)[i];
|
||||
}
|
||||
|
||||
pixformat = GL_RGBA;
|
||||
intformat = GL_RGBA8;
|
||||
}
|
||||
|
||||
if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE)
|
||||
{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
|
||||
use_scratch = true;
|
||||
scratch = new U32[width*height];
|
||||
|
||||
U32 pixel_count = (U32) (width*height);
|
||||
for (U32 i = 0; i < pixel_count; i++)
|
||||
{
|
||||
U8 lum = ((U8*) pixels)[i*2+0];
|
||||
U8 alpha = ((U8*) pixels)[i*2+1];
|
||||
|
||||
U8* pix = (U8*) &scratch[i];
|
||||
pix[0] = pix[1] = pix[2] = lum;
|
||||
pix[3] = alpha;
|
||||
}
|
||||
|
||||
pixformat = GL_RGBA;
|
||||
intformat = GL_RGBA8;
|
||||
}
|
||||
|
||||
if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
|
||||
{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
|
||||
use_scratch = true;
|
||||
scratch = new U32[width*height];
|
||||
|
||||
U32 pixel_count = (U32) (width*height);
|
||||
for (U32 i = 0; i < pixel_count; i++)
|
||||
{
|
||||
U8 lum = ((U8*) pixels)[i];
|
||||
|
||||
U8* pix = (U8*) &scratch[i];
|
||||
pix[0] = pix[1] = pix[2] = lum;
|
||||
pix[3] = 255;
|
||||
}
|
||||
|
||||
pixformat = GL_RGBA;
|
||||
intformat = GL_RGB8;
|
||||
}
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
|
||||
stop_glerror();
|
||||
|
||||
if (use_scratch)
|
||||
{
|
||||
delete [] scratch;
|
||||
}
|
||||
}
|
||||
|
||||
//create an empty GL texture: just create a texture name
|
||||
|
|
@ -1167,29 +1247,29 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
{
|
||||
switch (mComponents)
|
||||
{
|
||||
case 1:
|
||||
case 1:
|
||||
// Use luminance alpha (for fonts)
|
||||
mFormatInternal = GL_LUMINANCE8;
|
||||
mFormatPrimary = GL_LUMINANCE;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 2:
|
||||
case 2:
|
||||
// Use luminance alpha (for fonts)
|
||||
mFormatInternal = GL_LUMINANCE8_ALPHA8;
|
||||
mFormatPrimary = GL_LUMINANCE_ALPHA;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 3:
|
||||
case 3:
|
||||
mFormatInternal = GL_RGB8;
|
||||
mFormatPrimary = GL_RGB;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case 4:
|
||||
case 4:
|
||||
mFormatInternal = GL_RGBA8;
|
||||
mFormatPrimary = GL_RGBA;
|
||||
mFormatType = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
|
||||
}
|
||||
|
||||
|
|
@ -1212,6 +1292,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
|
||||
{
|
||||
llassert(data_in);
|
||||
stop_glerror();
|
||||
|
||||
if (discard_level < 0)
|
||||
{
|
||||
|
|
@ -1240,8 +1321,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
|||
stop_glerror();
|
||||
{
|
||||
llverify(gGL.getTexUnit(0)->bind(this));
|
||||
stop_glerror();
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
|
||||
stop_glerror();
|
||||
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
if (!mTexName)
|
||||
|
|
@ -1754,7 +1838,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
|
|||
// this to be an intentional effect and don't treat as a mask.
|
||||
|
||||
U32 midrangetotal = 0;
|
||||
for (U32 i = 4; i < 11; i++)
|
||||
for (U32 i = 2; i < 13; i++)
|
||||
{
|
||||
midrangetotal += sample[i];
|
||||
}
|
||||
|
|
@ -1769,7 +1853,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
|
|||
upperhalftotal += sample[i];
|
||||
}
|
||||
|
||||
if (midrangetotal > length/16 || // lots of midrange, or
|
||||
if (midrangetotal > length/48 || // lots of midrange, or
|
||||
(lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or
|
||||
(upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque
|
||||
{
|
||||
|
|
|
|||
|
|
@ -466,21 +466,21 @@ void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadT
|
|||
|
||||
void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.pushMatrix();
|
||||
gGL.loadIdentity();
|
||||
gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
gGL.pushMatrix();
|
||||
gGL.loadIdentity();
|
||||
}
|
||||
|
||||
void LLPostProcess::viewPerspective(void)
|
||||
{
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPopMatrix();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPopMatrix();
|
||||
gGL.matrixMode(LLRender::MM_PROJECTION);
|
||||
gGL.popMatrix();
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
gGL.popMatrix();
|
||||
}
|
||||
|
||||
void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -41,6 +41,8 @@
|
|||
#include "llstrider.h"
|
||||
#include "llpointer.h"
|
||||
#include "llglheaders.h"
|
||||
#include "llmatrix4a.h"
|
||||
#include "glh/glh_linear.h"
|
||||
|
||||
class LLVertexBuffer;
|
||||
class LLCubeMap;
|
||||
|
|
@ -48,6 +50,8 @@ class LLImageGL;
|
|||
class LLRenderTarget;
|
||||
class LLTexture ;
|
||||
|
||||
#define LL_MATRIX_STACK_DEPTH 32
|
||||
|
||||
class LLTexUnit
|
||||
{
|
||||
friend class LLRender;
|
||||
|
|
@ -235,6 +239,8 @@ public:
|
|||
void setSpotDirection(const LLVector3& direction);
|
||||
|
||||
protected:
|
||||
friend class LLRender;
|
||||
|
||||
S32 mIndex;
|
||||
bool mEnabled;
|
||||
LLColor4 mDiffuse;
|
||||
|
|
@ -308,6 +314,18 @@ public:
|
|||
BF_UNDEF
|
||||
} eBlendFactor;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MM_MODELVIEW = 0,
|
||||
MM_PROJECTION,
|
||||
MM_TEXTURE0,
|
||||
MM_TEXTURE1,
|
||||
MM_TEXTURE2,
|
||||
MM_TEXTURE3,
|
||||
NUM_MATRIX_MODES,
|
||||
MM_TEXTURE
|
||||
} eMatrixMode;
|
||||
|
||||
LLRender();
|
||||
~LLRender();
|
||||
void init() ;
|
||||
|
|
@ -319,8 +337,21 @@ public:
|
|||
|
||||
void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
|
||||
void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
|
||||
void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z);
|
||||
void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar);
|
||||
|
||||
void pushMatrix();
|
||||
void popMatrix();
|
||||
void loadMatrix(const GLfloat* m);
|
||||
void loadIdentity();
|
||||
void multMatrix(const GLfloat* m);
|
||||
void matrixMode(U32 mode);
|
||||
|
||||
const glh::matrix4f& getModelviewMatrix();
|
||||
const glh::matrix4f& getProjectionMatrix();
|
||||
|
||||
void syncMatrices();
|
||||
void syncLightState();
|
||||
|
||||
void translateUI(F32 x, F32 y, F32 z);
|
||||
void scaleUI(F32 x, F32 y, F32 z);
|
||||
|
|
@ -351,6 +382,12 @@ public:
|
|||
void color3fv(const GLfloat* c);
|
||||
void color4ubv(const GLubyte* c);
|
||||
|
||||
void diffuseColor3f(F32 r, F32 g, F32 b);
|
||||
void diffuseColor3fv(const F32* c);
|
||||
void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
|
||||
void diffuseColor4fv(const F32* c);
|
||||
void diffuseColor4ubv(const U8* c);
|
||||
|
||||
void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
|
||||
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
|
||||
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
|
||||
|
|
@ -368,7 +405,8 @@ public:
|
|||
eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
|
||||
|
||||
LLLightState* getLight(U32 index);
|
||||
|
||||
void setAmbientLightColor(const LLColor4& color);
|
||||
|
||||
LLTexUnit* getTexUnit(U32 index);
|
||||
|
||||
U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
|
||||
|
|
@ -389,9 +427,21 @@ public:
|
|||
public:
|
||||
static U32 sUICalls;
|
||||
static U32 sUIVerts;
|
||||
static bool sGLCoreProfile;
|
||||
|
||||
private:
|
||||
bool mDirty;
|
||||
friend class LLLightState;
|
||||
|
||||
U32 mMatrixMode;
|
||||
U32 mMatIdx[NUM_MATRIX_MODES];
|
||||
U32 mMatHash[NUM_MATRIX_MODES];
|
||||
glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH];
|
||||
U32 mCurMatHash[NUM_MATRIX_MODES];
|
||||
U32 mLightHash;
|
||||
LLColor4 mAmbientLightColor;
|
||||
|
||||
bool mDirty;
|
||||
U32 mQuadCycle;
|
||||
U32 mCount;
|
||||
U32 mMode;
|
||||
U32 mCurrTextureUnitIndex;
|
||||
|
|
@ -419,10 +469,10 @@ private:
|
|||
|
||||
};
|
||||
|
||||
extern F64 gGLModelView[16];
|
||||
extern F64 gGLLastModelView[16];
|
||||
extern F64 gGLLastProjection[16];
|
||||
extern F64 gGLProjection[16];
|
||||
extern F32 gGLModelView[16];
|
||||
extern F32 gGLLastModelView[16];
|
||||
extern F32 gGLLastProjection[16];
|
||||
extern F32 gGLProjection[16];
|
||||
extern S32 gGLViewport[4];
|
||||
|
||||
extern LLRender gGL;
|
||||
|
|
|
|||
|
|
@ -35,106 +35,12 @@
|
|||
|
||||
#include "llglheaders.h"
|
||||
|
||||
GLUquadricObj *gQuadObj2 = NULL;
|
||||
LLRenderSphere gSphere;
|
||||
|
||||
void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks);
|
||||
|
||||
void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks)
|
||||
{
|
||||
if (!gQuadObj2)
|
||||
{
|
||||
gQuadObj2 = gluNewQuadric();
|
||||
if (!gQuadObj2)
|
||||
{
|
||||
llwarns << "drawSolidSphere couldn't allocate quadric" << llendl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gluQuadricDrawStyle(gQuadObj2, GLU_FILL);
|
||||
gluQuadricNormals(gQuadObj2, GLU_SMOOTH);
|
||||
// If we ever changed/used the texture or orientation state
|
||||
// of quadObj, we'd need to change it to the defaults here
|
||||
// with gluQuadricTexture and/or gluQuadricOrientation.
|
||||
gluQuadricTexture(gQuadObj2, GL_TRUE);
|
||||
gluSphere(gQuadObj2, radius, slices, stacks);
|
||||
}
|
||||
|
||||
|
||||
// A couple thoughts on sphere drawing:
|
||||
// 1) You need more slices than stacks, but little less than 2:1
|
||||
// 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother
|
||||
void LLRenderSphere::prerender()
|
||||
{
|
||||
// Create a series of display lists for different LODs
|
||||
mDList[0] = glGenLists(1);
|
||||
glNewList(mDList[0], GL_COMPILE);
|
||||
drawSolidSphere(1.0, 30, 20);
|
||||
glEndList();
|
||||
|
||||
mDList[1] = glGenLists(1);
|
||||
glNewList(mDList[1], GL_COMPILE);
|
||||
drawSolidSphere(1.0, 20, 15);
|
||||
glEndList();
|
||||
|
||||
mDList[2] = glGenLists(1);
|
||||
glNewList(mDList[2], GL_COMPILE);
|
||||
drawSolidSphere(1.0, 12, 8);
|
||||
glEndList();
|
||||
|
||||
mDList[3] = glGenLists(1);
|
||||
glNewList(mDList[3], GL_COMPILE);
|
||||
drawSolidSphere(1.0, 8, 5);
|
||||
glEndList();
|
||||
}
|
||||
|
||||
void LLRenderSphere::cleanupGL()
|
||||
{
|
||||
for (S32 detail = 0; detail < 4; detail++)
|
||||
{
|
||||
glDeleteLists(mDList[detail], 1);
|
||||
mDList[detail] = 0;
|
||||
}
|
||||
|
||||
if (gQuadObj2)
|
||||
{
|
||||
gluDeleteQuadric(gQuadObj2);
|
||||
gQuadObj2 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Constants here are empirically derived from my eyeballs, JNC
|
||||
//
|
||||
// The toughest adjustment is the cutoff for the lowest LOD
|
||||
// Maybe we should have more LODs at the low end?
|
||||
void LLRenderSphere::render(F32 pixel_area)
|
||||
{
|
||||
S32 level_of_detail;
|
||||
|
||||
if (pixel_area > 10000.f)
|
||||
{
|
||||
level_of_detail = 0;
|
||||
}
|
||||
else if (pixel_area > 800.f)
|
||||
{
|
||||
level_of_detail = 1;
|
||||
}
|
||||
else if (pixel_area > 100.f)
|
||||
{
|
||||
level_of_detail = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
level_of_detail = 3;
|
||||
}
|
||||
glCallList(mDList[level_of_detail]);
|
||||
}
|
||||
|
||||
|
||||
void LLRenderSphere::render()
|
||||
{
|
||||
glCallList(mDList[0]);
|
||||
renderGGL();
|
||||
gGL.flush();
|
||||
}
|
||||
|
||||
inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)
|
||||
|
|
|
|||
|
|
@ -40,11 +40,6 @@ void lat2xyz(LLVector3 * result, F32 lat, F32 lon); // utility routine
|
|||
class LLRenderSphere
|
||||
{
|
||||
public:
|
||||
LLGLuint mDList[5];
|
||||
|
||||
void prerender();
|
||||
void cleanupGL();
|
||||
void render(F32 pixel_area); // of a box of size 1.0 at that position
|
||||
void render(); // render at highest LOD
|
||||
void renderGGL(); // render using LLRender
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@
|
|||
#include "llgl.h"
|
||||
|
||||
LLRenderTarget* LLRenderTarget::sBoundTarget = NULL;
|
||||
|
||||
|
||||
U32 LLRenderTarget::sBytesAllocated = 0;
|
||||
|
||||
void check_framebuffer_status()
|
||||
{
|
||||
|
|
@ -51,7 +50,7 @@ void check_framebuffer_status()
|
|||
}
|
||||
}
|
||||
|
||||
BOOL LLRenderTarget::sUseFBO = false;
|
||||
bool LLRenderTarget::sUseFBO = false;
|
||||
|
||||
LLRenderTarget::LLRenderTarget() :
|
||||
mResX(0),
|
||||
|
|
@ -62,8 +61,7 @@ LLRenderTarget::LLRenderTarget() :
|
|||
mStencil(0),
|
||||
mUseDepth(false),
|
||||
mRenderDepth(false),
|
||||
mUsage(LLTexUnit::TT_TEXTURE),
|
||||
mSamples(0)
|
||||
mUsage(LLTexUnit::TT_TEXTURE)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -84,20 +82,6 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
|
|||
mStencil = stencil;
|
||||
mUsage = usage;
|
||||
mUseDepth = depth;
|
||||
mSamples = samples;
|
||||
|
||||
mSamples = gGLManager.getNumFBOFSAASamples(mSamples);
|
||||
|
||||
if (mSamples > 1 && gGLManager.mHasTextureMultisample)
|
||||
{
|
||||
mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE;
|
||||
//no support for multisampled stencil targets yet
|
||||
mStencil = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSamples = 0;
|
||||
}
|
||||
|
||||
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
|
|
@ -157,21 +141,6 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
stop_glerror();
|
||||
|
||||
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
if (mSamples > 1)
|
||||
{
|
||||
clear_glerror();
|
||||
glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
llwarns << "Could not allocate multisample color buffer for render target." << llendl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
#else
|
||||
llassert_always(mSamples <= 1);
|
||||
#endif
|
||||
{
|
||||
clear_glerror();
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
|
@ -182,32 +151,32 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
|||
}
|
||||
}
|
||||
|
||||
sBytesAllocated += mResX*mResY*4;
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (mSamples == 0)
|
||||
{
|
||||
if (offset == 0)
|
||||
{ //use bilinear filtering on single texture render targets that aren't multisampled
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{ //don't filter data attachments
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
if (offset == 0)
|
||||
{ //use bilinear filtering on single texture render targets that aren't multisampled
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{ //don't filter data attachments
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ATI doesn't support mirrored repeat for rectangular textures.
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
}
|
||||
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ATI doesn't support mirrored repeat for rectangular textures.
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
if (mFBO)
|
||||
|
|
@ -250,26 +219,16 @@ bool LLRenderTarget::allocateDepth()
|
|||
{
|
||||
LLImageGL::generateTextures(1, &mDepth);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
if (mSamples == 0)
|
||||
{
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
stop_glerror();
|
||||
clear_glerror();
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
|
||||
}
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
clear_glerror();
|
||||
glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE);
|
||||
}
|
||||
#else
|
||||
llassert_always(mSamples <= 1);
|
||||
#endif
|
||||
|
||||
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);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
}
|
||||
|
||||
sBytesAllocated += mResX*mResY*4;
|
||||
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
llwarns << "Unable to allocate depth buffer for render target." << llendl;
|
||||
|
|
@ -339,14 +298,16 @@ void LLRenderTarget::release()
|
|||
stop_glerror();
|
||||
}
|
||||
mDepth = 0;
|
||||
|
||||
sBytesAllocated -= mResX*mResY*4;
|
||||
}
|
||||
else if (mUseDepth && mFBO)
|
||||
{ //detach shared depth buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
if (mStencil)
|
||||
{ //attached as a renderbuffer
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
mStencil = false;
|
||||
}
|
||||
else
|
||||
|
|
@ -364,6 +325,7 @@ void LLRenderTarget::release()
|
|||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
sBytesAllocated -= mResX*mResY*4*mTex.size();
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
|
||||
mTex.clear();
|
||||
}
|
||||
|
|
@ -495,7 +457,8 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
|
|||
gGL.flush();
|
||||
if (!source.mFBO || !mFBO)
|
||||
{
|
||||
llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
|
||||
llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ class LLRenderTarget
|
|||
{
|
||||
public:
|
||||
//whether or not to use FBO implementation
|
||||
static BOOL sUseFBO;
|
||||
static bool sUseFBO;
|
||||
static U32 sBytesAllocated;
|
||||
|
||||
LLRenderTarget();
|
||||
~LLRenderTarget();
|
||||
|
|
@ -143,11 +144,10 @@ protected:
|
|||
std::vector<U32> mTex;
|
||||
U32 mFBO;
|
||||
U32 mDepth;
|
||||
BOOL mStencil;
|
||||
BOOL mUseDepth;
|
||||
BOOL mRenderDepth;
|
||||
bool mStencil;
|
||||
bool mUseDepth;
|
||||
bool mRenderDepth;
|
||||
LLTexUnit::eTextureType mUsage;
|
||||
U32 mSamples;
|
||||
|
||||
static LLRenderTarget* sBoundTarget;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -81,7 +81,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
// NOTE order of shader object attaching is VERY IMPORTANT!!!
|
||||
if (features->calculatesAtmospherics)
|
||||
{
|
||||
if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
|
||||
if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("windlight/atmosphericsVarsWaterV.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -167,7 +174,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
|
||||
if(features->calculatesAtmospherics)
|
||||
{
|
||||
if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
|
||||
if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("windlight/atmosphericsVarsWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -247,7 +261,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -286,7 +300,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -310,7 +324,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
}
|
||||
}
|
||||
else if (features->hasWaterFog)
|
||||
|
|
@ -342,7 +356,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -361,7 +375,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +415,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -425,7 +439,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -444,10 +458,26 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
|||
{
|
||||
return FALSE;
|
||||
}
|
||||
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
|
||||
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (features->mIndexedTextureChannels <= 1)
|
||||
{
|
||||
if (!shader->attachObject("objects/nonindexedTextureV.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!shader->attachObject("objects/indexedTextureV.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +513,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
|
||||
LL_INFOS("ShaderLoading") << log << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -544,23 +574,64 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
}
|
||||
|
||||
//we can't have any lines longer than 1024 characters
|
||||
//or any shaders longer than 1024 lines... deal - DaveP
|
||||
//or any shaders longer than 4096 lines... deal - DaveP
|
||||
GLcharARB buff[1024];
|
||||
GLcharARB* text[1024];
|
||||
GLcharARB* text[4096];
|
||||
GLuint count = 0;
|
||||
|
||||
if (gGLManager.mGLVersion < 2.1f)
|
||||
F32 version = gGLManager.mGLVersion;
|
||||
|
||||
//hack to never use GLSL > 1.20 on OSX
|
||||
#if LL_DARWIN
|
||||
version = llmin(version, 2.9f);
|
||||
#endif
|
||||
|
||||
if (version < 2.1f)
|
||||
{
|
||||
text[count++] = strdup("#version 110\n");
|
||||
text[count++] = strdup("#define ATTRIBUTE attribute\n");
|
||||
text[count++] = strdup("#define VARYING varying\n");
|
||||
}
|
||||
else if (gGLManager.mGLVersion < 3.f)
|
||||
else if (version < 3.3f)
|
||||
{
|
||||
//set version to 1.20
|
||||
text[count++] = strdup("#version 120\n");
|
||||
text[count++] = strdup("#define FXAA_GLSL_120 1\n");
|
||||
text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
|
||||
text[count++] = strdup("#define ATTRIBUTE attribute\n");
|
||||
text[count++] = strdup("#define VARYING varying\n");
|
||||
}
|
||||
else
|
||||
{ //set version to 1.30
|
||||
text[count++] = strdup("#version 130\n");
|
||||
{
|
||||
if (version < 4.f)
|
||||
{
|
||||
//set version to 1.30
|
||||
text[count++] = strdup("#version 130\n");
|
||||
}
|
||||
else
|
||||
{ //set version to 400
|
||||
text[count++] = strdup("#version 400\n");
|
||||
}
|
||||
|
||||
text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
|
||||
text[count++] = strdup("#define FXAA_GLSL_130 1\n");
|
||||
|
||||
text[count++] = strdup("#define ATTRIBUTE in\n");
|
||||
|
||||
if (type == GL_VERTEX_SHADER_ARB)
|
||||
{ //"varying" state is "out" in a vertex program, "in" in a fragment program
|
||||
// ("varying" is deprecated after version 1.20)
|
||||
text[count++] = strdup("#define VARYING out\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
text[count++] = strdup("#define VARYING in\n");
|
||||
}
|
||||
|
||||
//backwards compatibility with legacy texture lookup syntax
|
||||
text[count++] = strdup("#define textureCube texture\n");
|
||||
text[count++] = strdup("#define texture2DLod textureLod\n");
|
||||
text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
|
||||
}
|
||||
|
||||
//copy preprocessor definitions into buffer
|
||||
|
|
@ -584,7 +655,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
.
|
||||
uniform sampler2D texN;
|
||||
|
||||
varying float vary_texture_index;
|
||||
VARYING float vary_texture_index;
|
||||
|
||||
vec4 diffuseLookup(vec2 texcoord)
|
||||
{
|
||||
|
|
@ -610,7 +681,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
text[count++] = strdup(decl.c_str());
|
||||
}
|
||||
|
||||
text[count++] = strdup("varying float vary_texture_index;\n");
|
||||
if (texture_index_channels > 1)
|
||||
{
|
||||
text[count++] = strdup("VARYING float vary_texture_index;\n");
|
||||
}
|
||||
|
||||
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
|
||||
text[count++] = strdup("{\n");
|
||||
|
||||
|
|
@ -633,7 +708,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
}
|
||||
|
||||
text[count++] = strdup("\t}\n");
|
||||
text[count++] = strdup("\treturn vec4(0,0,0,0);\n");
|
||||
text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
|
||||
text[count++] = strdup("}\n");
|
||||
}
|
||||
else
|
||||
|
|
@ -656,13 +731,13 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
text[count++] = strdup(if_str.c_str());
|
||||
}
|
||||
|
||||
text[count++] = strdup("\treturn vec4(0,0,0,0);\n");
|
||||
text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
|
||||
text[count++] = strdup("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
//copy file into memory
|
||||
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) )
|
||||
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )
|
||||
{
|
||||
text[count++] = (GLcharARB *)strdup((char *)buff);
|
||||
}
|
||||
|
|
@ -717,14 +792,24 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
|
||||
dumpObjectLog(ret);
|
||||
|
||||
#if LL_WINDOWS
|
||||
std::stringstream ostr;
|
||||
//dump shader source for debugging
|
||||
for (GLuint i = 0; i < count; i++)
|
||||
{
|
||||
ostr << i << ": " << text[i];
|
||||
|
||||
if (i % 128 == 0)
|
||||
{ //dump every 128 lines
|
||||
|
||||
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
|
||||
ostr = std::stringstream();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
|
|
@ -773,28 +858,42 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
|
|||
LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL;
|
||||
}
|
||||
|
||||
// NOTE: Removing LL_DARWIN block as it doesn't seem to actually give the correct answer,
|
||||
// but want it for reference once I move it.
|
||||
#if 0
|
||||
// Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software
|
||||
// per Apple's suggestion
|
||||
glBegin(gGL.mMode);
|
||||
glEnd();
|
||||
#if LL_DARWIN
|
||||
|
||||
// Query whether the shader can or cannot run in hardware
|
||||
// http://developer.apple.com/qa/qa2007/qa1502.html
|
||||
long vertexGPUProcessing;
|
||||
CGLContextObj ctx = CGLGetCurrentContext();
|
||||
CGLGetParameter (ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing);
|
||||
long fragmentGPUProcessing;
|
||||
CGLGetParameter (ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
|
||||
if (!fragmentGPUProcessing || !vertexGPUProcessing)
|
||||
// For some reason this absolutely kills the frame rate when VBO's are enabled
|
||||
if (0)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
|
||||
success = GL_FALSE;
|
||||
suppress_errors = FALSE;
|
||||
// Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software
|
||||
// per Apple's suggestion
|
||||
LLGLSLShader::sNoFixedFunction = false;
|
||||
|
||||
glUseProgramObjectARB(obj);
|
||||
|
||||
gGL.begin(LLRender::TRIANGLES);
|
||||
gGL.vertex3f(0.0f, 0.0f, 0.0f);
|
||||
gGL.vertex3f(0.0f, 0.0f, 0.0f);
|
||||
gGL.vertex3f(0.0f, 0.0f, 0.0f);
|
||||
gGL.end();
|
||||
gGL.flush();
|
||||
|
||||
glUseProgramObjectARB(0);
|
||||
|
||||
LLGLSLShader::sNoFixedFunction = true;
|
||||
|
||||
// Query whether the shader can or cannot run in hardware
|
||||
// http://developer.apple.com/qa/qa2007/qa1502.html
|
||||
GLint vertexGPUProcessing, fragmentGPUProcessing;
|
||||
CGLContextObj ctx = CGLGetCurrentContext();
|
||||
CGLGetParameter(ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing);
|
||||
CGLGetParameter(ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
|
||||
if (!fragmentGPUProcessing || !vertexGPUProcessing)
|
||||
{
|
||||
LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
|
||||
success = GL_FALSE;
|
||||
suppress_errors = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
std::string log = get_object_log(obj);
|
||||
LLStringUtil::toLower(log);
|
||||
|
|
@ -832,3 +931,181 @@ BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
|
|||
return success;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLShaderMgr::initAttribsAndUniforms()
|
||||
{
|
||||
//MUST match order of enum in LLVertexBuffer.h
|
||||
mReservedAttribs.push_back("position");
|
||||
mReservedAttribs.push_back("normal");
|
||||
mReservedAttribs.push_back("texcoord0");
|
||||
mReservedAttribs.push_back("texcoord1");
|
||||
mReservedAttribs.push_back("texcoord2");
|
||||
mReservedAttribs.push_back("texcoord3");
|
||||
mReservedAttribs.push_back("diffuse_color");
|
||||
mReservedAttribs.push_back("emissive");
|
||||
mReservedAttribs.push_back("binormal");
|
||||
mReservedAttribs.push_back("weight");
|
||||
mReservedAttribs.push_back("weight4");
|
||||
mReservedAttribs.push_back("clothing");
|
||||
mReservedAttribs.push_back("texture_index");
|
||||
|
||||
//matrix state
|
||||
mReservedUniforms.push_back("modelview_matrix");
|
||||
mReservedUniforms.push_back("projection_matrix");
|
||||
mReservedUniforms.push_back("inv_proj");
|
||||
mReservedUniforms.push_back("modelview_projection_matrix");
|
||||
mReservedUniforms.push_back("normal_matrix");
|
||||
mReservedUniforms.push_back("texture_matrix0");
|
||||
mReservedUniforms.push_back("texture_matrix1");
|
||||
mReservedUniforms.push_back("texture_matrix2");
|
||||
mReservedUniforms.push_back("texture_matrix3");
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1);
|
||||
|
||||
mReservedUniforms.push_back("viewport");
|
||||
|
||||
mReservedUniforms.push_back("light_position");
|
||||
mReservedUniforms.push_back("light_direction");
|
||||
mReservedUniforms.push_back("light_attenuation");
|
||||
mReservedUniforms.push_back("light_diffuse");
|
||||
mReservedUniforms.push_back("light_ambient");
|
||||
mReservedUniforms.push_back("light_count");
|
||||
mReservedUniforms.push_back("light");
|
||||
mReservedUniforms.push_back("light_col");
|
||||
mReservedUniforms.push_back("far_z");
|
||||
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1);
|
||||
|
||||
|
||||
mReservedUniforms.push_back("proj_mat");
|
||||
mReservedUniforms.push_back("proj_near");
|
||||
mReservedUniforms.push_back("proj_p");
|
||||
mReservedUniforms.push_back("proj_n");
|
||||
mReservedUniforms.push_back("proj_origin");
|
||||
mReservedUniforms.push_back("proj_range");
|
||||
mReservedUniforms.push_back("proj_ambiance");
|
||||
mReservedUniforms.push_back("proj_shadow_idx");
|
||||
mReservedUniforms.push_back("shadow_fade");
|
||||
mReservedUniforms.push_back("proj_focus");
|
||||
mReservedUniforms.push_back("proj_lod");
|
||||
mReservedUniforms.push_back("proj_ambient_lod");
|
||||
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
|
||||
|
||||
mReservedUniforms.push_back("color");
|
||||
|
||||
mReservedUniforms.push_back("diffuseMap");
|
||||
mReservedUniforms.push_back("specularMap");
|
||||
mReservedUniforms.push_back("bumpMap");
|
||||
mReservedUniforms.push_back("environmentMap");
|
||||
mReservedUniforms.push_back("cloude_noise_texture");
|
||||
mReservedUniforms.push_back("fullbright");
|
||||
mReservedUniforms.push_back("lightnorm");
|
||||
mReservedUniforms.push_back("sunlight_color_copy");
|
||||
mReservedUniforms.push_back("ambient");
|
||||
mReservedUniforms.push_back("blue_horizon");
|
||||
mReservedUniforms.push_back("blue_density");
|
||||
mReservedUniforms.push_back("haze_horizon");
|
||||
mReservedUniforms.push_back("haze_density");
|
||||
mReservedUniforms.push_back("cloud_shadow");
|
||||
mReservedUniforms.push_back("density_multiplier");
|
||||
mReservedUniforms.push_back("distance_multiplier");
|
||||
mReservedUniforms.push_back("max_y");
|
||||
mReservedUniforms.push_back("glow");
|
||||
mReservedUniforms.push_back("cloud_color");
|
||||
mReservedUniforms.push_back("cloud_pos_density1");
|
||||
mReservedUniforms.push_back("cloud_pos_density2");
|
||||
mReservedUniforms.push_back("cloud_scale");
|
||||
mReservedUniforms.push_back("gamma");
|
||||
mReservedUniforms.push_back("scene_light_strength");
|
||||
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::SCENE_LIGHT_STRENGTH+1);
|
||||
|
||||
mReservedUniforms.push_back("center");
|
||||
mReservedUniforms.push_back("size");
|
||||
mReservedUniforms.push_back("falloff");
|
||||
|
||||
|
||||
mReservedUniforms.push_back("minLuminance");
|
||||
mReservedUniforms.push_back("maxExtractAlpha");
|
||||
mReservedUniforms.push_back("lumWeights");
|
||||
mReservedUniforms.push_back("warmthWeights");
|
||||
mReservedUniforms.push_back("warmthAmount");
|
||||
mReservedUniforms.push_back("glowStrength");
|
||||
mReservedUniforms.push_back("glowDelta");
|
||||
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_DELTA+1);
|
||||
|
||||
|
||||
mReservedUniforms.push_back("minimum_alpha");
|
||||
|
||||
mReservedUniforms.push_back("shadow_matrix");
|
||||
mReservedUniforms.push_back("env_mat");
|
||||
mReservedUniforms.push_back("shadow_clip");
|
||||
mReservedUniforms.push_back("sun_wash");
|
||||
mReservedUniforms.push_back("shadow_noise");
|
||||
mReservedUniforms.push_back("blur_size");
|
||||
mReservedUniforms.push_back("ssao_radius");
|
||||
mReservedUniforms.push_back("ssao_max_radius");
|
||||
mReservedUniforms.push_back("ssao_factor");
|
||||
mReservedUniforms.push_back("ssao_factor_inv");
|
||||
mReservedUniforms.push_back("ssao_effect_mat");
|
||||
mReservedUniforms.push_back("screen_res");
|
||||
mReservedUniforms.push_back("near_clip");
|
||||
mReservedUniforms.push_back("shadow_offset");
|
||||
mReservedUniforms.push_back("shadow_bias");
|
||||
mReservedUniforms.push_back("spot_shadow_bias");
|
||||
mReservedUniforms.push_back("spot_shadow_offset");
|
||||
mReservedUniforms.push_back("sun_dir");
|
||||
mReservedUniforms.push_back("shadow_res");
|
||||
mReservedUniforms.push_back("proj_shadow_res");
|
||||
mReservedUniforms.push_back("depth_cutoff");
|
||||
mReservedUniforms.push_back("norm_cutoff");
|
||||
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_NORM_CUTOFF+1);
|
||||
|
||||
mReservedUniforms.push_back("tc_scale");
|
||||
mReservedUniforms.push_back("rcp_screen_res");
|
||||
mReservedUniforms.push_back("rcp_frame_opt");
|
||||
mReservedUniforms.push_back("rcp_frame_opt2");
|
||||
|
||||
mReservedUniforms.push_back("focal_distance");
|
||||
mReservedUniforms.push_back("blur_constant");
|
||||
mReservedUniforms.push_back("tan_pixel_angle");
|
||||
mReservedUniforms.push_back("magnification");
|
||||
mReservedUniforms.push_back("max_cof");
|
||||
mReservedUniforms.push_back("res_scale");
|
||||
|
||||
mReservedUniforms.push_back("depthMap");
|
||||
mReservedUniforms.push_back("shadowMap0");
|
||||
mReservedUniforms.push_back("shadowMap1");
|
||||
mReservedUniforms.push_back("shadowMap2");
|
||||
mReservedUniforms.push_back("shadowMap3");
|
||||
mReservedUniforms.push_back("shadowMap4");
|
||||
mReservedUniforms.push_back("shadowMap5");
|
||||
|
||||
llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1);
|
||||
|
||||
mReservedUniforms.push_back("normalMap");
|
||||
mReservedUniforms.push_back("positionMap");
|
||||
mReservedUniforms.push_back("diffuseRect");
|
||||
mReservedUniforms.push_back("specularRect");
|
||||
mReservedUniforms.push_back("noiseMap");
|
||||
mReservedUniforms.push_back("lightFunc");
|
||||
mReservedUniforms.push_back("lightMap");
|
||||
mReservedUniforms.push_back("bloomMap");
|
||||
mReservedUniforms.push_back("projectionMap");
|
||||
|
||||
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
|
||||
|
||||
std::set<std::string> dupe_check;
|
||||
|
||||
for (U32 i = 0; i < mReservedUniforms.size(); ++i)
|
||||
{
|
||||
if (dupe_check.find(mReservedUniforms[i]) != dupe_check.end())
|
||||
{
|
||||
llerrs << "Duplicate reserved uniform name found: " << mReservedUniforms[i] << llendl;
|
||||
}
|
||||
dupe_check.insert(mReservedUniforms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,9 +36,137 @@ public:
|
|||
LLShaderMgr();
|
||||
virtual ~LLShaderMgr();
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MODELVIEW_MATRIX = 0,
|
||||
PROJECTION_MATRIX,
|
||||
INVERSE_PROJECTION_MATRIX,
|
||||
MODELVIEW_PROJECTION_MATRIX,
|
||||
NORMAL_MATRIX,
|
||||
TEXTURE_MATRIX0,
|
||||
TEXTURE_MATRIX1,
|
||||
TEXTURE_MATRIX2,
|
||||
TEXTURE_MATRIX3,
|
||||
VIEWPORT,
|
||||
LIGHT_POSITION,
|
||||
LIGHT_DIRECTION,
|
||||
LIGHT_ATTENUATION,
|
||||
LIGHT_DIFFUSE,
|
||||
LIGHT_AMBIENT,
|
||||
MULTI_LIGHT_COUNT,
|
||||
MULTI_LIGHT,
|
||||
MULTI_LIGHT_COL,
|
||||
MULTI_LIGHT_FAR_Z,
|
||||
PROJECTOR_MATRIX,
|
||||
PROJECTOR_NEAR,
|
||||
PROJECTOR_P,
|
||||
PROJECTOR_N,
|
||||
PROJECTOR_ORIGIN,
|
||||
PROJECTOR_RANGE,
|
||||
PROJECTOR_AMBIANCE,
|
||||
PROJECTOR_SHADOW_INDEX,
|
||||
PROJECTOR_SHADOW_FADE,
|
||||
PROJECTOR_FOCUS,
|
||||
PROJECTOR_LOD,
|
||||
PROJECTOR_AMBIENT_LOD,
|
||||
DIFFUSE_COLOR,
|
||||
DIFFUSE_MAP,
|
||||
SPECULAR_MAP,
|
||||
BUMP_MAP,
|
||||
ENVIRONMENT_MAP,
|
||||
CLOUD_NOISE_MAP,
|
||||
FULLBRIGHT,
|
||||
LIGHTNORM,
|
||||
SUNLIGHT_COLOR,
|
||||
AMBIENT,
|
||||
BLUE_HORIZON,
|
||||
BLUE_DENSITY,
|
||||
HAZE_HORIZON,
|
||||
HAZE_DENSITY,
|
||||
CLOUD_SHADOW,
|
||||
DENSITY_MULTIPLIER,
|
||||
DISTANCE_MULTIPLIER,
|
||||
MAX_Y,
|
||||
GLOW,
|
||||
CLOUD_COLOR,
|
||||
CLOUD_POS_DENSITY1,
|
||||
CLOUD_POS_DENSITY2,
|
||||
CLOUD_SCALE,
|
||||
GAMMA,
|
||||
SCENE_LIGHT_STRENGTH,
|
||||
LIGHT_CENTER,
|
||||
LIGHT_SIZE,
|
||||
LIGHT_FALLOFF,
|
||||
|
||||
GLOW_MIN_LUMINANCE,
|
||||
GLOW_MAX_EXTRACT_ALPHA,
|
||||
GLOW_LUM_WEIGHTS,
|
||||
GLOW_WARMTH_WEIGHTS,
|
||||
GLOW_WARMTH_AMOUNT,
|
||||
GLOW_STRENGTH,
|
||||
GLOW_DELTA,
|
||||
|
||||
MINIMUM_ALPHA,
|
||||
|
||||
DEFERRED_SHADOW_MATRIX,
|
||||
DEFERRED_ENV_MAT,
|
||||
DEFERRED_SHADOW_CLIP,
|
||||
DEFERRED_SUN_WASH,
|
||||
DEFERRED_SHADOW_NOISE,
|
||||
DEFERRED_BLUR_SIZE,
|
||||
DEFERRED_SSAO_RADIUS,
|
||||
DEFERRED_SSAO_MAX_RADIUS,
|
||||
DEFERRED_SSAO_FACTOR,
|
||||
DEFERRED_SSAO_FACTOR_INV,
|
||||
DEFERRED_SSAO_EFFECT_MAT,
|
||||
DEFERRED_SCREEN_RES,
|
||||
DEFERRED_NEAR_CLIP,
|
||||
DEFERRED_SHADOW_OFFSET,
|
||||
DEFERRED_SHADOW_BIAS,
|
||||
DEFERRED_SPOT_SHADOW_BIAS,
|
||||
DEFERRED_SPOT_SHADOW_OFFSET,
|
||||
DEFERRED_SUN_DIR,
|
||||
DEFERRED_SHADOW_RES,
|
||||
DEFERRED_PROJ_SHADOW_RES,
|
||||
DEFERRED_DEPTH_CUTOFF,
|
||||
DEFERRED_NORM_CUTOFF,
|
||||
|
||||
FXAA_TC_SCALE,
|
||||
FXAA_RCP_SCREEN_RES,
|
||||
FXAA_RCP_FRAME_OPT,
|
||||
FXAA_RCP_FRAME_OPT2,
|
||||
|
||||
DOF_FOCAL_DISTANCE,
|
||||
DOF_BLUR_CONSTANT,
|
||||
DOF_TAN_PIXEL_ANGLE,
|
||||
DOF_MAGNIFICATION,
|
||||
DOF_MAX_COF,
|
||||
DOF_RES_SCALE,
|
||||
|
||||
DEFERRED_DEPTH,
|
||||
DEFERRED_SHADOW0,
|
||||
DEFERRED_SHADOW1,
|
||||
DEFERRED_SHADOW2,
|
||||
DEFERRED_SHADOW3,
|
||||
DEFERRED_SHADOW4,
|
||||
DEFERRED_SHADOW5,
|
||||
DEFERRED_NORMAL,
|
||||
DEFERRED_POSITION,
|
||||
DEFERRED_DIFFUSE,
|
||||
DEFERRED_SPECULAR,
|
||||
DEFERRED_NOISE,
|
||||
DEFERRED_LIGHTFUNC,
|
||||
DEFERRED_LIGHT,
|
||||
DEFERRED_BLOOM,
|
||||
DEFERRED_PROJECTION,
|
||||
END_RESERVED_UNIFORMS
|
||||
} eGLSLReservedUniforms;
|
||||
|
||||
// singleton pattern implementation
|
||||
static LLShaderMgr * instance();
|
||||
|
||||
virtual void initAttribsAndUniforms(void);
|
||||
|
||||
BOOL attachShaderFeatures(LLGLSLShader * shader);
|
||||
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
|
||||
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -38,6 +38,8 @@
|
|||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#define LL_MAX_VERTEX_ATTRIB_LOCATION 64
|
||||
|
||||
//============================================================================
|
||||
// NOTES
|
||||
// Threading:
|
||||
|
|
@ -49,25 +51,32 @@
|
|||
|
||||
//============================================================================
|
||||
// gl name pools for dynamic and streaming buffers
|
||||
|
||||
class LLVBOPool : public LLGLNamePool
|
||||
class LLVBOPool
|
||||
{
|
||||
protected:
|
||||
virtual GLuint allocateName()
|
||||
{
|
||||
GLuint name;
|
||||
stop_glerror();
|
||||
glGenBuffersARB(1, &name);
|
||||
stop_glerror();
|
||||
return name;
|
||||
}
|
||||
public:
|
||||
static U32 sBytesPooled;
|
||||
|
||||
virtual void releaseName(GLuint name)
|
||||
U32 mUsage;
|
||||
U32 mType;
|
||||
|
||||
//size MUST be a power of 2
|
||||
U8* allocate(U32& name, U32 size);
|
||||
|
||||
//size MUST be the size provided to allocate that returned the given name
|
||||
void release(U32 name, U8* buffer, U32 size);
|
||||
|
||||
//destroy all records in mFreeList
|
||||
void cleanup();
|
||||
|
||||
class Record
|
||||
{
|
||||
stop_glerror();
|
||||
glDeleteBuffersARB(1, &name);
|
||||
stop_glerror();
|
||||
}
|
||||
public:
|
||||
U32 mGLName;
|
||||
U8* mClientData;
|
||||
};
|
||||
|
||||
typedef std::list<Record> record_list_t;
|
||||
std::vector<record_list_t> mFreeList;
|
||||
};
|
||||
|
||||
class LLGLFence
|
||||
|
|
@ -90,9 +99,7 @@ public:
|
|||
S32 mIndex;
|
||||
S32 mCount;
|
||||
|
||||
MappedRegion(S32 type, S32 index, S32 count)
|
||||
: mType(type), mIndex(index), mCount(count)
|
||||
{ }
|
||||
MappedRegion(S32 type, S32 index, S32 count);
|
||||
};
|
||||
|
||||
LLVertexBuffer(const LLVertexBuffer& rhs)
|
||||
|
|
@ -111,18 +118,17 @@ public:
|
|||
static LLVBOPool sStreamIBOPool;
|
||||
static LLVBOPool sDynamicIBOPool;
|
||||
|
||||
static S32 sWeight4Loc;
|
||||
|
||||
static BOOL sUseStreamDraw;
|
||||
static BOOL sUseVAO;
|
||||
static BOOL sPreferStreamDraw;
|
||||
|
||||
static void initClass(bool use_vbo, bool no_vbo_mapping);
|
||||
static void cleanupClass();
|
||||
static void setupClientArrays(U32 data_mask);
|
||||
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);
|
||||
|
||||
static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
|
||||
static void unbind(); //unbind any bound vertex buffer
|
||||
static void unbind(); //unbind any bound vertex buffer
|
||||
|
||||
//get the size of a vertex with the given typemask
|
||||
static S32 calcVertexSize(const U32& typemask);
|
||||
|
|
@ -133,24 +139,29 @@ public:
|
|||
static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
|
||||
|
||||
|
||||
//WARNING -- when updating these enums you MUST
|
||||
// 1 - update LLVertexBuffer::sTypeSize
|
||||
// 2 - add a strider accessor
|
||||
// 3 - modify LLVertexBuffer::setupVertexBuffer
|
||||
// 4 - modify LLVertexBuffer::setupClientArray
|
||||
// 5 - modify LLViewerShaderMgr::mReservedAttribs
|
||||
// 6 - update LLVertexBuffer::setupVertexArray
|
||||
enum {
|
||||
TYPE_VERTEX,
|
||||
TYPE_VERTEX = 0,
|
||||
TYPE_NORMAL,
|
||||
TYPE_TEXCOORD0,
|
||||
TYPE_TEXCOORD1,
|
||||
TYPE_TEXCOORD2,
|
||||
TYPE_TEXCOORD3,
|
||||
TYPE_COLOR,
|
||||
// These use VertexAttribPointer and should possibly be made generic
|
||||
TYPE_EMISSIVE,
|
||||
TYPE_BINORMAL,
|
||||
TYPE_WEIGHT,
|
||||
TYPE_WEIGHT4,
|
||||
TYPE_CLOTHWEIGHT,
|
||||
TYPE_MAX,
|
||||
TYPE_INDEX,
|
||||
|
||||
//no actual additional data, but indicates position.w is texture index
|
||||
TYPE_TEXTURE_INDEX,
|
||||
TYPE_MAX,
|
||||
TYPE_INDEX,
|
||||
};
|
||||
enum {
|
||||
MAP_VERTEX = (1<<TYPE_VERTEX),
|
||||
|
|
@ -160,6 +171,7 @@ public:
|
|||
MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
|
||||
MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
|
||||
MAP_COLOR = (1<<TYPE_COLOR),
|
||||
MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
|
||||
// These use VertexAttribPointer and should possibly be made generic
|
||||
MAP_BINORMAL = (1<<TYPE_BINORMAL),
|
||||
MAP_WEIGHT = (1<<TYPE_WEIGHT),
|
||||
|
|
@ -173,24 +185,25 @@ protected:
|
|||
|
||||
virtual ~LLVertexBuffer(); // use unref()
|
||||
|
||||
virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
|
||||
virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()
|
||||
void setupVertexArray();
|
||||
|
||||
void genBuffer();
|
||||
void genIndices();
|
||||
void genBuffer(U32 size);
|
||||
void genIndices(U32 size);
|
||||
bool bindGLBuffer(bool force_bind = false);
|
||||
bool bindGLIndices(bool force_bind = false);
|
||||
bool bindGLArray();
|
||||
void releaseBuffer();
|
||||
void releaseIndices();
|
||||
void createGLBuffer();
|
||||
void createGLIndices();
|
||||
void createGLBuffer(U32 size);
|
||||
void createGLIndices(U32 size);
|
||||
void destroyGLBuffer();
|
||||
void destroyGLIndices();
|
||||
void updateNumVerts(S32 nverts);
|
||||
void updateNumIndices(S32 nindices);
|
||||
virtual BOOL useVBOs() const;
|
||||
void unmapBuffer(S32 type);
|
||||
void freeClientBuffer() ;
|
||||
void allocateClientVertexBuffer() ;
|
||||
void allocateClientIndexBuffer() ;
|
||||
|
||||
void unmapBuffer();
|
||||
|
||||
public:
|
||||
LLVertexBuffer(U32 typemask, S32 usage);
|
||||
|
||||
|
|
@ -199,7 +212,8 @@ public:
|
|||
U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
|
||||
|
||||
// set for rendering
|
||||
virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0
|
||||
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
|
||||
void flush(); //flush pending data to GL memory
|
||||
// allocate buffer
|
||||
void allocateBuffer(S32 nverts, S32 nindices, bool create);
|
||||
virtual void resizeBuffer(S32 newnverts, S32 newnindices);
|
||||
|
|
@ -212,29 +226,30 @@ public:
|
|||
// setVertsNorms(verts, norms);
|
||||
// vb->unmapBuffer();
|
||||
bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getVertexStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
|
||||
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 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 isEmpty() const { return mEmpty; }
|
||||
BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
|
||||
S32 getNumVerts() const { return mNumVerts; }
|
||||
S32 getNumIndices() const { return mNumIndices; }
|
||||
S32 getRequestedVerts() const { return mRequestedNumVerts; }
|
||||
S32 getRequestedIndices() const { return mRequestedNumIndices; }
|
||||
|
||||
|
||||
U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
|
||||
U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
|
||||
U32 getTypeMask() const { return mTypeMask; }
|
||||
bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
|
||||
S32 getSize() const;
|
||||
S32 getIndicesSize() const { return mNumIndices * sizeof(U16); }
|
||||
S32 getIndicesSize() const { return mIndicesSize; }
|
||||
U8* getMappedData() const { return mMappedData; }
|
||||
U8* getMappedIndices() const { return mMappedIndexData; }
|
||||
S32 getOffset(S32 type) const { return mOffsets[type]; }
|
||||
|
|
@ -252,25 +267,23 @@ public:
|
|||
protected:
|
||||
S32 mNumVerts; // Number of vertices allocated
|
||||
S32 mNumIndices; // Number of indices allocated
|
||||
S32 mRequestedNumVerts; // Number of vertices requested
|
||||
S32 mRequestedNumIndices; // Number of indices requested
|
||||
|
||||
|
||||
ptrdiff_t mAlignedOffset;
|
||||
ptrdiff_t mAlignedIndexOffset;
|
||||
S32 mSize;
|
||||
S32 mIndicesSize;
|
||||
U32 mTypeMask;
|
||||
S32 mUsage; // GL usage
|
||||
U32 mGLBuffer; // GL VBO handle
|
||||
U32 mGLIndices; // GL IBO handle
|
||||
U32 mGLArray; // GL VAO handle
|
||||
|
||||
U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
|
||||
U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
|
||||
BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory
|
||||
BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory
|
||||
BOOL mFinal; // if TRUE, buffer can not be mapped again
|
||||
BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
|
||||
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
|
||||
BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not
|
||||
BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
|
||||
S32 mOffsets[TYPE_MAX];
|
||||
|
||||
std::vector<MappedRegion> mMappedVertexRegions;
|
||||
|
|
@ -290,7 +303,6 @@ public:
|
|||
static S32 sGLCount;
|
||||
static S32 sMappedCount;
|
||||
static BOOL sMapped;
|
||||
static std::vector<U32> sDeleteList;
|
||||
typedef std::list<LLVertexBuffer*> buffer_list_t;
|
||||
|
||||
static BOOL sDisableVBOMapping; //disable glMapBufferARB
|
||||
|
|
@ -298,6 +310,7 @@ public:
|
|||
static S32 sTypeSize[TYPE_MAX];
|
||||
static U32 sGLMode[LLRender::NUM_MODES];
|
||||
static U32 sGLRenderBuffer;
|
||||
static U32 sGLRenderArray;
|
||||
static U32 sGLRenderIndices;
|
||||
static BOOL sVBOActive;
|
||||
static BOOL sIBOActive;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ project(llui)
|
|||
include(00-Common)
|
||||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLInventory)
|
||||
include(LLMath)
|
||||
include(LLMessage)
|
||||
include(LLRender)
|
||||
|
|
@ -16,6 +17,7 @@ include(LLXUIXML)
|
|||
include_directories(
|
||||
${LLCOMMON_INCLUDE_DIRS}
|
||||
${LLIMAGE_INCLUDE_DIRS}
|
||||
${LLINVENTORY_INCLUDE_DIRS}
|
||||
${LLMATH_INCLUDE_DIRS}
|
||||
${LLMESSAGE_INCLUDE_DIRS}
|
||||
${LLRENDER_INCLUDE_DIRS}
|
||||
|
|
@ -35,6 +37,7 @@ set(llui_SOURCE_FILES
|
|||
llcheckboxctrl.cpp
|
||||
llclipboard.cpp
|
||||
llcombobox.cpp
|
||||
llcommandmanager.cpp
|
||||
llconsole.cpp
|
||||
llcontainerview.cpp
|
||||
llctrlselectioninterface.cpp
|
||||
|
|
@ -100,6 +103,7 @@ set(llui_SOURCE_FILES
|
|||
lltimectrl.cpp
|
||||
lltransutil.cpp
|
||||
lltoggleablemenu.cpp
|
||||
lltoolbar.cpp
|
||||
lltooltip.cpp
|
||||
llui.cpp
|
||||
lluicolortable.cpp
|
||||
|
|
@ -133,6 +137,7 @@ set(llui_HEADER_FILES
|
|||
llcheckboxctrl.h
|
||||
llclipboard.h
|
||||
llcombobox.h
|
||||
llcommandmanager.h
|
||||
llconsole.h
|
||||
llcontainerview.h
|
||||
llctrlselectioninterface.h
|
||||
|
|
@ -204,6 +209,7 @@ set(llui_HEADER_FILES
|
|||
lltextvalidate.h
|
||||
lltimectrl.h
|
||||
lltoggleablemenu.h
|
||||
lltoolbar.h
|
||||
lltooltip.h
|
||||
lltransutil.h
|
||||
lluicolortable.h
|
||||
|
|
@ -250,6 +256,7 @@ target_link_libraries(llui
|
|||
${LLRENDER_LIBRARIES}
|
||||
${LLWINDOW_LIBRARIES}
|
||||
${LLIMAGE_LIBRARIES}
|
||||
${LLINVENTORY_LIBRARIES}
|
||||
${LLVFS_LIBRARIES} # ugh, just for LLDir
|
||||
${LLXUIXML_LIBRARIES}
|
||||
${LLXML_LIBRARIES}
|
||||
|
|
|
|||
|
|
@ -973,7 +973,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
|
|||
|
||||
if ( root_rect.overlaps(screen_rect) && LLUI::sDirtyRect.overlaps(screen_rect))
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
LLUI::pushMatrix();
|
||||
{
|
||||
LLUI::translate((F32)child->getRect().mLeft, (F32)child->getRect().mBottom, 0.f);
|
||||
|
|
|
|||
|
|
@ -86,10 +86,11 @@ LLButton::Params::Params()
|
|||
label_color_selected("label_color_selected"), // requires is_toggle true
|
||||
label_color_disabled("label_color_disabled"),
|
||||
label_color_disabled_selected("label_color_disabled_selected"),
|
||||
highlight_color("highlight_color"),
|
||||
image_color("image_color"),
|
||||
image_color_disabled("image_color_disabled"),
|
||||
image_overlay_color("image_overlay_color", LLColor4::white),
|
||||
image_overlay_color("image_overlay_color", LLColor4::white % 0.75f),
|
||||
image_overlay_disabled_color("image_overlay_disabled_color", LLColor4::white % 0.3f),
|
||||
image_overlay_selected_color("image_overlay_selected_color", LLColor4::white),
|
||||
flash_color("flash_color"),
|
||||
pad_right("pad_right", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")),
|
||||
pad_left("pad_left", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")),
|
||||
|
|
@ -102,10 +103,13 @@ LLButton::Params::Params()
|
|||
scale_image("scale_image", true),
|
||||
hover_glow_amount("hover_glow_amount"),
|
||||
commit_on_return("commit_on_return", true),
|
||||
display_pressed_state("display_pressed_state", true),
|
||||
use_draw_context_alpha("use_draw_context_alpha", true),
|
||||
badge("badge"),
|
||||
handle_right_mouse("handle_right_mouse"),
|
||||
held_down_delay("held_down_delay")
|
||||
held_down_delay("held_down_delay"),
|
||||
button_flash_count("button_flash_count"),
|
||||
button_flash_rate("button_flash_rate")
|
||||
{
|
||||
addSynonym(is_toggle, "toggle");
|
||||
changeDefault(initial_value, LLSD(false));
|
||||
|
|
@ -114,7 +118,7 @@ LLButton::Params::Params()
|
|||
|
||||
LLButton::LLButton(const LLButton::Params& p)
|
||||
: LLUICtrl(p),
|
||||
LLBadgeOwner(LLView::getHandle()),
|
||||
LLBadgeOwner(getHandle()),
|
||||
mMouseDownFrame(0),
|
||||
mMouseHeldDownCount(0),
|
||||
mBorderEnabled( FALSE ),
|
||||
|
|
@ -139,12 +143,13 @@ LLButton::LLButton(const LLButton::Params& p)
|
|||
mSelectedLabelColor(p.label_color_selected()),
|
||||
mDisabledLabelColor(p.label_color_disabled()),
|
||||
mDisabledSelectedLabelColor(p.label_color_disabled_selected()),
|
||||
mHighlightColor(p.highlight_color()),
|
||||
mImageColor(p.image_color()),
|
||||
mFlashBgColor(p.flash_color()),
|
||||
mDisabledImageColor(p.image_color_disabled()),
|
||||
mImageOverlay(p.image_overlay()),
|
||||
mImageOverlayColor(p.image_overlay_color()),
|
||||
mImageOverlayDisabledColor(p.image_overlay_disabled_color()),
|
||||
mImageOverlaySelectedColor(p.image_overlay_selected_color()),
|
||||
mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)),
|
||||
mImageOverlayTopPad(p.image_top_pad),
|
||||
mImageOverlayBottomPad(p.image_bottom_pad),
|
||||
|
|
@ -162,12 +167,15 @@ LLButton::LLButton(const LLButton::Params& p)
|
|||
mCommitOnReturn(p.commit_on_return),
|
||||
mFadeWhenDisabled(FALSE),
|
||||
mForcePressedState(false),
|
||||
mDisplayPressedState(p.display_pressed_state),
|
||||
mLastDrawCharsCount(0),
|
||||
mMouseDownSignal(NULL),
|
||||
mMouseUpSignal(NULL),
|
||||
mHeldDownSignal(NULL),
|
||||
mUseDrawContextAlpha(p.use_draw_context_alpha),
|
||||
mHandleRightMouse(p.handle_right_mouse)
|
||||
mHandleRightMouse(p.handle_right_mouse),
|
||||
mButtonFlashCount(p.button_flash_count),
|
||||
mButtonFlashRate(p.button_flash_rate)
|
||||
{
|
||||
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
|
||||
static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
|
||||
|
|
@ -295,6 +303,24 @@ void LLButton::onCommit()
|
|||
LLUICtrl::onCommit();
|
||||
}
|
||||
|
||||
boost::signals2::connection LLButton::setClickedCallback(const CommitCallbackParam& cb)
|
||||
{
|
||||
return setClickedCallback(initCommitCallback(cb));
|
||||
}
|
||||
boost::signals2::connection LLButton::setMouseDownCallback(const CommitCallbackParam& cb)
|
||||
{
|
||||
return setMouseDownCallback(initCommitCallback(cb));
|
||||
}
|
||||
boost::signals2::connection LLButton::setMouseUpCallback(const CommitCallbackParam& cb)
|
||||
{
|
||||
return setMouseUpCallback(initCommitCallback(cb));
|
||||
}
|
||||
boost::signals2::connection LLButton::setHeldDownCallback(const CommitCallbackParam& cb)
|
||||
{
|
||||
return setHeldDownCallback(initCommitCallback(cb));
|
||||
}
|
||||
|
||||
|
||||
boost::signals2::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb )
|
||||
{
|
||||
if (!mCommitSignal) mCommitSignal = new commit_signal_t();
|
||||
|
|
@ -317,7 +343,7 @@ boost::signals2::connection LLButton::setHeldDownCallback( const commit_signal_t
|
|||
}
|
||||
|
||||
|
||||
// *TODO: Deprecate (for backwards compatability only)
|
||||
// *TODO: Deprecate (for backwards compatibility only)
|
||||
boost::signals2::connection LLButton::setClickedCallback( button_callback_t cb, void* data )
|
||||
{
|
||||
return setClickedCallback(boost::bind(cb, data));
|
||||
|
|
@ -514,15 +540,6 @@ BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void LLButton::onMouseEnter(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLUICtrl::onMouseEnter(x, y, mask);
|
||||
|
||||
if (isInEnabledChain())
|
||||
mNeedsHighlight = TRUE;
|
||||
}
|
||||
|
||||
void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLUICtrl::onMouseLeave(x, y, mask);
|
||||
|
|
@ -537,6 +554,10 @@ void LLButton::setHighlight(bool b)
|
|||
|
||||
BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if (isInEnabledChain()
|
||||
&& (!gFocusMgr.getMouseCapture() || gFocusMgr.getMouseCapture() == this))
|
||||
mNeedsHighlight = TRUE;
|
||||
|
||||
if (!childrenHandleHover(x, y, mask))
|
||||
{
|
||||
if (mMouseDownTimer.getStarted())
|
||||
|
|
@ -557,21 +578,37 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void LLButton::getOverlayImageSize(S32& overlay_width, S32& overlay_height)
|
||||
{
|
||||
overlay_width = mImageOverlay->getWidth();
|
||||
overlay_height = mImageOverlay->getHeight();
|
||||
|
||||
F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
|
||||
overlay_width = llround((F32)overlay_width * scale_factor);
|
||||
overlay_height = llround((F32)overlay_height * scale_factor);
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void LLButton::draw()
|
||||
{
|
||||
static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
|
||||
F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
|
||||
bool flash = FALSE;
|
||||
static LLUICachedControl<F32> button_flash_rate("ButtonFlashRate", 0);
|
||||
static LLUICachedControl<S32> button_flash_count("ButtonFlashCount", 0);
|
||||
|
||||
if( mFlashing )
|
||||
if( mFlashing)
|
||||
{
|
||||
F32 elapsed = mFlashingTimer.getElapsedTimeF32();
|
||||
S32 flash_count = S32(elapsed * button_flash_rate * 2.f);
|
||||
// flash on or off?
|
||||
flash = (flash_count % 2 == 0) || flash_count > S32((F32)button_flash_count * 2.f);
|
||||
if ( sEnableButtonFlashing)
|
||||
{
|
||||
F32 elapsed = mFlashingTimer.getElapsedTimeF32();
|
||||
S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
|
||||
// flash on or off?
|
||||
flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
|
||||
}
|
||||
else
|
||||
{ // otherwise just highlight button in flash color
|
||||
flash = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool pressed_by_keyboard = FALSE;
|
||||
|
|
@ -600,7 +637,7 @@ void LLButton::draw()
|
|||
LLColor4 glow_color = LLColor4::white;
|
||||
LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
|
||||
LLUIImage* imagep = NULL;
|
||||
if (pressed)
|
||||
if (pressed && mDisplayPressedState)
|
||||
{
|
||||
imagep = selected ? mImagePressedSelected : mImagePressed;
|
||||
}
|
||||
|
|
@ -710,16 +747,7 @@ void LLButton::draw()
|
|||
}
|
||||
|
||||
// Unselected label assignments
|
||||
LLWString label;
|
||||
|
||||
if( getToggleState() )
|
||||
{
|
||||
label = mSelectedLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
label = mUnselectedLabel;
|
||||
}
|
||||
LLWString label = getCurrentLabel();
|
||||
|
||||
// overlay with keyboard focus border
|
||||
if (hasFocus())
|
||||
|
|
@ -784,18 +812,16 @@ void LLButton::draw()
|
|||
if (mImageOverlay.notNull())
|
||||
{
|
||||
// get max width and height (discard level 0)
|
||||
S32 overlay_width = mImageOverlay->getWidth();
|
||||
S32 overlay_height = mImageOverlay->getHeight();
|
||||
S32 overlay_width;
|
||||
S32 overlay_height;
|
||||
|
||||
F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
|
||||
overlay_width = llround((F32)overlay_width * scale_factor);
|
||||
overlay_height = llround((F32)overlay_height * scale_factor);
|
||||
getOverlayImageSize(overlay_width, overlay_height);
|
||||
|
||||
S32 center_x = getLocalRect().getCenterX();
|
||||
S32 center_y = getLocalRect().getCenterY();
|
||||
|
||||
//FUGLY HACK FOR "DEPRESSED" BUTTONS
|
||||
if (pressed)
|
||||
if (pressed && mDisplayPressedState)
|
||||
{
|
||||
center_y--;
|
||||
center_x++;
|
||||
|
|
@ -806,7 +832,11 @@ void LLButton::draw()
|
|||
LLColor4 overlay_color = mImageOverlayColor.get();
|
||||
if (!enabled)
|
||||
{
|
||||
overlay_color.mV[VALPHA] = 0.5f;
|
||||
overlay_color = mImageOverlayDisabledColor.get();
|
||||
}
|
||||
else if (getToggleState())
|
||||
{
|
||||
overlay_color = mImageOverlaySelectedColor.get();
|
||||
}
|
||||
overlay_color.mV[VALPHA] *= alpha;
|
||||
|
||||
|
|
@ -814,6 +844,7 @@ void LLButton::draw()
|
|||
{
|
||||
case LLFontGL::LEFT:
|
||||
text_left += overlay_width + mImgOverlayLabelSpace;
|
||||
text_width -= overlay_width + mImgOverlayLabelSpace;
|
||||
mImageOverlay->draw(
|
||||
mLeftHPad,
|
||||
center_y - (overlay_height / 2),
|
||||
|
|
@ -831,6 +862,7 @@ void LLButton::draw()
|
|||
break;
|
||||
case LLFontGL::RIGHT:
|
||||
text_right -= overlay_width + mImgOverlayLabelSpace;
|
||||
text_width -= overlay_width + mImgOverlayLabelSpace;
|
||||
mImageOverlay->draw(
|
||||
getRect().getWidth() - mRightHPad - overlay_width,
|
||||
center_y - (overlay_height / 2),
|
||||
|
|
@ -866,7 +898,7 @@ void LLButton::draw()
|
|||
|
||||
S32 y_offset = 2 + (getRect().getHeight() - 20)/2;
|
||||
|
||||
if (pressed)
|
||||
if (pressed && mDisplayPressedState)
|
||||
{
|
||||
y_offset--;
|
||||
x++;
|
||||
|
|
@ -922,7 +954,7 @@ void LLButton::setToggleState(BOOL b)
|
|||
|
||||
void LLButton::setFlashing( BOOL b )
|
||||
{
|
||||
if (b != mFlashing)
|
||||
if ((bool)b != mFlashing)
|
||||
{
|
||||
mFlashing = b;
|
||||
mFlashingTimer.reset();
|
||||
|
|
@ -962,6 +994,23 @@ void LLButton::setLabelSelected( const LLStringExplicit& label )
|
|||
mSelectedLabel = label;
|
||||
}
|
||||
|
||||
bool LLButton::labelIsTruncated() const
|
||||
{
|
||||
return getCurrentLabel().getString().size() > mLastDrawCharsCount;
|
||||
}
|
||||
|
||||
const LLUIString& LLButton::getCurrentLabel() const
|
||||
{
|
||||
if( getToggleState() )
|
||||
{
|
||||
return mSelectedLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mUnselectedLabel;
|
||||
}
|
||||
}
|
||||
|
||||
void LLButton::setImageUnselected(LLPointer<LLUIImage> image)
|
||||
{
|
||||
mImageUnselected = image;
|
||||
|
|
@ -973,16 +1022,7 @@ void LLButton::setImageUnselected(LLPointer<LLUIImage> image)
|
|||
|
||||
void LLButton::autoResize()
|
||||
{
|
||||
LLUIString label;
|
||||
if(getToggleState())
|
||||
{
|
||||
label = mSelectedLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
label = mUnselectedLabel;
|
||||
}
|
||||
resize(label);
|
||||
resize(getCurrentLabel());
|
||||
}
|
||||
|
||||
void LLButton::resize(LLUIString label)
|
||||
|
|
@ -992,11 +1032,32 @@ void LLButton::resize(LLUIString label)
|
|||
// get current btn length
|
||||
S32 btn_width =getRect().getWidth();
|
||||
// check if it need resize
|
||||
if (mAutoResize == TRUE)
|
||||
if (mAutoResize)
|
||||
{
|
||||
if (btn_width - (mRightHPad + mLeftHPad) < label_width)
|
||||
S32 min_width = label_width + mLeftHPad + mRightHPad;
|
||||
if (mImageOverlay)
|
||||
{
|
||||
setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mLeft + label_width + mLeftHPad + mRightHPad , getRect().mBottom));
|
||||
S32 overlay_width = mImageOverlay->getWidth();
|
||||
F32 scale_factor = (getRect().getHeight() - (mImageOverlayBottomPad + mImageOverlayTopPad)) / (F32)mImageOverlay->getHeight();
|
||||
overlay_width = llround((F32)overlay_width * scale_factor);
|
||||
|
||||
switch(mImageOverlayAlignment)
|
||||
{
|
||||
case LLFontGL::LEFT:
|
||||
case LLFontGL::RIGHT:
|
||||
min_width += overlay_width + mImgOverlayLabelSpace;
|
||||
break;
|
||||
case LLFontGL::HCENTER:
|
||||
min_width = llmax(min_width, overlay_width + mLeftHPad + mRightHPad);
|
||||
break;
|
||||
default:
|
||||
// draw nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (btn_width < min_width)
|
||||
{
|
||||
reshape(min_width, getRect().getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1143,7 +1204,7 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
|
|||
// Set the button control value (toggle state) to the floater visibility control (Sets the value as well)
|
||||
button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
|
||||
// Set the clicked callback to toggle the floater
|
||||
button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
|
||||
button->setClickedCallback(boost::bind(&LLFloaterReg::toggleInstance, sdname, LLSD()));
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1184,7 +1245,6 @@ void LLButton::resetMouseDownTimer()
|
|||
mMouseDownTimer.reset();
|
||||
}
|
||||
|
||||
|
||||
BOOL LLButton::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
// just treat a double click as a second click
|
||||
|
|
|
|||
|
|
@ -94,10 +94,11 @@ public:
|
|||
label_color_selected,
|
||||
label_color_disabled,
|
||||
label_color_disabled_selected,
|
||||
highlight_color,
|
||||
image_color,
|
||||
image_color_disabled,
|
||||
image_overlay_color,
|
||||
image_overlay_selected_color,
|
||||
image_overlay_disabled_color,
|
||||
flash_color;
|
||||
|
||||
// layout
|
||||
|
|
@ -123,7 +124,8 @@ public:
|
|||
// misc
|
||||
Optional<bool> is_toggle,
|
||||
scale_image,
|
||||
commit_on_return;
|
||||
commit_on_return,
|
||||
display_pressed_state;
|
||||
|
||||
Optional<F32> hover_glow_amount;
|
||||
Optional<TimeIntervalParam> held_down_delay;
|
||||
|
|
@ -134,6 +136,9 @@ public:
|
|||
|
||||
Optional<bool> handle_right_mouse;
|
||||
|
||||
Optional<S32> button_flash_count;
|
||||
Optional<F32> button_flash_rate;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
|
|
@ -160,7 +165,6 @@ public:
|
|||
virtual void draw();
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
virtual void onMouseCaptureLost();
|
||||
|
||||
|
|
@ -171,6 +175,11 @@ public:
|
|||
void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; }
|
||||
|
||||
|
||||
boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb);
|
||||
boost::signals2::connection setMouseDownCallback(const CommitCallbackParam& cb);
|
||||
boost::signals2::connection setMouseUpCallback(const CommitCallbackParam& cb);
|
||||
boost::signals2::connection setHeldDownCallback(const CommitCallbackParam& cb);
|
||||
|
||||
boost::signals2::connection setClickedCallback( const commit_signal_t::slot_type& cb ); // mouse down and up within button
|
||||
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb );
|
||||
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ); // mouse up, EVEN IF NOT IN BUTTON
|
||||
|
|
@ -238,6 +247,8 @@ public:
|
|||
|
||||
|
||||
S32 getLastDrawCharsCount() const { return mLastDrawCharsCount; }
|
||||
bool labelIsTruncated() const;
|
||||
const LLUIString& getCurrentLabel() const;
|
||||
|
||||
void setScaleImage(BOOL scale) { mScaleImage = scale; }
|
||||
BOOL getScaleImage() const { return mScaleImage; }
|
||||
|
|
@ -273,14 +284,16 @@ public:
|
|||
protected:
|
||||
LLPointer<LLUIImage> getImageUnselected() const { return mImageUnselected; }
|
||||
LLPointer<LLUIImage> getImageSelected() const { return mImageSelected; }
|
||||
void getOverlayImageSize(S32& overlay_width, S32& overlay_height);
|
||||
|
||||
LLFrameTimer mMouseDownTimer;
|
||||
bool mNeedsHighlight;
|
||||
S32 mButtonFlashCount;
|
||||
F32 mButtonFlashRate;
|
||||
|
||||
private:
|
||||
void drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size);
|
||||
void resetMouseDownTimer();
|
||||
|
||||
private:
|
||||
commit_signal_t* mMouseDownSignal;
|
||||
commit_signal_t* mMouseUpSignal;
|
||||
commit_signal_t* mHeldDownSignal;
|
||||
|
|
@ -296,6 +309,8 @@ private:
|
|||
LLPointer<LLUIImage> mImageOverlay;
|
||||
LLFontGL::HAlign mImageOverlayAlignment;
|
||||
LLUIColor mImageOverlayColor;
|
||||
LLUIColor mImageOverlaySelectedColor;
|
||||
LLUIColor mImageOverlayDisabledColor;
|
||||
|
||||
LLPointer<LLUIImage> mImageUnselected;
|
||||
LLUIString mUnselectedLabel;
|
||||
|
|
@ -324,21 +339,19 @@ private:
|
|||
flash icon name is set in attributes(by default it isn't). First way is used otherwise. */
|
||||
LLPointer<LLUIImage> mImageFlash;
|
||||
|
||||
LLUIColor mHighlightColor;
|
||||
LLUIColor mFlashBgColor;
|
||||
|
||||
LLUIColor mImageColor;
|
||||
LLUIColor mDisabledImageColor;
|
||||
|
||||
BOOL mIsToggle;
|
||||
BOOL mScaleImage;
|
||||
bool mIsToggle;
|
||||
bool mScaleImage;
|
||||
|
||||
BOOL mDropShadowedText;
|
||||
BOOL mAutoResize;
|
||||
BOOL mUseEllipses;
|
||||
BOOL mBorderEnabled;
|
||||
|
||||
BOOL mFlashing;
|
||||
bool mDropShadowedText;
|
||||
bool mAutoResize;
|
||||
bool mUseEllipses;
|
||||
bool mBorderEnabled;
|
||||
bool mFlashing;
|
||||
|
||||
LLFontGL::HAlign mHAlign;
|
||||
S32 mLeftHPad;
|
||||
|
|
@ -358,10 +371,10 @@ private:
|
|||
F32 mHoverGlowStrength;
|
||||
F32 mCurGlowStrength;
|
||||
|
||||
BOOL mNeedsHighlight;
|
||||
BOOL mCommitOnReturn;
|
||||
BOOL mFadeWhenDisabled;
|
||||
bool mCommitOnReturn;
|
||||
bool mFadeWhenDisabled;
|
||||
bool mForcePressedState;
|
||||
bool mDisplayPressedState;
|
||||
|
||||
LLFrameTimer mFlashingTimer;
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ LLClipboard gClipboard;
|
|||
|
||||
LLClipboard::LLClipboard()
|
||||
{
|
||||
mSourceItem = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -134,3 +135,8 @@ BOOL LLClipboard::canPastePrimaryString() const
|
|||
{
|
||||
return LLView::getWindow()->isPrimaryTextAvailable();
|
||||
}
|
||||
|
||||
void LLClipboard::setSourceObject(const LLUUID& source_id, LLAssetType::EType type)
|
||||
{
|
||||
mSourceItem = new LLInventoryObject (source_id, LLUUID::null, type, "");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "llstring.h"
|
||||
#include "lluuid.h"
|
||||
#include "stdenums.h"
|
||||
#include "llinventory.h"
|
||||
|
||||
|
||||
class LLClipboard
|
||||
|
|
@ -52,9 +54,14 @@ public:
|
|||
BOOL canPastePrimaryString() const;
|
||||
const LLWString& getPastePrimaryWString(LLUUID* source_id = NULL);
|
||||
|
||||
// Support clipboard for object known only by their uuid and asset type
|
||||
void setSourceObject(const LLUUID& source_id, LLAssetType::EType type);
|
||||
const LLInventoryObject* getSourceObject() { return mSourceItem; }
|
||||
|
||||
private:
|
||||
LLUUID mSourceID;
|
||||
LLUUID mSourceID;
|
||||
LLWString mString;
|
||||
LLInventoryObject* mSourceItem;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,172 @@
|
|||
/**
|
||||
* @file llcommandmanager.cpp
|
||||
* @brief LLCommandManager class
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&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$
|
||||
*/
|
||||
|
||||
// A control that displays the name of the chosen item, which when
|
||||
// clicked shows a scrolling box of options.
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llcommandmanager.h"
|
||||
#include "lldir.h"
|
||||
#include "llerror.h"
|
||||
#include "llxuiparser.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
||||
//
|
||||
// LLCommandId class
|
||||
//
|
||||
|
||||
const LLCommandId LLCommandId::null = LLCommandId("null command");
|
||||
|
||||
//
|
||||
// LLCommand class
|
||||
//
|
||||
|
||||
LLCommand::Params::Params()
|
||||
: available_in_toybox("available_in_toybox", false)
|
||||
, icon("icon")
|
||||
, label_ref("label_ref")
|
||||
, name("name")
|
||||
, tooltip_ref("tooltip_ref")
|
||||
, execute_function("execute_function")
|
||||
, execute_parameters("execute_parameters")
|
||||
, execute_stop_function("execute_stop_function")
|
||||
, execute_stop_parameters("execute_stop_parameters")
|
||||
, is_enabled_function("is_enabled_function")
|
||||
, is_enabled_parameters("is_enabled_parameters")
|
||||
, is_running_function("is_running_function")
|
||||
, is_running_parameters("is_running_parameters")
|
||||
, is_starting_function("is_starting_function")
|
||||
, is_starting_parameters("is_starting_parameters")
|
||||
{
|
||||
}
|
||||
|
||||
LLCommand::LLCommand(const LLCommand::Params& p)
|
||||
: mIdentifier(p.name)
|
||||
, mAvailableInToybox(p.available_in_toybox)
|
||||
, mIcon(p.icon)
|
||||
, mLabelRef(p.label_ref)
|
||||
, mName(p.name)
|
||||
, mTooltipRef(p.tooltip_ref)
|
||||
, mExecuteFunction(p.execute_function)
|
||||
, mExecuteParameters(p.execute_parameters)
|
||||
, mExecuteStopFunction(p.execute_stop_function)
|
||||
, mExecuteStopParameters(p.execute_stop_parameters)
|
||||
, mIsEnabledFunction(p.is_enabled_function)
|
||||
, mIsEnabledParameters(p.is_enabled_parameters)
|
||||
, mIsRunningFunction(p.is_running_function)
|
||||
, mIsRunningParameters(p.is_running_parameters)
|
||||
, mIsStartingFunction(p.is_starting_function)
|
||||
, mIsStartingParameters(p.is_starting_parameters)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LLCommandManager class
|
||||
//
|
||||
|
||||
LLCommandManager::LLCommandManager()
|
||||
{
|
||||
}
|
||||
|
||||
LLCommandManager::~LLCommandManager()
|
||||
{
|
||||
for (CommandVector::iterator cmdIt = mCommands.begin(); cmdIt != mCommands.end(); ++cmdIt)
|
||||
{
|
||||
LLCommand * command = *cmdIt;
|
||||
|
||||
delete command;
|
||||
}
|
||||
}
|
||||
|
||||
U32 LLCommandManager::commandCount() const
|
||||
{
|
||||
return mCommands.size();
|
||||
}
|
||||
|
||||
LLCommand * LLCommandManager::getCommand(U32 commandIndex)
|
||||
{
|
||||
return mCommands[commandIndex];
|
||||
}
|
||||
|
||||
LLCommand * LLCommandManager::getCommand(const LLCommandId& commandId)
|
||||
{
|
||||
LLCommand * command_match = NULL;
|
||||
|
||||
CommandIndexMap::const_iterator found = mCommandIndices.find(commandId.uuid());
|
||||
|
||||
if (found != mCommandIndices.end())
|
||||
{
|
||||
command_match = mCommands[found->second];
|
||||
}
|
||||
|
||||
return command_match;
|
||||
}
|
||||
|
||||
void LLCommandManager::addCommand(LLCommand * command)
|
||||
{
|
||||
LLCommandId command_id = command->id();
|
||||
mCommandIndices[command_id.uuid()] = mCommands.size();
|
||||
mCommands.push_back(command);
|
||||
|
||||
lldebugs << "Successfully added command: " << command->name() << llendl;
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLCommandManager::load()
|
||||
{
|
||||
LLCommandManager& mgr = LLCommandManager::instance();
|
||||
|
||||
std::string commands_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "commands.xml");
|
||||
|
||||
LLCommandManager::Params commandsParams;
|
||||
|
||||
LLSimpleXUIParser parser;
|
||||
|
||||
if (!parser.readXUI(commands_file, commandsParams))
|
||||
{
|
||||
llerrs << "Unable to load xml file: " << commands_file << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!commandsParams.validateBlock())
|
||||
{
|
||||
llerrs << "Invalid commands file: " << commands_file << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(LLCommand::Params& commandParams, commandsParams.commands)
|
||||
{
|
||||
LLCommand * command = new LLCommand(commandParams);
|
||||
|
||||
mgr.addCommand(command);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
/**
|
||||
* @file llcommandmanager.h
|
||||
* @brief LLCommandManager class to hold commands
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLCOMMANDMANAGER_H
|
||||
#define LL_LLCOMMANDMANAGER_H
|
||||
|
||||
#include "llinitparam.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
|
||||
class LLCommand;
|
||||
class LLCommandManager;
|
||||
|
||||
|
||||
class LLCommandId
|
||||
{
|
||||
public:
|
||||
friend class LLCommand;
|
||||
friend class LLCommandManager;
|
||||
|
||||
struct Params : public LLInitParam::Block<Params>
|
||||
{
|
||||
Mandatory<std::string> name;
|
||||
|
||||
Params()
|
||||
: name("name")
|
||||
{}
|
||||
};
|
||||
|
||||
LLCommandId(const std::string& name)
|
||||
{
|
||||
mUUID = LLUUID::generateNewID(name);
|
||||
}
|
||||
|
||||
LLCommandId(const Params& p)
|
||||
{
|
||||
mUUID = LLUUID::generateNewID(p.name);
|
||||
}
|
||||
|
||||
LLCommandId(const LLUUID& uuid)
|
||||
: mUUID(uuid)
|
||||
{}
|
||||
|
||||
const LLUUID& uuid() const { return mUUID; }
|
||||
|
||||
bool operator!=(const LLCommandId& command) const
|
||||
{
|
||||
return (mUUID != command.mUUID);
|
||||
}
|
||||
|
||||
bool operator==(const LLCommandId& command) const
|
||||
{
|
||||
return (mUUID == command.mUUID);
|
||||
}
|
||||
|
||||
static const LLCommandId null;
|
||||
|
||||
private:
|
||||
LLUUID mUUID;
|
||||
};
|
||||
|
||||
typedef std::list<LLCommandId> command_id_list_t;
|
||||
|
||||
|
||||
class LLCommand
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params>
|
||||
{
|
||||
Mandatory<bool> available_in_toybox;
|
||||
Mandatory<std::string> icon;
|
||||
Mandatory<std::string> label_ref;
|
||||
Mandatory<std::string> name;
|
||||
Mandatory<std::string> tooltip_ref;
|
||||
|
||||
Mandatory<std::string> execute_function;
|
||||
Optional<LLSD> execute_parameters;
|
||||
|
||||
Optional<std::string> execute_stop_function;
|
||||
Optional<LLSD> execute_stop_parameters;
|
||||
|
||||
Optional<std::string> is_enabled_function;
|
||||
Optional<LLSD> is_enabled_parameters;
|
||||
|
||||
Optional<std::string> is_running_function;
|
||||
Optional<LLSD> is_running_parameters;
|
||||
|
||||
Optional<std::string> is_starting_function;
|
||||
Optional<LLSD> is_starting_parameters;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
LLCommand(const LLCommand::Params& p);
|
||||
|
||||
const bool availableInToybox() const { return mAvailableInToybox; }
|
||||
const std::string& icon() const { return mIcon; }
|
||||
const LLCommandId& id() const { return mIdentifier; }
|
||||
const std::string& labelRef() const { return mLabelRef; }
|
||||
const std::string& name() const { return mName; }
|
||||
const std::string& tooltipRef() const { return mTooltipRef; }
|
||||
|
||||
const std::string& executeFunctionName() const { return mExecuteFunction; }
|
||||
const LLSD& executeParameters() const { return mExecuteParameters; }
|
||||
|
||||
const std::string& executeStopFunctionName() const { return mExecuteStopFunction; }
|
||||
const LLSD& executeStopParameters() const { return mExecuteStopParameters; }
|
||||
|
||||
const std::string& isEnabledFunctionName() const { return mIsEnabledFunction; }
|
||||
const LLSD& isEnabledParameters() const { return mIsEnabledParameters; }
|
||||
|
||||
const std::string& isRunningFunctionName() const { return mIsRunningFunction; }
|
||||
const LLSD& isRunningParameters() const { return mIsRunningParameters; }
|
||||
|
||||
const std::string& isStartingFunctionName() const { return mIsStartingFunction; }
|
||||
const LLSD& isStartingParameters() const { return mIsStartingParameters; }
|
||||
|
||||
private:
|
||||
LLCommandId mIdentifier;
|
||||
|
||||
bool mAvailableInToybox;
|
||||
std::string mIcon;
|
||||
std::string mLabelRef;
|
||||
std::string mName;
|
||||
std::string mTooltipRef;
|
||||
|
||||
std::string mExecuteFunction;
|
||||
LLSD mExecuteParameters;
|
||||
|
||||
std::string mExecuteStopFunction;
|
||||
LLSD mExecuteStopParameters;
|
||||
|
||||
std::string mIsEnabledFunction;
|
||||
LLSD mIsEnabledParameters;
|
||||
|
||||
std::string mIsRunningFunction;
|
||||
LLSD mIsRunningParameters;
|
||||
|
||||
std::string mIsStartingFunction;
|
||||
LLSD mIsStartingParameters;
|
||||
};
|
||||
|
||||
|
||||
class LLCommandManager
|
||||
: public LLSingleton<LLCommandManager>
|
||||
{
|
||||
public:
|
||||
struct Params : public LLInitParam::Block<Params>
|
||||
{
|
||||
Multiple< LLCommand::Params, AtLeast<1> > commands;
|
||||
|
||||
Params()
|
||||
: commands("command")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
LLCommandManager();
|
||||
~LLCommandManager();
|
||||
|
||||
U32 commandCount() const;
|
||||
LLCommand * getCommand(U32 commandIndex);
|
||||
LLCommand * getCommand(const LLCommandId& commandId);
|
||||
|
||||
static bool load();
|
||||
|
||||
protected:
|
||||
void addCommand(LLCommand * command);
|
||||
|
||||
private:
|
||||
typedef std::map<LLUUID, U32> CommandIndexMap;
|
||||
typedef std::vector<LLCommand *> CommandVector;
|
||||
|
||||
CommandVector mCommands;
|
||||
CommandIndexMap mCommandIndices;
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_LLCOMMANDMANAGER_H
|
||||
|
|
@ -82,7 +82,7 @@ BOOL LLDockableFloater::postBuild()
|
|||
mForceDocking = true;
|
||||
}
|
||||
|
||||
mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
|
||||
mDockTongue = LLUI::getUIImage("Flyout_Pointer");
|
||||
LLFloater::setDocked(true);
|
||||
return LLView::postBuild();
|
||||
}
|
||||
|
|
@ -162,10 +162,15 @@ void LLDockableFloater::setVisible(BOOL visible)
|
|||
|
||||
void LLDockableFloater::setMinimized(BOOL minimize)
|
||||
{
|
||||
if(minimize)
|
||||
if(minimize && isDocked())
|
||||
{
|
||||
// minimizing a docked floater just hides it
|
||||
setVisible(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFloater::setMinimized(minimize);
|
||||
}
|
||||
}
|
||||
|
||||
LLView * LLDockableFloater::getDockWidget()
|
||||
|
|
@ -234,8 +239,21 @@ void LLDockableFloater::setDockControl(LLDockControl* dockControl)
|
|||
setDocked(isDocked());
|
||||
}
|
||||
|
||||
const LLUIImagePtr& LLDockableFloater::getDockTongue()
|
||||
const LLUIImagePtr& LLDockableFloater::getDockTongue(LLDockControl::DocAt dock_side)
|
||||
{
|
||||
switch(dock_side)
|
||||
{
|
||||
case LLDockControl::LEFT:
|
||||
mDockTongue = LLUI::getUIImage("Flyout_Left");
|
||||
break;
|
||||
case LLDockControl::RIGHT:
|
||||
mDockTongue = LLUI::getUIImage("Flyout_Right");
|
||||
break;
|
||||
default:
|
||||
mDockTongue = LLUI::getUIImage("Flyout_Pointer");
|
||||
break;
|
||||
}
|
||||
|
||||
return mDockTongue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@ public:
|
|||
|
||||
bool getUniqueDocking() { return mUniqueDocking; }
|
||||
bool getUseTongue() { return mUseTongue; }
|
||||
|
||||
void setUseTongue(bool use_tongue) { mUseTongue = use_tongue;}
|
||||
private:
|
||||
/**
|
||||
* Provides unique of dockable floater.
|
||||
|
|
@ -122,7 +124,7 @@ private:
|
|||
|
||||
protected:
|
||||
void setDockControl(LLDockControl* dockControl);
|
||||
const LLUIImagePtr& getDockTongue();
|
||||
const LLUIImagePtr& getDockTongue(LLDockControl::DocAt dock_side = LLDockControl::TOP);
|
||||
|
||||
// Checks if docking should be forced.
|
||||
// It may be useful e.g. if floater created in mouselook mode (see EXT-5609)
|
||||
|
|
|
|||
|
|
@ -92,19 +92,24 @@ void LLDockControl::setDock(LLView* dockWidget)
|
|||
|
||||
void LLDockControl::getAllowedRect(LLRect& rect)
|
||||
{
|
||||
rect = mDockableFloater->getRootView()->getRect();
|
||||
rect = mDockableFloater->getRootView()->getChild<LLView>("non_toolbar_panel")->getRect();
|
||||
}
|
||||
|
||||
void LLDockControl::repositionDockable()
|
||||
{
|
||||
if (!mDockWidget) return;
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
LLRect floater_rect = mDockableFloater->calcScreenRect();
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
|
||||
// recalculate dockable position if dock position changed, dock visibility changed,
|
||||
// root view rect changed or recalculation is forced
|
||||
if (mPrevDockRect != dockRect || mDockWidgetVisible != isDockVisible()
|
||||
|| mRootRect != rootRect || mRecalculateDocablePosition)
|
||||
// recalculate dockable position if:
|
||||
if (mPrevDockRect != dockRect //dock position changed
|
||||
|| mDockWidgetVisible != isDockVisible() //dock visibility changed
|
||||
|| mRootRect != rootRect //root view rect changed
|
||||
|| mFloaterRect != floater_rect //floater rect changed
|
||||
|| mRecalculateDockablePosition //recalculation is forced
|
||||
)
|
||||
{
|
||||
// undock dockable and off() if dock not visible
|
||||
if (!isDockVisible())
|
||||
|
|
@ -135,7 +140,8 @@ void LLDockControl::repositionDockable()
|
|||
|
||||
mPrevDockRect = dockRect;
|
||||
mRootRect = rootRect;
|
||||
mRecalculateDocablePosition = false;
|
||||
mFloaterRect = floater_rect;
|
||||
mRecalculateDockablePosition = false;
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
}
|
||||
|
|
@ -160,7 +166,7 @@ bool LLDockControl::isDockVisible()
|
|||
case TOP:
|
||||
{
|
||||
// check is dock inside parent rect
|
||||
// assume that parent for all dockable flaoters
|
||||
// assume that parent for all dockable floaters
|
||||
// is the root view
|
||||
LLRect dockParentRect =
|
||||
mDockWidget->getRootView()->calcScreenRect();
|
||||
|
|
@ -202,21 +208,33 @@ void LLDockControl::moveDockable()
|
|||
switch (mDockAt)
|
||||
{
|
||||
case LEFT:
|
||||
x = dockRect.mLeft;
|
||||
y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
|
||||
// check is dockable inside root view rect
|
||||
if (x < rootRect.mLeft)
|
||||
{
|
||||
x = rootRect.mLeft;
|
||||
}
|
||||
if (x + dockableRect.getWidth() > rootRect.mRight)
|
||||
{
|
||||
x = rootRect.mRight - dockableRect.getWidth();
|
||||
}
|
||||
|
||||
x = dockRect.mLeft - dockableRect.getWidth();
|
||||
y = dockRect.getCenterY() + dockableRect.getHeight() / 2;
|
||||
|
||||
mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
|
||||
if (use_tongue)
|
||||
{
|
||||
x -= mDockTongue->getWidth();
|
||||
}
|
||||
|
||||
mDockTongueX = dockableRect.mRight;
|
||||
mDockTongueY = dockableRect.getCenterY() - mDockTongue->getHeight() / 2;
|
||||
|
||||
mDockTongueY = dockRect.mTop;
|
||||
break;
|
||||
|
||||
case RIGHT:
|
||||
|
||||
x = dockRect.mRight;
|
||||
y = dockRect.getCenterY() + dockableRect.getHeight() / 2;
|
||||
|
||||
if (use_tongue)
|
||||
{
|
||||
x += mDockTongue->getWidth();
|
||||
}
|
||||
|
||||
mDockTongueX = dockRect.mRight;
|
||||
mDockTongueY = dockableRect.getCenterY() - mDockTongue->getHeight() / 2;
|
||||
|
||||
break;
|
||||
|
||||
case TOP:
|
||||
|
|
@ -314,13 +332,12 @@ void LLDockControl::moveDockable()
|
|||
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
|
||||
dockableRect.getHeight());
|
||||
}
|
||||
LLRect localDocableParentRect;
|
||||
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
|
||||
&localDocableParentRect);
|
||||
mDockableFloater->setRect(localDocableParentRect);
|
||||
|
||||
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
|
||||
&mDockTongueX, &mDockTongueY);
|
||||
LLRect localDocableParentRect;
|
||||
|
||||
mDockableFloater->getParent()->screenRectToLocal(dockableRect, &localDocableParentRect);
|
||||
mDockableFloater->setRect(localDocableParentRect);
|
||||
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY, &mDockTongueX, &mDockTongueY);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +346,7 @@ void LLDockControl::on()
|
|||
if (isDockVisible())
|
||||
{
|
||||
mEnabled = true;
|
||||
mRecalculateDocablePosition = true;
|
||||
mRecalculateDockablePosition = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -340,7 +357,7 @@ void LLDockControl::off()
|
|||
|
||||
void LLDockControl::forceRecalculatePosition()
|
||||
{
|
||||
mRecalculateDocablePosition = true;
|
||||
mRecalculateDockablePosition = true;
|
||||
}
|
||||
|
||||
void LLDockControl::drawToungue()
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public:
|
|||
{
|
||||
TOP,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
BOTTOM
|
||||
};
|
||||
|
||||
|
|
@ -79,12 +80,13 @@ private:
|
|||
private:
|
||||
get_allowed_rect_callback_t mGetAllowedRectCallback;
|
||||
bool mEnabled;
|
||||
bool mRecalculateDocablePosition;
|
||||
bool mRecalculateDockablePosition;
|
||||
bool mDockWidgetVisible;
|
||||
DocAt mDockAt;
|
||||
LLView* mDockWidget;
|
||||
LLRect mPrevDockRect;
|
||||
LLRect mRootRect;
|
||||
LLRect mFloaterRect;
|
||||
LLFloater* mDockableFloater;
|
||||
LLUIImagePtr mDockTongue;
|
||||
S32 mDockTongueX;
|
||||
|
|
|
|||
|
|
@ -58,13 +58,24 @@
|
|||
#include "llhelp.h"
|
||||
#include "llmultifloater.h"
|
||||
#include "llsdutil.h"
|
||||
#include "../newview/llviewercontrol.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <string.h>
|
||||
#include "../newview/llviewercontrol.h" // This is a nasty hack ...
|
||||
|
||||
// use this to control "jumping" behavior when Ctrl-Tabbing
|
||||
const S32 TABBED_FLOATER_OFFSET = 0;
|
||||
|
||||
namespace LLInitParam
|
||||
{
|
||||
void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues()
|
||||
{
|
||||
declare("none", LLFloaterEnums::OPEN_POSITIONING_NONE);
|
||||
declare("cascading", LLFloaterEnums::OPEN_POSITIONING_CASCADING);
|
||||
declare("centered", LLFloaterEnums::OPEN_POSITIONING_CENTERED);
|
||||
declare("specified", LLFloaterEnums::OPEN_POSITIONING_SPECIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLFloater::sButtonNames[BUTTON_COUNT] =
|
||||
{
|
||||
"llfloater_close_btn", //BUTTON_CLOSE
|
||||
|
|
@ -103,7 +114,6 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
|
|||
|
||||
LLMultiFloater* LLFloater::sHostp = NULL;
|
||||
BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
|
||||
LLFloater::handle_map_t LLFloater::sFloaterMap;
|
||||
|
||||
LLFloaterView* gFloaterView = NULL;
|
||||
|
||||
|
|
@ -157,7 +167,7 @@ LLFloater::Params::Params()
|
|||
: title("title"),
|
||||
short_title("short_title"),
|
||||
single_instance("single_instance", false),
|
||||
auto_tile("auto_tile", false),
|
||||
reuse_instance("reuse_instance", false),
|
||||
can_resize("can_resize", false),
|
||||
can_minimize("can_minimize", true),
|
||||
can_close("can_close", true),
|
||||
|
|
@ -168,7 +178,10 @@ LLFloater::Params::Params()
|
|||
save_rect("save_rect", false),
|
||||
save_visibility("save_visibility", false),
|
||||
can_dock("can_dock", false),
|
||||
open_centered("open_centered", true),
|
||||
show_title("show_title", true),
|
||||
open_positioning("open_positioning", LLFloaterEnums::OPEN_POSITIONING_NONE),
|
||||
specified_left("specified_left"),
|
||||
specified_bottom("specified_bottom"),
|
||||
header_height("header_height", 0),
|
||||
legacy_header_height("legacy_header_height", 0),
|
||||
close_image("close_image"),
|
||||
|
|
@ -184,7 +197,8 @@ LLFloater::Params::Params()
|
|||
dock_pressed_image("dock_pressed_image"),
|
||||
help_pressed_image("help_pressed_image"),
|
||||
open_callback("open_callback"),
|
||||
close_callback("close_callback")
|
||||
close_callback("close_callback"),
|
||||
follows("follows")
|
||||
{
|
||||
changeDefault(visible, false);
|
||||
}
|
||||
|
|
@ -230,13 +244,16 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
|
|||
mTitle(p.title),
|
||||
mShortTitle(p.short_title),
|
||||
mSingleInstance(p.single_instance),
|
||||
mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default
|
||||
mKey(key),
|
||||
mAutoTile(p.auto_tile),
|
||||
mCanTearOff(p.can_tear_off),
|
||||
mCanMinimize(p.can_minimize),
|
||||
mCanClose(p.can_close),
|
||||
mDragOnLeft(p.can_drag_on_left),
|
||||
mResizable(p.can_resize),
|
||||
mOpenPositioning(p.open_positioning),
|
||||
mSpecifiedLeft(p.specified_left),
|
||||
mSpecifiedBottom(p.specified_bottom),
|
||||
mMinWidth(p.min_width),
|
||||
mMinHeight(p.min_height),
|
||||
mHeaderHeight(p.header_height),
|
||||
|
|
@ -256,7 +273,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
|
|||
mMinimizeSignal(NULL)
|
||||
// mNotificationContext(NULL)
|
||||
{
|
||||
mHandle.bind(this);
|
||||
// mNotificationContext = new LLFloaterNotificationContext(getHandle());
|
||||
|
||||
// Clicks stop here.
|
||||
|
|
@ -311,9 +327,6 @@ void LLFloater::initFloater(const Params& p)
|
|||
// Floaters are created in the invisible state
|
||||
setVisible(FALSE);
|
||||
|
||||
// add self to handle->floater map
|
||||
sFloaterMap[mHandle] = this;
|
||||
|
||||
if (!getParent())
|
||||
{
|
||||
gFloaterView->addChild(this);
|
||||
|
|
@ -464,15 +477,24 @@ void LLFloater::layoutResizeCtrls()
|
|||
mResizeHandle[3]->setRect(rect);
|
||||
}
|
||||
|
||||
void LLFloater::enableResizeCtrls(bool enable)
|
||||
void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
|
||||
{
|
||||
mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width);
|
||||
mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width);
|
||||
|
||||
mResizeBar[LLResizeBar::TOP]->setVisible(enable && height);
|
||||
mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height);
|
||||
|
||||
mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width);
|
||||
mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width);
|
||||
|
||||
mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height);
|
||||
mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height);
|
||||
|
||||
for (S32 i = 0; i < 4; ++i)
|
||||
{
|
||||
mResizeBar[i]->setVisible(enable);
|
||||
mResizeBar[i]->setEnabled(enable);
|
||||
|
||||
mResizeHandle[i]->setVisible(enable);
|
||||
mResizeHandle[i]->setEnabled(enable);
|
||||
mResizeHandle[i]->setVisible(enable && width && height);
|
||||
mResizeHandle[i]->setEnabled(enable && width && height);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -514,8 +536,6 @@ LLFloater::~LLFloater()
|
|||
storeMinimizeStateControl();
|
||||
setMinimized( FALSE );
|
||||
|
||||
sFloaterMap.erase(mHandle);
|
||||
|
||||
delete mDragHandle;
|
||||
for (S32 i = 0; i < 4; i++)
|
||||
{
|
||||
|
|
@ -523,7 +543,6 @@ LLFloater::~LLFloater()
|
|||
delete mResizeHandle[i];
|
||||
}
|
||||
|
||||
storeRectControl();
|
||||
setVisible(false); // We're not visible if we're destroyed
|
||||
storeVisibilityControl();
|
||||
storeDockStateControl();
|
||||
|
|
@ -681,15 +700,23 @@ void LLFloater::openFloater(const LLSD& key)
|
|||
}
|
||||
else
|
||||
{
|
||||
// AO: setMinimized(FALSE);
|
||||
|
||||
LLFloater* floater_to_stack = LLFloaterReg::getLastFloaterInGroup(mInstanceName);
|
||||
if (!floater_to_stack)
|
||||
{
|
||||
floater_to_stack = LLFloaterReg::getLastFloaterCascading();
|
||||
}
|
||||
applyControlsAndPosition(floater_to_stack);
|
||||
|
||||
// AO: Always unminimize notecards *HACK*
|
||||
// TS: scripts too
|
||||
|
||||
// setMinimized(FALSE);
|
||||
if ((strcmp(getName().c_str(),"preview notecard") == 0) ||
|
||||
(strcmp(getName().c_str(),"preview lsl text") == 0))
|
||||
{
|
||||
setMinimized(FALSE);
|
||||
}
|
||||
|
||||
setVisibleAndFrontmost(mAutoFocus);
|
||||
}
|
||||
|
||||
|
|
@ -781,12 +808,19 @@ void LLFloater::closeFloater(bool app_quitting)
|
|||
else
|
||||
{
|
||||
setVisible(FALSE);
|
||||
if (!mReuseInstance)
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setVisible(FALSE); // hide before destroying (so handleVisibilityChange() gets called)
|
||||
destroy();
|
||||
if (!mReuseInstance)
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -851,45 +885,59 @@ LLMultiFloater* LLFloater::getHost()
|
|||
return (LLMultiFloater*)mHostHandle.get();
|
||||
}
|
||||
|
||||
void LLFloater::applySavedVariables()
|
||||
void LLFloater::applyControlsAndPosition(LLFloater* other)
|
||||
{
|
||||
applyRectControl();
|
||||
applyDockState();
|
||||
if (!applyDockState())
|
||||
{
|
||||
if (!applyRectControl())
|
||||
{
|
||||
applyPositioning(other);
|
||||
}
|
||||
}
|
||||
applyMinimizedState();
|
||||
}
|
||||
|
||||
void LLFloater::applyRectControl()
|
||||
bool LLFloater::applyRectControl()
|
||||
{
|
||||
// first, center on screen if requested
|
||||
if (mOpenCentered)
|
||||
{
|
||||
center();
|
||||
}
|
||||
bool saved_rect = false;
|
||||
|
||||
// override center if we have saved rect control
|
||||
// only if we are torn off -Zi
|
||||
if (mTornOff && mRectControl.size() > 1)
|
||||
LLFloater* last_in_group = LLFloaterReg::getLastFloaterInGroup(mInstanceName);
|
||||
if (last_in_group && last_in_group != this)
|
||||
{
|
||||
// other floaters in our group, position ourselves relative to them and don't save the rect
|
||||
mRectControl.clear();
|
||||
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP;
|
||||
}
|
||||
else if (mRectControl.size() > 1)
|
||||
{
|
||||
// If we have a saved rect, use it
|
||||
const LLRect& rect = getControlGroup()->getRect(mRectControl);
|
||||
if (rect.getWidth() > 0 && rect.getHeight() > 0)
|
||||
saved_rect = rect.notEmpty();
|
||||
if (saved_rect)
|
||||
{
|
||||
translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom);
|
||||
setOrigin(rect.mLeft, rect.mBottom);
|
||||
|
||||
if (mResizable)
|
||||
{
|
||||
reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return saved_rect;
|
||||
}
|
||||
|
||||
void LLFloater::applyDockState()
|
||||
bool LLFloater::applyDockState()
|
||||
{
|
||||
bool docked = false;
|
||||
|
||||
if (mDocStateControl.size() > 1)
|
||||
{
|
||||
bool dockState = getControlGroup()->getBOOL(mDocStateControl);
|
||||
setDocked(dockState);
|
||||
docked = getControlGroup()->getBOOL(mDocStateControl);
|
||||
setDocked(docked);
|
||||
}
|
||||
|
||||
return docked;
|
||||
}
|
||||
|
||||
void LLFloater::applyMinimizedState()
|
||||
|
|
@ -901,6 +949,56 @@ void LLFloater::applyMinimizedState()
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloater::applyPositioning(LLFloater* other)
|
||||
{
|
||||
// Otherwise position according to the positioning code
|
||||
switch (mOpenPositioning)
|
||||
{
|
||||
case LLFloaterEnums::OPEN_POSITIONING_CENTERED:
|
||||
center();
|
||||
break;
|
||||
|
||||
case LLFloaterEnums::OPEN_POSITIONING_SPECIFIED:
|
||||
{
|
||||
// Translate relative to snap rect
|
||||
setOrigin(mSpecifiedLeft, mSpecifiedBottom);
|
||||
const LLRect& snap_rect = gFloaterView->getSnapRect();
|
||||
translate(snap_rect.mLeft, snap_rect.mBottom);
|
||||
translateIntoRect(snap_rect, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP:
|
||||
case LLFloaterEnums::OPEN_POSITIONING_CASCADING:
|
||||
if (other != NULL && other != this)
|
||||
{
|
||||
stackWith(*other);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const U32 CASCADING_FLOATER_HOFFSET = 0;
|
||||
static const U32 CASCADING_FLOATER_VOFFSET = 0;
|
||||
|
||||
const LLRect& snap_rect = gFloaterView->getSnapRect();
|
||||
|
||||
const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET;
|
||||
const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET;
|
||||
|
||||
S32 rect_height = getRect().getHeight();
|
||||
setOrigin(horizontal_offset, vertical_offset - rect_height);
|
||||
|
||||
translate(snap_rect.mLeft, snap_rect.mBottom);
|
||||
translateIntoRect(snap_rect, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
case LLFloaterEnums::OPEN_POSITIONING_NONE:
|
||||
default:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloater::applyTitle()
|
||||
{
|
||||
if (!mDragHandle)
|
||||
|
|
@ -981,7 +1079,9 @@ BOOL LLFloater::canSnapTo(const LLView* other_view)
|
|||
if (other_view != getParent())
|
||||
{
|
||||
const LLFloater* other_floaterp = dynamic_cast<const LLFloater*>(other_view);
|
||||
if (other_floaterp && other_floaterp->getSnapTarget() == getHandle() && mDependents.find(other_floaterp->getHandle()) != mDependents.end())
|
||||
if (other_floaterp
|
||||
&& other_floaterp->getSnapTarget() == getHandle()
|
||||
&& mDependents.find(other_floaterp->getHandle()) != mDependents.end())
|
||||
{
|
||||
// this is a dependent that is already snapped to us, so don't snap back to it
|
||||
return FALSE;
|
||||
|
|
@ -1013,9 +1113,10 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
|
|||
const LLRect old_rect = getRect();
|
||||
LLView::handleReshape(new_rect, by_user);
|
||||
|
||||
if (by_user)
|
||||
if (by_user && !isMinimized())
|
||||
{
|
||||
storeRectControl();
|
||||
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
|
||||
}
|
||||
|
||||
// if not minimized, adjust all snapped dependents to new shape
|
||||
|
|
@ -1075,7 +1176,7 @@ void LLFloater::setMinimized(BOOL minimize)
|
|||
|
||||
if (minimize == mMinimized) return;
|
||||
|
||||
if(mMinimizeSignal)
|
||||
if (mMinimizeSignal)
|
||||
{
|
||||
(*mMinimizeSignal)(this, LLSD(minimize));
|
||||
}
|
||||
|
|
@ -1129,10 +1230,6 @@ void LLFloater::setMinimized(BOOL minimize)
|
|||
mButtonsEnabled[BUTTON_RESTORE] = TRUE;
|
||||
}
|
||||
|
||||
if (mDragHandle)
|
||||
{
|
||||
mDragHandle->setVisible(TRUE);
|
||||
}
|
||||
setBorderVisible(TRUE);
|
||||
|
||||
for(handle_set_iter_t dependent_it = mDependents.begin();
|
||||
|
|
@ -1296,19 +1393,9 @@ void LLFloater::setIsChrome(BOOL is_chrome)
|
|||
mButtons[BUTTON_CLOSE]->setToolTip(LLStringExplicit(getButtonTooltip(Params(), BUTTON_CLOSE, is_chrome)));
|
||||
}
|
||||
|
||||
// no titles displayed on "chrome" floaters
|
||||
if (mDragHandle)
|
||||
mDragHandle->setTitleVisible(!is_chrome);
|
||||
|
||||
LLPanel::setIsChrome(is_chrome);
|
||||
}
|
||||
|
||||
void LLFloater::setTitleVisible(bool visible)
|
||||
{
|
||||
if (mDragHandle)
|
||||
mDragHandle->setTitleVisible(visible);
|
||||
}
|
||||
|
||||
// Change the draw style to account for the foreground state.
|
||||
void LLFloater::setForeground(BOOL front)
|
||||
{
|
||||
|
|
@ -1396,7 +1483,10 @@ void LLFloater::moveResizeHandlesToFront()
|
|||
|
||||
BOOL LLFloater::isFrontmost()
|
||||
{
|
||||
return gFloaterView && gFloaterView->getFrontmost() == this && getVisible();
|
||||
LLFloaterView* floater_view = getParentByType<LLFloaterView>();
|
||||
return getVisible()
|
||||
&& (floater_view
|
||||
&& floater_view->getFrontmost() == this);
|
||||
}
|
||||
|
||||
void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition)
|
||||
|
|
@ -1469,6 +1559,7 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
if(offerClickToButton(x, y, mask, BUTTON_CLOSE)) return TRUE;
|
||||
if(offerClickToButton(x, y, mask, BUTTON_RESTORE)) return TRUE;
|
||||
if(offerClickToButton(x, y, mask, BUTTON_TEAR_OFF)) return TRUE;
|
||||
if(offerClickToButton(x, y, mask, BUTTON_DOCK)) return TRUE;
|
||||
|
||||
// Otherwise pass to drag handle for movement
|
||||
return mDragHandle->handleMouseDown(x, y, mask);
|
||||
|
|
@ -1574,6 +1665,13 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
|
|||
{
|
||||
mDocked = docked;
|
||||
mButtonsEnabled[BUTTON_DOCK] = !mDocked;
|
||||
|
||||
if (mDocked)
|
||||
{
|
||||
setMinimized(FALSE);
|
||||
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
|
||||
}
|
||||
|
||||
updateTitleButtons();
|
||||
|
||||
storeDockStateControl();
|
||||
|
|
@ -1668,18 +1766,17 @@ void LLFloater::onClickHelp( LLFloater* self )
|
|||
LLFloater* LLFloater::getClosableFloaterFromFocus()
|
||||
{
|
||||
LLFloater* focused_floater = NULL;
|
||||
|
||||
handle_map_iter_t iter;
|
||||
for(iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter)
|
||||
LLInstanceTracker<LLFloater>::instance_iter it = beginInstances();
|
||||
LLInstanceTracker<LLFloater>::instance_iter end_it = endInstances();
|
||||
for (; it != end_it; ++it)
|
||||
{
|
||||
focused_floater = iter->second;
|
||||
if (focused_floater->hasFocus())
|
||||
if (it->hasFocus())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iter == sFloaterMap.end())
|
||||
if (it == endInstances())
|
||||
{
|
||||
// nothing found, return
|
||||
return NULL;
|
||||
|
|
@ -1828,7 +1925,7 @@ void LLFloater::draw()
|
|||
{
|
||||
drawChild(mButtons[i]);
|
||||
}
|
||||
drawChild(mDragHandle);
|
||||
drawChild(mDragHandle, 0, 0, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1945,6 +2042,12 @@ void LLFloater::setCanDrag(BOOL can_drag)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLFloater::getCanDrag()
|
||||
{
|
||||
return mDragHandle->getEnabled();
|
||||
}
|
||||
|
||||
|
||||
void LLFloater::updateTitleButtons()
|
||||
{
|
||||
static LLUICachedControl<S32> floater_close_box_size ("UIFloaterCloseBoxSize", 0);
|
||||
|
|
@ -2166,8 +2269,15 @@ LLFloaterView::LLFloaterView (const Params& p)
|
|||
// By default, adjust vertical.
|
||||
void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
S32 old_width = getRect().getWidth();
|
||||
S32 old_height = getRect().getHeight();
|
||||
S32 old_right = mLastSnapRect.mRight;
|
||||
S32 old_top = mLastSnapRect.mTop;
|
||||
|
||||
LLView::reshape(width, height, called_from_parent);
|
||||
|
||||
S32 new_right = getSnapRect().mRight;
|
||||
S32 new_top = getSnapRect().mTop;
|
||||
|
||||
mLastSnapRect = getSnapRect();
|
||||
|
||||
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
|
||||
{
|
||||
|
|
@ -2175,66 +2285,48 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|||
LLFloater* floaterp = (LLFloater*)viewp;
|
||||
if (floaterp->isDependent())
|
||||
{
|
||||
// dependents use same follow flags as their "dependee"
|
||||
// dependents are moved with their "dependee"
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make if follow the edge it is closest to
|
||||
U32 follow_flags = 0x0;
|
||||
|
||||
if (floaterp->isMinimized())
|
||||
{
|
||||
follow_flags |= (FOLLOWS_LEFT | FOLLOWS_TOP);
|
||||
}
|
||||
else
|
||||
if (!floaterp->isMinimized())
|
||||
{
|
||||
LLRect r = floaterp->getRect();
|
||||
|
||||
// Compute absolute distance from each edge of screen
|
||||
S32 left_offset = llabs(r.mLeft - 0);
|
||||
S32 right_offset = llabs(old_width - r.mRight);
|
||||
S32 right_offset = llabs(old_right - r.mRight);
|
||||
|
||||
S32 top_offset = llabs(old_height - r.mTop);
|
||||
S32 top_offset = llabs(old_top - r.mTop);
|
||||
S32 bottom_offset = llabs(r.mBottom - 0);
|
||||
|
||||
S32 translate_x = 0;
|
||||
S32 translate_y = 0;
|
||||
|
||||
if (left_offset < right_offset)
|
||||
if (left_offset > right_offset)
|
||||
{
|
||||
follow_flags |= FOLLOWS_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
follow_flags |= FOLLOWS_RIGHT;
|
||||
translate_x = new_right - old_right;
|
||||
}
|
||||
|
||||
// "No vertical adjustment" usually means that the bottom of the view
|
||||
// has been pushed up or down. Hence we want the floaters to follow
|
||||
// the top.
|
||||
if (top_offset < bottom_offset)
|
||||
{
|
||||
follow_flags |= FOLLOWS_TOP;
|
||||
translate_y = new_top - old_top;
|
||||
}
|
||||
else
|
||||
|
||||
// don't reposition immovable floaters
|
||||
if (floaterp->getCanDrag())
|
||||
{
|
||||
follow_flags |= FOLLOWS_BOTTOM;
|
||||
floaterp->translate(translate_x, translate_y);
|
||||
}
|
||||
}
|
||||
|
||||
floaterp->setFollows(follow_flags);
|
||||
|
||||
//RN: all dependent floaters copy follow behavior of "parent"
|
||||
for(LLFloater::handle_set_iter_t dependent_it = floaterp->mDependents.begin();
|
||||
dependent_it != floaterp->mDependents.end(); ++dependent_it)
|
||||
{
|
||||
LLFloater* dependent_floaterp = dependent_it->get();
|
||||
if (dependent_floaterp)
|
||||
BOOST_FOREACH(LLHandle<LLFloater> dependent_floater, floaterp->mDependents)
|
||||
{
|
||||
dependent_floaterp->setFollows(follow_flags);
|
||||
if (dependent_floater.get())
|
||||
{
|
||||
dependent_floater.get()->translate(translate_x, translate_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLView::reshape(width, height, called_from_parent);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2575,6 +2667,52 @@ void LLFloaterView::closeAllChildren(bool app_quitting)
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterView::hiddenFloaterClosed(LLFloater* floater)
|
||||
{
|
||||
for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
if (it->first.get() == floater)
|
||||
{
|
||||
it->second.disconnect();
|
||||
mHiddenFloaters.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterView::hideAllFloaters()
|
||||
{
|
||||
child_list_t child_list = *(getChildList());
|
||||
|
||||
for (child_list_iter_t it = child_list.begin(); it != child_list.end(); ++it)
|
||||
{
|
||||
LLFloater* floaterp = dynamic_cast<LLFloater*>(*it);
|
||||
if (floaterp && floaterp->getVisible())
|
||||
{
|
||||
floaterp->setVisible(false);
|
||||
boost::signals2::connection connection = floaterp->mCloseSignal.connect(boost::bind(&LLFloaterView::hiddenFloaterClosed, this, floaterp));
|
||||
mHiddenFloaters.push_back(std::make_pair(floaterp->getHandle(), connection));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterView::showHiddenFloaters()
|
||||
{
|
||||
for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
LLFloater* floaterp = it->first.get();
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->setVisible(true);
|
||||
}
|
||||
it->second.disconnect();
|
||||
}
|
||||
mHiddenFloaters.clear();
|
||||
}
|
||||
|
||||
BOOL LLFloaterView::allChildrenClosed()
|
||||
{
|
||||
|
|
@ -2608,6 +2746,12 @@ void LLFloaterView::shiftFloaters(S32 x_offset, S32 y_offset)
|
|||
|
||||
void LLFloaterView::refresh()
|
||||
{
|
||||
LLRect snap_rect = getSnapRect();
|
||||
if (snap_rect != mLastSnapRect)
|
||||
{
|
||||
reshape(getRect().getWidth(), getRect().getHeight(), TRUE);
|
||||
}
|
||||
|
||||
// Constrain children to be entirely on the screen
|
||||
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
|
||||
{
|
||||
|
|
@ -2673,7 +2817,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
|
|||
}
|
||||
|
||||
// move window fully onscreen
|
||||
if (floater->translateIntoRect( getLocalRect(), allow_partial_outside ))
|
||||
if (floater->translateIntoRect( getSnapRect(), allow_partial_outside ))
|
||||
{
|
||||
floater->clearSnapTarget();
|
||||
}
|
||||
|
|
@ -2903,7 +3047,6 @@ void LLFloater::setInstanceName(const std::string& name)
|
|||
{
|
||||
mMinimizeStateControl = LLFloaterReg::declareMinimizeStateControl(ctrl_name);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2950,6 +3093,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
|
|||
// control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible
|
||||
LLPanel::initFromParams(p);
|
||||
|
||||
// override any follows flags
|
||||
setFollows(FOLLOWS_NONE);
|
||||
|
||||
mTitle = p.title;
|
||||
mShortTitle = p.short_title;
|
||||
applyTitle();
|
||||
|
|
@ -2965,8 +3111,11 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
|
|||
mHeaderHeight = p.header_height;
|
||||
mLegacyHeaderHeight = p.legacy_header_height;
|
||||
mSingleInstance = p.single_instance;
|
||||
mAutoTile = p.auto_tile;
|
||||
mOpenCentered = p.open_centered;
|
||||
mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance;
|
||||
|
||||
mOpenPositioning = p.open_positioning;
|
||||
mSpecifiedLeft = p.specified_left;
|
||||
mSpecifiedBottom = p.specified_bottom;
|
||||
|
||||
// ## Zi: Optional Drop Shadows
|
||||
// we do this here because the values in the constructor get ignored, probably due to
|
||||
|
|
@ -2981,7 +3130,6 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
|
|||
{
|
||||
mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set
|
||||
}
|
||||
|
||||
if(p.save_dock_state)
|
||||
{
|
||||
mDocStateControl = "t"; // flag to build mDocStateControl name once mInstanceName is set
|
||||
|
|
@ -2992,13 +3140,18 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
|
|||
// open callback
|
||||
if (p.open_callback.isProvided())
|
||||
{
|
||||
mOpenSignal.connect(initCommitCallback(p.open_callback));
|
||||
setOpenCallback(initCommitCallback(p.open_callback));
|
||||
}
|
||||
// close callback
|
||||
if (p.close_callback.isProvided())
|
||||
{
|
||||
setCloseCallback(initCommitCallback(p.close_callback));
|
||||
}
|
||||
|
||||
if (mDragHandle)
|
||||
{
|
||||
mDragHandle->setTitleVisible(p.show_title);
|
||||
}
|
||||
}
|
||||
|
||||
boost::signals2::connection LLFloater::setMinimizeCallback( const commit_signal_t::slot_type& cb )
|
||||
|
|
@ -3007,6 +3160,11 @@ boost::signals2::connection LLFloater::setMinimizeCallback( const commit_signal_
|
|||
return mMinimizeSignal->connect(cb);
|
||||
}
|
||||
|
||||
boost::signals2::connection LLFloater::setOpenCallback( const commit_signal_t::slot_type& cb )
|
||||
{
|
||||
return mOpenSignal.connect(cb);
|
||||
}
|
||||
|
||||
boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::slot_type& cb )
|
||||
{
|
||||
return mCloseSignal.connect(cb);
|
||||
|
|
@ -3051,7 +3209,9 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
parser.readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName());
|
||||
Params referenced_params;
|
||||
parser.readXUI(referenced_xml, referenced_params, LLUICtrlFactory::getInstance()->getCurFileName());
|
||||
params.fillFrom(referenced_params);
|
||||
|
||||
// add children using dimensions from referenced xml for consistent layout
|
||||
setShape(params.rect);
|
||||
|
|
@ -3241,7 +3401,6 @@ void LLFloater::stackWith(LLFloater& other)
|
|||
|
||||
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
|
||||
|
||||
mRectControl.clear(); // don't save rect of stacked floaters
|
||||
setShape(next_rect);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "lluuid.h"
|
||||
//#include "llnotificationsutil.h"
|
||||
#include <set>
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
class LLDragHandle;
|
||||
class LLResizeHandle;
|
||||
|
|
@ -59,11 +60,35 @@ const BOOL CLOSE_NO = FALSE;
|
|||
const BOOL ADJUST_VERTICAL_YES = TRUE;
|
||||
const BOOL ADJUST_VERTICAL_NO = FALSE;
|
||||
|
||||
class LLFloater : public LLPanel
|
||||
namespace LLFloaterEnums
|
||||
{
|
||||
friend class LLFloaterView;
|
||||
friend class LLFloaterReg;
|
||||
friend class LLMultiFloater;
|
||||
enum EOpenPositioning
|
||||
{
|
||||
OPEN_POSITIONING_NONE,
|
||||
OPEN_POSITIONING_CASCADING,
|
||||
OPEN_POSITIONING_CASCADE_GROUP,
|
||||
OPEN_POSITIONING_CENTERED,
|
||||
OPEN_POSITIONING_SPECIFIED,
|
||||
OPEN_POSITIONING_COUNT
|
||||
};
|
||||
}
|
||||
|
||||
namespace LLInitParam
|
||||
{
|
||||
template<>
|
||||
struct TypeValues<LLFloaterEnums::EOpenPositioning> : public TypeValuesHelper<LLFloaterEnums::EOpenPositioning>
|
||||
{
|
||||
static void declareValues();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
|
||||
{
|
||||
friend class LLFloaterView;
|
||||
friend class LLFloaterReg;
|
||||
friend class LLMultiFloater;
|
||||
|
||||
public:
|
||||
struct KeyCompare
|
||||
{
|
||||
|
|
@ -95,7 +120,7 @@ public:
|
|||
short_title;
|
||||
|
||||
Optional<bool> single_instance,
|
||||
auto_tile,
|
||||
reuse_instance,
|
||||
can_resize,
|
||||
can_minimize,
|
||||
can_close,
|
||||
|
|
@ -106,7 +131,13 @@ public:
|
|||
save_visibility,
|
||||
save_dock_state,
|
||||
can_dock,
|
||||
open_centered;
|
||||
show_title;
|
||||
|
||||
Optional<LLFloaterEnums::EOpenPositioning> open_positioning;
|
||||
Optional<S32> specified_left;
|
||||
Optional<S32> specified_bottom;
|
||||
|
||||
|
||||
Optional<S32> header_height,
|
||||
legacy_header_height; // HACK see initFromXML()
|
||||
|
||||
|
|
@ -126,6 +157,8 @@ public:
|
|||
|
||||
Optional<CommitCallbackParam> open_callback,
|
||||
close_callback;
|
||||
|
||||
Ignored follows;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
|
@ -145,6 +178,7 @@ public:
|
|||
bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL);
|
||||
|
||||
boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb );
|
||||
boost::signals2::connection setOpenCallback( const commit_signal_t::slot_type& cb );
|
||||
boost::signals2::connection setCloseCallback( const commit_signal_t::slot_type& cb );
|
||||
|
||||
void initFromParams(const LLFloater::Params& p);
|
||||
|
|
@ -181,7 +215,6 @@ public:
|
|||
void setShortTitle( const std::string& short_title );
|
||||
std::string getShortTitle() const;
|
||||
void setHideOnMinimize(bool hide);
|
||||
void setTitleVisible(bool visible);
|
||||
virtual void setMinimized(BOOL b);
|
||||
void moveResizeHandlesToFront();
|
||||
void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE);
|
||||
|
|
@ -205,6 +238,7 @@ public:
|
|||
void setCanTearOff(BOOL can_tear_off);
|
||||
virtual void setCanResize(BOOL can_resize);
|
||||
void setCanDrag(BOOL can_drag);
|
||||
bool getCanDrag();
|
||||
void setHost(LLMultiFloater* host);
|
||||
BOOL isResizable() const { return mResizable; }
|
||||
void setResizeLimits( S32 min_width, S32 min_height );
|
||||
|
|
@ -253,7 +287,7 @@ public:
|
|||
void clearSnapTarget() { mSnappedTo.markDead(); }
|
||||
LLHandle<LLFloater> getSnapTarget() const { return mSnappedTo; }
|
||||
|
||||
LLHandle<LLFloater> getHandle() const { return mHandle; }
|
||||
LLHandle<LLFloater> getHandle() const { return getDerivedHandle<LLFloater>(); }
|
||||
const LLSD& getKey() { return mKey; }
|
||||
virtual bool matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); }
|
||||
|
||||
|
|
@ -267,8 +301,6 @@ public:
|
|||
|
||||
virtual void setTornOff(bool torn_off) { mTornOff = torn_off; }
|
||||
|
||||
void stackWith(LLFloater& other);
|
||||
|
||||
// Return a closeable floater, if any, given the current focus.
|
||||
static LLFloater* getClosableFloaterFromFocus();
|
||||
|
||||
|
|
@ -292,16 +324,22 @@ public:
|
|||
|
||||
void updateTransparency(ETypeTransparency transparency_type);
|
||||
|
||||
protected:
|
||||
virtual void applySavedVariables();
|
||||
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
|
||||
|
||||
void applyRectControl();
|
||||
void applyDockState();
|
||||
void applyMinimizedState();
|
||||
bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mOpenPositioning); }
|
||||
protected:
|
||||
void applyControlsAndPosition(LLFloater* other);
|
||||
|
||||
void stackWith(LLFloater& other);
|
||||
|
||||
virtual bool applyRectControl();
|
||||
bool applyDockState();
|
||||
void applyPositioning(LLFloater* other);
|
||||
void storeRectControl();
|
||||
void storeVisibilityControl();
|
||||
void storeDockStateControl();
|
||||
void storeMinimizeStateControl();
|
||||
void applyMinimizedState();
|
||||
|
||||
void setKey(const LLSD& key);
|
||||
void setInstanceName(const std::string& name);
|
||||
|
|
@ -343,7 +381,6 @@ private:
|
|||
BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index);
|
||||
void addResizeCtrls();
|
||||
void layoutResizeCtrls();
|
||||
void enableResizeCtrls(bool enable);
|
||||
void addDragHandle();
|
||||
void layoutDragHandle(); // repair layout
|
||||
|
||||
|
|
@ -382,8 +419,8 @@ private:
|
|||
LLUIString mShortTitle;
|
||||
|
||||
BOOL mSingleInstance; // TRUE if there is only ever one instance of the floater
|
||||
bool mReuseInstance; // true if we want to hide the floater when we close it instead of destroying it
|
||||
std::string mInstanceName; // Store the instance name so we can remove ourselves from the list
|
||||
BOOL mAutoTile; // TRUE if placement of new instances tiles
|
||||
|
||||
BOOL mDropShadow; // ## Zi: Optional Drop Shadows
|
||||
BOOL mCanTearOff;
|
||||
|
|
@ -391,8 +428,11 @@ private:
|
|||
BOOL mCanClose;
|
||||
BOOL mDragOnLeft;
|
||||
BOOL mResizable;
|
||||
bool mOpenCentered;
|
||||
bool mHideOnMinimize;
|
||||
|
||||
LLFloaterEnums::EOpenPositioning mOpenPositioning;
|
||||
S32 mSpecifiedLeft;
|
||||
S32 mSpecifiedBottom;
|
||||
|
||||
S32 mMinWidth;
|
||||
S32 mMinHeight;
|
||||
|
|
@ -431,18 +471,9 @@ private:
|
|||
typedef void(*click_callback)(LLFloater*);
|
||||
static click_callback sButtonCallbacks[BUTTON_COUNT];
|
||||
|
||||
typedef std::map<LLHandle<LLFloater>, LLFloater*> handle_map_t;
|
||||
typedef std::map<LLHandle<LLFloater>, LLFloater*>::iterator handle_map_iter_t;
|
||||
static handle_map_t sFloaterMap;
|
||||
|
||||
std::vector<LLHandle<LLView> > mMinimizedHiddenChildren;
|
||||
|
||||
BOOL mHasBeenDraggedWhileMinimized;
|
||||
S32 mPreviousMinimizedBottom;
|
||||
S32 mPreviousMinimizedLeft;
|
||||
|
||||
// LLFloaterNotificationContext* mNotificationContext;
|
||||
LLRootHandle<LLFloater> mHandle;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -490,6 +521,10 @@ public:
|
|||
BOOL allChildrenClosed();
|
||||
void shiftFloaters(S32 x_offset, S32 y_offset);
|
||||
|
||||
void hideAllFloaters();
|
||||
void showHiddenFloaters();
|
||||
|
||||
|
||||
LLFloater* getFrontmost() const;
|
||||
LLFloater* getBackmost() const;
|
||||
LLFloater* getParentFloater(LLView* viewp) const;
|
||||
|
|
@ -504,11 +539,16 @@ public:
|
|||
void setFloaterSnapView(LLHandle<LLView> snap_view) {mSnapView = snap_view; }
|
||||
|
||||
private:
|
||||
void hiddenFloaterClosed(LLFloater* floater);
|
||||
|
||||
LLRect mLastSnapRect;
|
||||
LLHandle<LLView> mSnapView;
|
||||
BOOL mFocusCycleMode;
|
||||
S32 mSnapOffsetBottom;
|
||||
S32 mSnapOffsetRight;
|
||||
S32 mMinimizePositionVOffset;
|
||||
typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
|
||||
hidden_floaters_t mHiddenFloaters;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -64,19 +64,57 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con
|
|||
//static
|
||||
LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
|
||||
{
|
||||
LLRect rect;
|
||||
const std::string& groupname = sGroupMap[name];
|
||||
if (!groupname.empty())
|
||||
{
|
||||
instance_list_t& list = sInstanceMap[groupname];
|
||||
if (!list.empty())
|
||||
{
|
||||
return list.back();
|
||||
for (instance_list_t::reverse_iterator iter = list.rbegin(); iter != list.rend(); ++iter)
|
||||
{
|
||||
LLFloater* inst = *iter;
|
||||
|
||||
if (inst->getVisible() && !inst->isMinimized())
|
||||
{
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLFloater* LLFloaterReg::getLastFloaterCascading()
|
||||
{
|
||||
LLRect candidate_rect;
|
||||
candidate_rect.mTop = 100000;
|
||||
LLFloater* candidate_floater = NULL;
|
||||
|
||||
std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
|
||||
for( ; it != it_end; ++it)
|
||||
{
|
||||
const std::string& group_name = it->second;
|
||||
|
||||
instance_list_t& instances = sInstanceMap[group_name];
|
||||
|
||||
for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
|
||||
{
|
||||
LLFloater* inst = *iter;
|
||||
|
||||
if (inst->getVisible() && inst->isPositioning(LLFloaterEnums::OPEN_POSITIONING_CASCADING))
|
||||
{
|
||||
if (candidate_rect.mTop > inst->getRect().mTop)
|
||||
{
|
||||
candidate_floater = inst;
|
||||
candidate_rect = inst->getRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return candidate_floater;
|
||||
}
|
||||
|
||||
//static
|
||||
LLFloater* LLFloaterReg::findInstance(const std::string& name, const LLSD& key)
|
||||
{
|
||||
|
|
@ -112,21 +150,24 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
|
|||
if (!groupname.empty())
|
||||
{
|
||||
instance_list_t& list = sInstanceMap[groupname];
|
||||
int index = list.size();
|
||||
|
||||
res = build_func(key);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
llwarns << "Failed to build floater type: '" << name << "'." << llendl;
|
||||
return NULL;
|
||||
}
|
||||
bool success = res->buildFromFile(xui_file, NULL);
|
||||
if (!success)
|
||||
{
|
||||
llwarns << "Failed to build floater type: '" << name << "'." << llendl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
|
||||
if (res->mKey.isUndefined())
|
||||
{
|
||||
res->mKey = key;
|
||||
res->mKey = key;
|
||||
}
|
||||
res->setInstanceName(name);
|
||||
|
||||
|
|
@ -142,20 +183,13 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
|
|||
res->setHideOnMinimize(true);
|
||||
}
|
||||
|
||||
res->applySavedVariables(); // Can't apply rect and dock state until setting instance name
|
||||
if (res->mAutoTile && !res->getHost() && index > 0)
|
||||
{
|
||||
LLFloater* last_floater = getLastFloaterInGroup(groupname);
|
||||
if (last_floater)
|
||||
{
|
||||
res->stackWith(*last_floater);
|
||||
gFloaterView->adjustToFitScreen(res, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gFloaterView->adjustToFitScreen(res, false);
|
||||
}
|
||||
|
||||
LLFloater *last_floater = (list.empty() ? NULL : list.back());
|
||||
|
||||
res->applyControlsAndPosition(last_floater);
|
||||
|
||||
gFloaterView->adjustToFitScreen(res, false);
|
||||
|
||||
list.push_back(res);
|
||||
}
|
||||
}
|
||||
|
|
@ -444,70 +478,71 @@ void LLFloaterReg::registerControlVariables()
|
|||
}
|
||||
}
|
||||
|
||||
// Callbacks
|
||||
|
||||
// static
|
||||
// Call once (i.e use for init callbacks)
|
||||
void LLFloaterReg::initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname)
|
||||
//static
|
||||
void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key)
|
||||
{
|
||||
// Get the visibility control name for the floater
|
||||
std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString());
|
||||
// Set the control value to the floater visibility control (Sets the value as well)
|
||||
ctrl->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
|
||||
}
|
||||
//
|
||||
// Floaters controlled by the toolbar behave a bit differently from others.
|
||||
// Namely they have 3-4 states as defined in the design wiki page here:
|
||||
// https://wiki.lindenlab.com/wiki/FUI_Button_states
|
||||
//
|
||||
// The basic idea is this:
|
||||
// * If the target floater is minimized, this button press will un-minimize it.
|
||||
// * Else if the target floater is closed open it.
|
||||
// * Else if the target floater does not have focus, give it focus.
|
||||
// * Also, if it is not on top, bring it forward when focus is given.
|
||||
// * Else the target floater is open, close it.
|
||||
//
|
||||
|
||||
// callback args may use "floatername.key" format
|
||||
static void parse_name_key(std::string& name, LLSD& key)
|
||||
{
|
||||
std::string instname = name;
|
||||
std::size_t dotpos = instname.find(".");
|
||||
if (dotpos != std::string::npos)
|
||||
std::string name = sdname.asString();
|
||||
LLFloater* instance = getInstance(name, key);
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
name = instname.substr(0, dotpos);
|
||||
key = LLSD(instname.substr(dotpos+1, std::string::npos));
|
||||
lldebugs << "Unable to get instance of floater '" << name << "'" << llendl;
|
||||
}
|
||||
else if (instance->isMinimized())
|
||||
{
|
||||
instance->setMinimized(FALSE);
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else if (!instance->isShown())
|
||||
{
|
||||
instance->openFloater(key);
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else if (!instance->isFrontmost())
|
||||
{
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else
|
||||
{
|
||||
instance->closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterReg::showFloaterInstance(const LLSD& sdname)
|
||||
// static
|
||||
U32 LLFloaterReg::getVisibleFloaterInstanceCount()
|
||||
{
|
||||
LLSD key;
|
||||
std::string name = sdname.asString();
|
||||
parse_name_key(name, key);
|
||||
showInstance(name, key, TRUE);
|
||||
}
|
||||
//static
|
||||
void LLFloaterReg::hideFloaterInstance(const LLSD& sdname)
|
||||
{
|
||||
LLSD key;
|
||||
std::string name = sdname.asString();
|
||||
parse_name_key(name, key);
|
||||
hideInstance(name, key);
|
||||
}
|
||||
//static
|
||||
void LLFloaterReg::toggleFloaterInstance(const LLSD& sdname)
|
||||
{
|
||||
LLSD key;
|
||||
std::string name = sdname.asString();
|
||||
parse_name_key(name, key);
|
||||
toggleInstance(name, key);
|
||||
}
|
||||
U32 count = 0;
|
||||
|
||||
//static
|
||||
bool LLFloaterReg::floaterInstanceVisible(const LLSD& sdname)
|
||||
{
|
||||
LLSD key;
|
||||
std::string name = sdname.asString();
|
||||
parse_name_key(name, key);
|
||||
return instanceVisible(name, key);
|
||||
}
|
||||
std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
|
||||
for( ; it != it_end; ++it)
|
||||
{
|
||||
const std::string& group_name = it->second;
|
||||
|
||||
//static
|
||||
bool LLFloaterReg::floaterInstanceMinimized(const LLSD& sdname)
|
||||
{
|
||||
LLSD key;
|
||||
std::string name = sdname.asString();
|
||||
parse_name_key(name, key);
|
||||
LLFloater* instance = findInstance(name, key);
|
||||
return LLFloater::isShown(instance);
|
||||
instance_list_t& instances = sInstanceMap[group_name];
|
||||
|
||||
for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
|
||||
{
|
||||
LLFloater* inst = *iter;
|
||||
|
||||
if (inst->getVisible() && !inst->isMinimized())
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ public:
|
|||
|
||||
// Helpers
|
||||
static LLFloater* getLastFloaterInGroup(const std::string& name);
|
||||
static LLFloater* getLastFloaterCascading();
|
||||
|
||||
// Find / get (create) / remove / destroy
|
||||
static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());
|
||||
|
|
@ -137,12 +138,7 @@ public:
|
|||
static void registerControlVariables();
|
||||
|
||||
// Callback wrappers
|
||||
static void initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname);
|
||||
static void showFloaterInstance(const LLSD& sdname);
|
||||
static void hideFloaterInstance(const LLSD& sdname);
|
||||
static void toggleFloaterInstance(const LLSD& sdname);
|
||||
static bool floaterInstanceVisible(const LLSD& sdname);
|
||||
static bool floaterInstanceMinimized(const LLSD& sdname);
|
||||
static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD());
|
||||
|
||||
// Typed find / get / show
|
||||
template <class T>
|
||||
|
|
@ -165,6 +161,7 @@ public:
|
|||
|
||||
static void blockShowFloaters(bool value) { sBlockShowFloaters = value;}
|
||||
|
||||
static U32 getVisibleFloaterInstanceCount();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -28,17 +28,18 @@
|
|||
#define LLHANDLE_H
|
||||
|
||||
#include "llpointer.h"
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
template <typename T>
|
||||
class LLTombStone : public LLRefCount
|
||||
{
|
||||
public:
|
||||
LLTombStone(T* target = NULL) : mTarget(target) {}
|
||||
LLTombStone(void* target = NULL) : mTarget(target) {}
|
||||
|
||||
void setTarget(T* target) { mTarget = target; }
|
||||
T* getTarget() const { return mTarget; }
|
||||
void setTarget(void* target) { mTarget = target; }
|
||||
void* getTarget() const { return mTarget; }
|
||||
private:
|
||||
T* mTarget;
|
||||
mutable void* mTarget;
|
||||
};
|
||||
|
||||
// LLHandles are used to refer to objects whose lifetime you do not control or influence.
|
||||
|
|
@ -53,13 +54,15 @@ private:
|
|||
template <typename T>
|
||||
class LLHandle
|
||||
{
|
||||
template <typename U> friend class LLHandle;
|
||||
template <typename U> friend class LLHandleProvider;
|
||||
public:
|
||||
LLHandle() : mTombStone(getDefaultTombStone()) {}
|
||||
const LLHandle<T>& operator =(const LLHandle<T>& other)
|
||||
{
|
||||
mTombStone = other.mTombStone;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
LLHandle(const LLHandle<U>& other, typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0)
|
||||
: mTombStone(other.mTombStone)
|
||||
{}
|
||||
|
||||
bool isDead() const
|
||||
{
|
||||
|
|
@ -73,7 +76,7 @@ public:
|
|||
|
||||
T* get() const
|
||||
{
|
||||
return mTombStone->getTarget();
|
||||
return reinterpret_cast<T*>(mTombStone->getTarget());
|
||||
}
|
||||
|
||||
friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
|
||||
|
|
@ -94,12 +97,13 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
LLPointer<LLTombStone<T> > mTombStone;
|
||||
LLPointer<LLTombStone> mTombStone;
|
||||
|
||||
private:
|
||||
static LLPointer<LLTombStone<T> >& getDefaultTombStone()
|
||||
typedef T* pointer_t;
|
||||
static LLPointer<LLTombStone>& getDefaultTombStone()
|
||||
{
|
||||
static LLPointer<LLTombStone<T> > sDefaultTombStone = new LLTombStone<T>;
|
||||
static LLPointer<LLTombStone> sDefaultTombStone = new LLTombStone;
|
||||
return sDefaultTombStone;
|
||||
}
|
||||
};
|
||||
|
|
@ -108,23 +112,26 @@ template <typename T>
|
|||
class LLRootHandle : public LLHandle<T>
|
||||
{
|
||||
public:
|
||||
typedef LLRootHandle<T> self_t;
|
||||
typedef LLHandle<T> base_t;
|
||||
|
||||
LLRootHandle(T* object) { bind(object); }
|
||||
LLRootHandle() {};
|
||||
~LLRootHandle() { unbind(); }
|
||||
|
||||
// this is redundant, since a LLRootHandle *is* an LLHandle
|
||||
LLHandle<T> getHandle() { return LLHandle<T>(*this); }
|
||||
// this is redundant, since an LLRootHandle *is* an LLHandle
|
||||
//LLHandle<T> getHandle() { return LLHandle<T>(*this); }
|
||||
|
||||
void bind(T* object)
|
||||
{
|
||||
// unbind existing tombstone
|
||||
if (LLHandle<T>::mTombStone.notNull())
|
||||
{
|
||||
if (LLHandle<T>::mTombStone->getTarget() == object) return;
|
||||
if (LLHandle<T>::mTombStone->getTarget() == (void*)object) return;
|
||||
LLHandle<T>::mTombStone->setTarget(NULL);
|
||||
}
|
||||
// tombstone reference counted, so no paired delete
|
||||
LLHandle<T>::mTombStone = new LLTombStone<T>(object);
|
||||
LLHandle<T>::mTombStone = new LLTombStone((void*)object);
|
||||
}
|
||||
|
||||
void unbind()
|
||||
|
|
@ -142,6 +149,15 @@ private:
|
|||
template <typename T>
|
||||
class LLHandleProvider
|
||||
{
|
||||
public:
|
||||
LLHandle<T> getHandle() const
|
||||
{
|
||||
// perform lazy binding to avoid small tombstone allocations for handle
|
||||
// providers whose handles are never referenced
|
||||
mHandle.bind(static_cast<T*>(const_cast<LLHandleProvider<T>* >(this)));
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef LLHandle<T> handle_type_t;
|
||||
LLHandleProvider()
|
||||
|
|
@ -149,16 +165,17 @@ protected:
|
|||
// provided here to enforce T deriving from LLHandleProvider<T>
|
||||
}
|
||||
|
||||
LLHandle<T> getHandle()
|
||||
{
|
||||
// perform lazy binding to avoid small tombstone allocations for handle
|
||||
// providers whose handles are never referenced
|
||||
mHandle.bind(static_cast<T*>(this));
|
||||
return mHandle;
|
||||
template <typename U>
|
||||
LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
|
||||
{
|
||||
LLHandle<U> downcast_handle;
|
||||
downcast_handle.mTombStone = getHandle().mTombStone;
|
||||
return downcast_handle;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
LLRootHandle<T> mHandle;
|
||||
mutable LLRootHandle<T> mHandle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ class LLHelp
|
|||
{
|
||||
public:
|
||||
virtual void showTopic(const std::string &topic) = 0;
|
||||
virtual std::string getURL(const std::string &topic) = 0;
|
||||
// return default (fallback) topic name suitable for showTopic()
|
||||
virtual std::string defaultTopic() = 0;
|
||||
// return topic to use before the user logs in
|
||||
|
|
|
|||
|
|
@ -51,8 +51,7 @@ public:
|
|||
* - TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with.
|
||||
* - DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close.
|
||||
*/
|
||||
// typedef enum TOKEN_TYPE
|
||||
enum TOKEN_TYPE // <ND/> That typedef makes GCC >= 4.6 really angry, rightfully so.
|
||||
enum TOKEN_TYPE
|
||||
{
|
||||
WORD,
|
||||
LINE,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,19 @@ void LLLayoutStack::OrientationNames::declareValues()
|
|||
//
|
||||
// LLLayoutPanel
|
||||
//
|
||||
LLLayoutPanel::Params::Params()
|
||||
: expanded_min_dim("expanded_min_dim", 0),
|
||||
min_dim("min_dim", 0),
|
||||
max_dim("max_dim", S32_MAX),
|
||||
user_resize("user_resize", true),
|
||||
auto_resize("auto_resize", true)
|
||||
{
|
||||
addSynonym(min_dim, "min_width");
|
||||
addSynonym(min_dim, "min_height");
|
||||
addSynonym(max_dim, "max_width");
|
||||
addSynonym(max_dim, "max_height");
|
||||
}
|
||||
|
||||
LLLayoutPanel::LLLayoutPanel(const Params& p)
|
||||
: LLPanel(p),
|
||||
mExpandedMinDimSpecified(false),
|
||||
|
|
@ -58,7 +71,9 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
|
|||
mCollapsed(FALSE),
|
||||
mCollapseAmt(0.f),
|
||||
mVisibleAmt(1.f), // default to fully visible
|
||||
mResizeBar(NULL)
|
||||
mResizeBar(NULL),
|
||||
mFractionalSize(0.f),
|
||||
mOrientation(LLLayoutStack::HORIZONTAL)
|
||||
{
|
||||
// Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value
|
||||
if (p.expanded_min_dim.isProvided())
|
||||
|
|
@ -88,9 +103,22 @@ LLLayoutPanel::~LLLayoutPanel()
|
|||
mResizeBar = NULL;
|
||||
}
|
||||
|
||||
F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)
|
||||
void LLLayoutPanel::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
if (orientation == LLLayoutStack::HORIZONTAL)
|
||||
if (mOrientation == LLLayoutStack::HORIZONTAL)
|
||||
{
|
||||
mFractionalSize += width - llround(mFractionalSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFractionalSize += height - llround(mFractionalSize);
|
||||
}
|
||||
LLPanel::reshape(width, height, called_from_parent);
|
||||
}
|
||||
|
||||
F32 LLLayoutPanel::getCollapseFactor()
|
||||
{
|
||||
if (mOrientation == LLLayoutStack::HORIZONTAL)
|
||||
{
|
||||
F32 collapse_amt =
|
||||
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getWidth()));
|
||||
|
|
@ -149,11 +177,11 @@ void LLLayoutStack::draw()
|
|||
// scale clipping rectangle by visible amount
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor(mOrientation));
|
||||
clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor(mOrientation));
|
||||
clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
|
||||
}
|
||||
|
||||
LLPanel* panelp = (*panel_it);
|
||||
|
|
@ -193,36 +221,15 @@ bool LLLayoutStack::addChild(LLView* child, S32 tab_group)
|
|||
LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child);
|
||||
if (panelp)
|
||||
{
|
||||
panelp->mFractionalSize = (mOrientation == HORIZONTAL)
|
||||
? panelp->getRect().getWidth()
|
||||
: panelp->getRect().getHeight();
|
||||
panelp->setOrientation(mOrientation);
|
||||
mPanels.push_back(panelp);
|
||||
}
|
||||
return LLView::addChild(child, tab_group);
|
||||
}
|
||||
|
||||
|
||||
S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
|
||||
{
|
||||
// if we are spanning our children (crude upward propagation of size)
|
||||
// then don't enforce our size on our children
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
cur_height = llmax(mMinHeight, getRect().getHeight());
|
||||
}
|
||||
|
||||
return cur_height;
|
||||
}
|
||||
|
||||
S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
|
||||
{
|
||||
// if we are spanning our children (crude upward propagation of size)
|
||||
// then don't enforce our size on our children
|
||||
if (mOrientation == VERTICAL)
|
||||
{
|
||||
cur_width = llmax(mMinWidth, getRect().getWidth());
|
||||
}
|
||||
|
||||
return cur_width;
|
||||
}
|
||||
|
||||
void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front)
|
||||
{
|
||||
LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move);
|
||||
|
|
@ -317,9 +324,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
createResizeBars();
|
||||
|
||||
// calculate current extents
|
||||
S32 total_width = 0;
|
||||
S32 total_height = 0;
|
||||
F32 total_size = 0.f;
|
||||
|
||||
//
|
||||
// animate visibility
|
||||
//
|
||||
e_panel_list_t::iterator panel_it;
|
||||
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
|
||||
{
|
||||
|
|
@ -361,179 +370,110 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
}
|
||||
}
|
||||
|
||||
if (panelp->mCollapsed)
|
||||
{
|
||||
panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
|
||||
}
|
||||
else
|
||||
{
|
||||
panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
|
||||
}
|
||||
F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f;
|
||||
panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
|
||||
|
||||
if (mOrientation == HORIZONTAL)
|
||||
total_size += panelp->mFractionalSize * panelp->getCollapseFactor();
|
||||
// want n-1 panel gaps for n panels
|
||||
if (panel_it != mPanels.begin())
|
||||
{
|
||||
// enforce minimize size constraint by default
|
||||
if (panelp->getRect().getWidth() < panelp->getRelevantMinDim())
|
||||
{
|
||||
panelp->reshape(panelp->getRelevantMinDim(), panelp->getRect().getHeight());
|
||||
}
|
||||
total_width += llround(panelp->getRect().getWidth() * panelp->getCollapseFactor(mOrientation));
|
||||
// want n-1 panel gaps for n panels
|
||||
if (panel_it != mPanels.begin())
|
||||
{
|
||||
total_width += mPanelSpacing;
|
||||
}
|
||||
}
|
||||
else //VERTICAL
|
||||
{
|
||||
// enforce minimize size constraint by default
|
||||
if (panelp->getRect().getHeight() < panelp->getRelevantMinDim())
|
||||
{
|
||||
panelp->reshape(panelp->getRect().getWidth(), panelp->getRelevantMinDim());
|
||||
}
|
||||
total_height += llround(panelp->getRect().getHeight() * panelp->getCollapseFactor(mOrientation));
|
||||
if (panel_it != mPanels.begin())
|
||||
{
|
||||
total_height += mPanelSpacing;
|
||||
}
|
||||
total_size += mPanelSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
S32 num_resizable_panels = 0;
|
||||
S32 shrink_headroom_available = 0;
|
||||
S32 shrink_headroom_total = 0;
|
||||
F32 shrink_headroom_available = 0.f;
|
||||
F32 shrink_headroom_total = 0.f;
|
||||
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
|
||||
{
|
||||
LLLayoutPanel* panelp = (*panel_it);
|
||||
|
||||
// panels that are not fully visible do not count towards shrink headroom
|
||||
if ((*panel_it)->getCollapseFactor(mOrientation) < 1.f)
|
||||
if (panelp->getCollapseFactor() < 1.f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight();
|
||||
S32 relevant_min = (*panel_it)->getRelevantMinDim();
|
||||
F32 cur_size = panelp->mFractionalSize;
|
||||
F32 min_size = (F32)panelp->getRelevantMinDim();
|
||||
|
||||
// if currently resizing a panel or the panel is flagged as not automatically resizing
|
||||
// only track total available headroom, but don't use it for automatic resize logic
|
||||
if ((*panel_it)->mResizeBar->hasMouseCapture()
|
||||
|| (!(*panel_it)->mAutoResize
|
||||
if (panelp->mResizeBar->hasMouseCapture()
|
||||
|| (!panelp->mAutoResize
|
||||
&& !force_resize))
|
||||
{
|
||||
shrink_headroom_total += relevant_dimension - relevant_min;
|
||||
shrink_headroom_total += cur_size - min_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
num_resizable_panels++;
|
||||
|
||||
shrink_headroom_available += relevant_dimension - relevant_min;
|
||||
shrink_headroom_total += relevant_dimension - relevant_min;
|
||||
shrink_headroom_available += cur_size - min_size;
|
||||
shrink_headroom_total += cur_size - min_size;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate how many pixels need to be distributed among layout panels
|
||||
// positive means panels need to grow, negative means shrink
|
||||
S32 pixels_to_distribute;
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
pixels_to_distribute = getRect().getWidth() - total_width;
|
||||
}
|
||||
else //VERTICAL
|
||||
{
|
||||
pixels_to_distribute = getRect().getHeight() - total_height;
|
||||
}
|
||||
F32 pixels_to_distribute = (mOrientation == HORIZONTAL)
|
||||
? getRect().getWidth() - total_size
|
||||
: getRect().getHeight() - total_size;
|
||||
|
||||
// now we distribute the pixels...
|
||||
S32 cur_x = 0;
|
||||
S32 cur_y = getRect().getHeight();
|
||||
F32 cur_x = 0.f;
|
||||
F32 cur_y = (F32)getRect().getHeight();
|
||||
|
||||
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
|
||||
{
|
||||
LLLayoutPanel* panelp = (*panel_it);
|
||||
|
||||
S32 cur_width = panelp->getRect().getWidth();
|
||||
S32 cur_height = panelp->getRect().getHeight();
|
||||
S32 new_width = cur_width;
|
||||
S32 new_height = cur_height;
|
||||
S32 relevant_min = panelp->getRelevantMinDim();
|
||||
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
new_width = llmax(relevant_min, new_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_height = llmax(relevant_min, new_height);
|
||||
}
|
||||
S32 delta_size = 0;
|
||||
F32 min_size = panelp->getRelevantMinDim();
|
||||
F32 delta_size = 0.f;
|
||||
|
||||
// if panel can automatically resize (not animating, and resize flag set)...
|
||||
if (panelp->getCollapseFactor(mOrientation) == 1.f
|
||||
if (panelp->getCollapseFactor() == 1.f
|
||||
&& (force_resize || panelp->mAutoResize)
|
||||
&& !panelp->mResizeBar->hasMouseCapture())
|
||||
{
|
||||
if (mOrientation == HORIZONTAL)
|
||||
if (pixels_to_distribute < 0.f)
|
||||
{
|
||||
// if we're shrinking
|
||||
if (pixels_to_distribute < 0)
|
||||
{
|
||||
// shrink proportionally to amount over minimum
|
||||
// so we can do this in one pass
|
||||
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - relevant_min) / (F32)shrink_headroom_available)) : 0;
|
||||
shrink_headroom_available -= (cur_width - relevant_min);
|
||||
}
|
||||
else
|
||||
{
|
||||
// grow all elements equally
|
||||
delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
|
||||
num_resizable_panels--;
|
||||
}
|
||||
pixels_to_distribute -= delta_size;
|
||||
new_width = llmax(relevant_min, cur_width + delta_size);
|
||||
// shrink proportionally to amount over minimum
|
||||
// so we can do this in one pass
|
||||
delta_size = (shrink_headroom_available > 0.f)
|
||||
? pixels_to_distribute * ((F32)(panelp->mFractionalSize - min_size) / shrink_headroom_available)
|
||||
: 0.f;
|
||||
shrink_headroom_available -= (panelp->mFractionalSize - min_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_width = getDefaultWidth(new_width);
|
||||
}
|
||||
|
||||
if (mOrientation == VERTICAL)
|
||||
{
|
||||
if (pixels_to_distribute < 0)
|
||||
{
|
||||
// shrink proportionally to amount over minimum
|
||||
// so we can do this in one pass
|
||||
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - relevant_min) / (F32)shrink_headroom_available)) : 0;
|
||||
shrink_headroom_available -= (cur_height - relevant_min);
|
||||
}
|
||||
else
|
||||
{
|
||||
delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
|
||||
num_resizable_panels--;
|
||||
}
|
||||
pixels_to_distribute -= delta_size;
|
||||
new_height = llmax(relevant_min, cur_height + delta_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
new_height = getDefaultHeight(new_height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
new_height = getDefaultHeight(new_height);
|
||||
}
|
||||
else // VERTICAL
|
||||
{
|
||||
new_width = getDefaultWidth(new_width);
|
||||
// grow all elements equally
|
||||
delta_size = pixels_to_distribute / (F32)num_resizable_panels;
|
||||
num_resizable_panels--;
|
||||
}
|
||||
|
||||
panelp->mFractionalSize = llmax(min_size, panelp->mFractionalSize + delta_size);
|
||||
pixels_to_distribute -= delta_size;
|
||||
}
|
||||
|
||||
// adjust running headroom count based on new sizes
|
||||
shrink_headroom_total += delta_size;
|
||||
|
||||
LLRect panel_rect;
|
||||
panel_rect.setLeftTopAndSize(cur_x, cur_y, new_width, new_height);
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
panel_rect.setLeftTopAndSize(llround(cur_x),
|
||||
llround(cur_y),
|
||||
llround(panelp->mFractionalSize),
|
||||
getRect().getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
panel_rect.setLeftTopAndSize(llround(cur_x),
|
||||
llround(cur_y),
|
||||
getRect().getWidth(),
|
||||
llround(panelp->mFractionalSize));
|
||||
}
|
||||
panelp->setShape(panel_rect);
|
||||
|
||||
LLRect resize_bar_rect = panel_rect;
|
||||
|
|
@ -549,13 +489,14 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
}
|
||||
(*panel_it)->mResizeBar->setRect(resize_bar_rect);
|
||||
|
||||
F32 size = ((*panel_it)->mFractionalSize * (*panel_it)->getCollapseFactor()) + (F32)mPanelSpacing;
|
||||
if (mOrientation == HORIZONTAL)
|
||||
{
|
||||
cur_x += llround(new_width * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing;
|
||||
cur_x += size;
|
||||
}
|
||||
else //VERTICAL
|
||||
{
|
||||
cur_y -= llround(new_height * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing;
|
||||
cur_y -= size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -570,13 +511,13 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
{
|
||||
(*panel_it)->mResizeBar->setResizeLimits(
|
||||
relevant_min,
|
||||
relevant_min + shrink_headroom_total);
|
||||
relevant_min + llround(shrink_headroom_total));
|
||||
}
|
||||
else //VERTICAL
|
||||
{
|
||||
(*panel_it)->mResizeBar->setResizeLimits(
|
||||
relevant_min,
|
||||
relevant_min + shrink_headroom_total);
|
||||
relevant_min + llround(shrink_headroom_total));
|
||||
}
|
||||
|
||||
// toggle resize bars based on panel visibility, resizability, etc
|
||||
|
|
@ -599,8 +540,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
|
|||
// not enough room to fit existing contents
|
||||
if (force_resize == FALSE
|
||||
// layout did not complete by reaching target position
|
||||
&& ((mOrientation == VERTICAL && cur_y != -mPanelSpacing)
|
||||
|| (mOrientation == HORIZONTAL && cur_x != getRect().getWidth() + mPanelSpacing)))
|
||||
&& ((mOrientation == VERTICAL && llround(cur_y) != -mPanelSpacing)
|
||||
|| (mOrientation == HORIZONTAL && llround(cur_x) != getRect().getWidth() + mPanelSpacing)))
|
||||
{
|
||||
// do another layout pass with all stacked elements contributing
|
||||
// even those that don't usually resize
|
||||
|
|
|
|||
|
|
@ -126,8 +126,6 @@ protected:
|
|||
private:
|
||||
void createResizeBars();
|
||||
void calcMinExtents();
|
||||
S32 getDefaultHeight(S32 cur_height);
|
||||
S32 getDefaultWidth(S32 cur_width);
|
||||
|
||||
const ELayoutOrientation mOrientation;
|
||||
|
||||
|
|
@ -163,24 +161,15 @@ public:
|
|||
Optional<bool> user_resize,
|
||||
auto_resize;
|
||||
|
||||
Params()
|
||||
: expanded_min_dim("expanded_min_dim", 0),
|
||||
min_dim("min_dim", 0),
|
||||
max_dim("max_dim", 0),
|
||||
user_resize("user_resize", true),
|
||||
auto_resize("auto_resize", true)
|
||||
{
|
||||
addSynonym(min_dim, "min_width");
|
||||
addSynonym(min_dim, "min_height");
|
||||
addSynonym(max_dim, "max_width");
|
||||
addSynonym(max_dim, "max_height");
|
||||
}
|
||||
Params();
|
||||
};
|
||||
|
||||
~LLLayoutPanel();
|
||||
|
||||
void initFromParams(const Params& p);
|
||||
|
||||
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
S32 getMinDim() const { return mMinDim; }
|
||||
void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; }
|
||||
|
||||
|
|
@ -202,22 +191,25 @@ public:
|
|||
return min_dim;
|
||||
}
|
||||
|
||||
F32 getCollapseFactor();
|
||||
void setOrientation(LLLayoutStack::ELayoutOrientation orientation) { mOrientation = orientation; }
|
||||
|
||||
protected:
|
||||
LLLayoutPanel(const Params& p);
|
||||
|
||||
F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation);
|
||||
|
||||
bool mExpandedMinDimSpecified;
|
||||
S32 mExpandedMinDim;
|
||||
bool mExpandedMinDimSpecified;
|
||||
S32 mExpandedMinDim;
|
||||
|
||||
S32 mMinDim;
|
||||
S32 mMaxDim;
|
||||
BOOL mAutoResize;
|
||||
BOOL mUserResize;
|
||||
BOOL mCollapsed;
|
||||
S32 mMinDim;
|
||||
S32 mMaxDim;
|
||||
bool mAutoResize;
|
||||
bool mUserResize;
|
||||
bool mCollapsed;
|
||||
F32 mVisibleAmt;
|
||||
F32 mCollapseAmt;
|
||||
F32 mFractionalSize;
|
||||
LLLayoutStack::ELayoutOrientation mOrientation;
|
||||
class LLResizeBar* mResizeBar;
|
||||
F32 mVisibleAmt;
|
||||
F32 mCollapseAmt;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public:
|
|||
|
||||
typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t;
|
||||
|
||||
struct MaxLength : public LLInitParam::Choice<MaxLength>
|
||||
struct MaxLength : public LLInitParam::ChoiceBlock<MaxLength>
|
||||
{
|
||||
Alternative<S32> bytes, chars;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
// Project includes
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lluiimage.h"
|
||||
#include "boost/foreach.hpp"
|
||||
|
||||
// registered in llui.cpp to avoid being left out by MS linker
|
||||
//static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");
|
||||
|
|
@ -51,11 +52,9 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
|
|||
|
||||
void LLLoadingIndicator::initFromParams(const Params& p)
|
||||
{
|
||||
for (LLInitParam::ParamIterator<LLUIImage*>::const_iterator it = p.images().image.begin(), end_it = p.images().image.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
BOOST_FOREACH(LLUIImage* image, p.images.image)
|
||||
{
|
||||
mImages.push_back(it->getValue());
|
||||
mImages.push_back(image);
|
||||
}
|
||||
|
||||
// Start timer for switching images.
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class LLLoadingIndicator
|
|||
LOG_CLASS(LLLoadingIndicator);
|
||||
public:
|
||||
|
||||
struct Images : public LLInitParam::Block<Images>
|
||||
struct Images : public LLInitParam::BatchBlock<Images>
|
||||
{
|
||||
Multiple<LLUIImage*> image;
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ public:
|
|||
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
|
||||
{
|
||||
Optional<F32> images_per_sec;
|
||||
Batch<Images> images;
|
||||
Optional<Images> images;
|
||||
|
||||
Params()
|
||||
: images_per_sec("images_per_sec", 1.0f),
|
||||
|
|
|
|||
|
|
@ -941,9 +941,14 @@ LLMenuItemBranchGL::LLMenuItemBranchGL(const LLMenuItemBranchGL::Params& p)
|
|||
|
||||
LLMenuItemBranchGL::~LLMenuItemBranchGL()
|
||||
{
|
||||
LLView::deleteViewByHandle(mBranchHandle);
|
||||
if (mBranchHandle.get())
|
||||
{
|
||||
mBranchHandle.get()->die();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// virtual
|
||||
LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse) const
|
||||
{
|
||||
|
|
@ -1680,7 +1685,8 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
|
|||
mSpilloverMenu(NULL),
|
||||
mJumpKey(p.jump_key),
|
||||
mCreateJumpKeys(p.create_jump_keys),
|
||||
mNeedsArrange(FALSE),
|
||||
mNeedsArrange(FALSE),
|
||||
mResetScrollPositionOnShow(true),
|
||||
mShortcutPad(p.shortcut_pad)
|
||||
{
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
|
|
@ -1725,7 +1731,7 @@ void LLMenuGL::setCanTearOff(BOOL tear_off)
|
|||
{
|
||||
LLMenuItemTearOffGL::Params p;
|
||||
mTearOffItem = LLUICtrlFactory::create<LLMenuItemTearOffGL>(p);
|
||||
addChildInBack(mTearOffItem);
|
||||
addChild(mTearOffItem);
|
||||
}
|
||||
else if (!tear_off && mTearOffItem != NULL)
|
||||
{
|
||||
|
|
@ -3037,7 +3043,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
|
|||
S32 mouse_x, mouse_y;
|
||||
|
||||
// Resetting scrolling position
|
||||
if (menu->isScrollable())
|
||||
if (menu->isScrollable() && menu->isScrollPositionOnShowReset())
|
||||
{
|
||||
menu->mFirstVisibleItem = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -516,6 +516,9 @@ public:
|
|||
|
||||
static class LLMenuHolderGL* sMenuContainer;
|
||||
|
||||
void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; }
|
||||
bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; }
|
||||
|
||||
protected:
|
||||
void createSpilloverBranch();
|
||||
void cleanupSpilloverBranch();
|
||||
|
|
@ -565,6 +568,7 @@ private:
|
|||
KEY mJumpKey;
|
||||
BOOL mCreateJumpKeys;
|
||||
S32 mShortcutPad;
|
||||
bool mResetScrollPositionOnShow;
|
||||
}; // end class LLMenuGL
|
||||
|
||||
|
||||
|
|
@ -677,7 +681,7 @@ public:
|
|||
|
||||
BOOL appendContextSubMenu(LLContextMenu *menu);
|
||||
|
||||
LLHandle<LLContextMenu> getHandle() { mHandle.bind(this); return mHandle; }
|
||||
LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
|
||||
|
||||
// [SL:KB] - Patch: Misc-Spellcheck | Checked: 2010-12-19 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
|
||||
// NOTE: this is currently only used for spell checking so don't presume this will return something meaningful elsewhere
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
|
|||
|
||||
// update torn off status and remove title bar
|
||||
floaterp->setTornOff(FALSE);
|
||||
floaterp->setTitleVisible(FALSE);
|
||||
// floaterp->setTitleVisible(FALSE);
|
||||
LLRect rect = floaterp->getRect();
|
||||
rect.mTop -= floaterp->getHeaderHeight();
|
||||
floaterp->setRect(rect);
|
||||
|
|
@ -315,7 +315,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)
|
|||
|
||||
// update torn off status and add title bar
|
||||
floaterp->setTornOff(TRUE);
|
||||
floaterp->setTitleVisible(TRUE);
|
||||
// floaterp->setTitleVisible(TRUE);
|
||||
LLRect rect = floaterp->getRect();
|
||||
rect.mTop += floaterp->getHeaderHeight();
|
||||
floaterp->setRect(rect);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
|
||||
const std::string NOTIFICATION_PERSIST_VERSION = "0.93";
|
||||
|
|
@ -416,23 +417,17 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
|
|||
mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound));
|
||||
}
|
||||
|
||||
for(LLInitParam::ParamIterator<LLNotificationTemplate::UniquenessContext>::const_iterator it = p.unique.contexts.begin(),
|
||||
end_it = p.unique.contexts.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
BOOST_FOREACH(const LLNotificationTemplate::UniquenessContext& context, p.unique.contexts)
|
||||
{
|
||||
mUniqueContext.push_back(it->value);
|
||||
mUniqueContext.push_back(context.value);
|
||||
}
|
||||
|
||||
lldebugs << "notification \"" << mName << "\": tag count is " << p.tags.size() << llendl;
|
||||
|
||||
for(LLInitParam::ParamIterator<LLNotificationTemplate::Tag>::const_iterator it = p.tags.begin(),
|
||||
end_it = p.tags.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
BOOST_FOREACH(const LLNotificationTemplate::Tag& tag, p.tags)
|
||||
{
|
||||
lldebugs << " tag \"" << std::string(it->value) << "\"" << llendl;
|
||||
mTags.push_back(it->value);
|
||||
lldebugs << " tag \"" << std::string(tag.value) << "\"" << llendl;
|
||||
mTags.push_back(tag.value);
|
||||
}
|
||||
|
||||
mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form));
|
||||
|
|
@ -1404,14 +1399,12 @@ void replaceFormText(LLNotificationForm::Params& form, const std::string& patter
|
|||
{
|
||||
form.ignore.text = replace;
|
||||
}
|
||||
for (LLInitParam::ParamIterator<LLNotificationForm::FormElement>::iterator it = form.form_elements.elements.begin(),
|
||||
end_it = form.form_elements.elements.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
|
||||
BOOST_FOREACH(LLNotificationForm::FormElement& element, form.form_elements.elements)
|
||||
{
|
||||
if (it->button.isChosen() && it->button.text() == pattern)
|
||||
if (element.button.isChosen() && element.button.text() == pattern)
|
||||
{
|
||||
it->button.text = replace;
|
||||
element.button.text = replace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1460,48 +1453,42 @@ bool LLNotifications::loadTemplates()
|
|||
|
||||
mTemplates.clear();
|
||||
|
||||
for(LLInitParam::ParamIterator<LLNotificationTemplate::GlobalString>::const_iterator it = params.strings.begin(), end_it = params.strings.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
BOOST_FOREACH(LLNotificationTemplate::GlobalString& string, params.strings)
|
||||
{
|
||||
mGlobalStrings[it->name] = it->value;
|
||||
mGlobalStrings[string.name] = string.value;
|
||||
}
|
||||
|
||||
std::map<std::string, LLNotificationForm::Params> form_templates;
|
||||
|
||||
for(LLInitParam::ParamIterator<LLNotificationTemplate::Template>::const_iterator it = params.templates.begin(), end_it = params.templates.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
BOOST_FOREACH(LLNotificationTemplate::Template& notification_template, params.templates)
|
||||
{
|
||||
form_templates[it->name] = it->form;
|
||||
form_templates[notification_template.name] = notification_template.form;
|
||||
}
|
||||
|
||||
for(LLInitParam::ParamIterator<LLNotificationTemplate::Params>::iterator it = params.notifications.begin(), end_it = params.notifications.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
BOOST_FOREACH(LLNotificationTemplate::Params& notification, params.notifications)
|
||||
{
|
||||
if (it->form_ref.form_template.isChosen())
|
||||
if (notification.form_ref.form_template.isChosen())
|
||||
{
|
||||
// replace form contents from template
|
||||
it->form_ref.form = form_templates[it->form_ref.form_template.name];
|
||||
if(it->form_ref.form_template.yes_text.isProvided())
|
||||
notification.form_ref.form = form_templates[notification.form_ref.form_template.name];
|
||||
if(notification.form_ref.form_template.yes_text.isProvided())
|
||||
{
|
||||
replaceFormText(it->form_ref.form, "$yestext", it->form_ref.form_template.yes_text);
|
||||
replaceFormText(notification.form_ref.form, "$yestext", notification.form_ref.form_template.yes_text);
|
||||
}
|
||||
if(it->form_ref.form_template.no_text.isProvided())
|
||||
if(notification.form_ref.form_template.no_text.isProvided())
|
||||
{
|
||||
replaceFormText(it->form_ref.form, "$notext", it->form_ref.form_template.no_text);
|
||||
replaceFormText(notification.form_ref.form, "$notext", notification.form_ref.form_template.no_text);
|
||||
}
|
||||
if(it->form_ref.form_template.cancel_text.isProvided())
|
||||
if(notification.form_ref.form_template.cancel_text.isProvided())
|
||||
{
|
||||
replaceFormText(it->form_ref.form, "$canceltext", it->form_ref.form_template.cancel_text);
|
||||
replaceFormText(notification.form_ref.form, "$canceltext", notification.form_ref.form_template.cancel_text);
|
||||
}
|
||||
if(it->form_ref.form_template.ignore_text.isProvided())
|
||||
if(notification.form_ref.form_template.ignore_text.isProvided())
|
||||
{
|
||||
replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text);
|
||||
replaceFormText(notification.form_ref.form, "$ignoretext", notification.form_ref.form_template.ignore_text);
|
||||
}
|
||||
}
|
||||
mTemplates[it->name] = LLNotificationTemplatePtr(new LLNotificationTemplate(*it));
|
||||
mTemplates[notification.name] = LLNotificationTemplatePtr(new LLNotificationTemplate(notification));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1524,12 +1511,9 @@ bool LLNotifications::loadVisibilityRules()
|
|||
|
||||
mVisibilityRules.clear();
|
||||
|
||||
for(LLInitParam::ParamIterator<LLNotificationVisibilityRule::Rule>::iterator it = params.rules.begin(),
|
||||
end_it = params.rules.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
BOOST_FOREACH(LLNotificationVisibilityRule::Rule& rule, params.rules)
|
||||
{
|
||||
mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(*it)));
|
||||
mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(rule)));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ public:
|
|||
FormInput();
|
||||
};
|
||||
|
||||
struct FormElement : public LLInitParam::Choice<FormElement>
|
||||
struct FormElement : public LLInitParam::ChoiceBlock<FormElement>
|
||||
{
|
||||
Alternative<FormButton> button;
|
||||
Alternative<FormInput> input;
|
||||
|
|
@ -312,7 +312,7 @@ public:
|
|||
Optional<LLNotificationContext*> context;
|
||||
Optional<void*> responder;
|
||||
|
||||
struct Functor : public LLInitParam::Choice<Functor>
|
||||
struct Functor : public LLInitParam::ChoiceBlock<Functor>
|
||||
{
|
||||
Alternative<std::string> name;
|
||||
Alternative<LLNotificationFunctorRegistry::ResponseFunctor> function;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ struct LLNotificationTemplate
|
|||
// <notification> <unique/> </notification>
|
||||
// as well as
|
||||
// <notification> <unique> <context></context> </unique>...
|
||||
Flag dummy_val;
|
||||
Optional<LLInitParam::Flag> dummy_val;
|
||||
public:
|
||||
Multiple<UniquenessContext> contexts;
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ struct LLNotificationTemplate
|
|||
{}
|
||||
};
|
||||
|
||||
struct FormRef : public LLInitParam::Choice<FormRef>
|
||||
struct FormRef : public LLInitParam::ChoiceBlock<FormRef>
|
||||
{
|
||||
Alternative<LLNotificationForm::Params> form;
|
||||
Alternative<TemplateRef> form_template;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ struct LLNotificationVisibilityRule
|
|||
{}
|
||||
};
|
||||
|
||||
struct Rule : public LLInitParam::Choice<Rule>
|
||||
struct Rule : public LLInitParam::ChoiceBlock<Rule>
|
||||
{
|
||||
Alternative<Filter> show;
|
||||
Alternative<Filter> hide;
|
||||
|
|
|
|||
|
|
@ -122,8 +122,6 @@ LLPanel::LLPanel(const LLPanel::Params& p)
|
|||
{
|
||||
addBorder(p.border);
|
||||
}
|
||||
|
||||
mPanelHandle.bind(this);
|
||||
}
|
||||
|
||||
LLPanel::~LLPanel()
|
||||
|
|
|
|||
|
|
@ -96,9 +96,6 @@ public:
|
|||
Params();
|
||||
};
|
||||
|
||||
// valid children for LLPanel are stored in this registry
|
||||
typedef LLDefaultChildRegistry child_registry_t;
|
||||
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8
|
||||
|
|
@ -138,6 +135,8 @@ public:
|
|||
const LLColor4& getBackgroundColor() const { return mBgOpaqueColor; }
|
||||
void setTransparentColor(const LLColor4& color) { mBgAlphaColor = color; }
|
||||
const LLColor4& getTransparentColor() const { return mBgAlphaColor; }
|
||||
void setBackgroundImage(LLUIImage* image) { mBgOpaqueImage = image; }
|
||||
void setTransparentImage(LLUIImage* image) { mBgAlphaImage = image; }
|
||||
LLPointer<LLUIImage> getBackgroundImage() const { return mBgOpaqueImage; }
|
||||
LLPointer<LLUIImage> getTransparentImage() const { return mBgAlphaImage; }
|
||||
LLColor4 getBackgroundImageOverlay() { return mBgOpaqueImageOverlay; }
|
||||
|
|
@ -156,7 +155,7 @@ public:
|
|||
|
||||
void setCtrlsEnabled(BOOL b);
|
||||
|
||||
LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
|
||||
LLHandle<LLPanel> getHandle() const { return getDerivedHandle<LLPanel>(); }
|
||||
|
||||
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
|
||||
|
||||
|
|
@ -281,7 +280,6 @@ private:
|
|||
LLViewBorder* mBorder;
|
||||
LLButton* mDefaultBtn;
|
||||
LLUIString mLabel;
|
||||
LLRootHandle<LLPanel> mPanelHandle;
|
||||
|
||||
typedef std::map<std::string, std::string> ui_string_map_t;
|
||||
ui_string_map_t mUIStrings;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
|
||||
|
||||
void setResizeLimits( S32 min_width, S32 min_height ) { mMinWidth = min_width; mMinHeight = min_height; }
|
||||
|
||||
|
||||
private:
|
||||
BOOL pointInHandle( S32 x, S32 y );
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ public:
|
|||
Optional<ESortDirection, SortNames> sort_direction;
|
||||
Optional<bool> sort_ascending;
|
||||
|
||||
struct Width : public LLInitParam::Choice<Width>
|
||||
struct Width : public LLInitParam::ChoiceBlock<Width>
|
||||
{
|
||||
Alternative<bool> dynamic_width;
|
||||
Alternative<S32> pixel_width;
|
||||
|
|
@ -112,7 +112,7 @@ public:
|
|||
Optional<Width> width;
|
||||
|
||||
// either an image or label is used in column header
|
||||
struct Header : public LLInitParam::Choice<Header>
|
||||
struct Header : public LLInitParam::ChoiceBlock<Header>
|
||||
{
|
||||
Alternative<std::string> label;
|
||||
Alternative<LLUIImage*> image;
|
||||
|
|
|
|||
|
|
@ -483,6 +483,7 @@ void LLScrollListCtrl::updateLayout()
|
|||
{
|
||||
mCommentTextView = getChildView("comment_text");
|
||||
}
|
||||
|
||||
mCommentTextView->setShape(mItemListRect);
|
||||
|
||||
// how many lines of content in a single "page"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue