Merged with Appearance-Misc tip

--HG--
branch : .RLVa
master
Kitty Barnett 2012-04-17 21:44:48 +02:00
commit 6c71e11b2f
925 changed files with 19695 additions and 10293 deletions

View File

@ -67,3 +67,4 @@ glob:indra/newview/filters.xml
glob:indra/newview/avatar_icons_cache.txt
glob:indra/newview/avatar_lad.log
glob:*.diff
*.rej

View File

@ -1 +1 @@
d4a366ed0f30c33e7523dca6ea6d0c469961fe68
ff62e814853d28b800181543816108d445314182

View File

@ -1 +1 @@
286d73ff5c19f6c00e023dc1b60975ed6bbe2872
f8183e357a6f5a3d6d25a8dd0c09fa2bcd45e107

89
.hgtags
View File

@ -228,6 +228,10 @@ c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
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 3.2.4-start
a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
@ -244,7 +248,45 @@ bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
3d2d5d244c6398a4214c666d5dd3965b0918709a 3.2.5-beta1
65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d DRTVWR-107_3.2.5-beta2
65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d 3.2.5-beta2
c6175c955a19e9b9353d242889ec1779b5762522 DRTVWR-105_3.2.5-release
c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
2174ed1c7129562428a5cfe8651ed77b8d26ae18 3.2.6-start
286d73ff5c19f6c00e023dc1b60975ed6bbe2872 DRTVWR-109_3.2.6-beta1
4891c46a56fed7512c783b9cbe7cb7260727bf0c 3.2.7-start
286d73ff5c19f6c00e023dc1b60975ed6bbe2872 3.2.6-beta1
c6175c955a19e9b9353d242889ec1779b5762522 DRTVWR-105_3.2.5-release
c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
3d75c836d178c7c7e788f256afe195f6cab764a2 DRTVWR-111_3.2.7-beta1
3d75c836d178c7c7e788f256afe195f6cab764a2 3.2.7-beta1
89980333c99dbaf1787fe20784f1d8849e9b5d4f 3.2.8-start
16f8e2915f3f2e4d732fb3125daf229cb0fd1875 DRTVWR-114_3.2.8-beta1
16f8e2915f3f2e4d732fb3125daf229cb0fd1875 3.2.8-beta1
987425b1acf4752379b2e1eb20944b4b35d67a85 DRTVWR-115_3.2.8-beta2
987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
51b2fd52e36aab8f670e0874e7e1472434ec4b4a DRTVWR-113_3.2.8-release
51b2fd52e36aab8f670e0874e7e1472434ec4b4a 3.2.8-release
37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
e9c82fca5ae6fb8a8af29012d78fb194a29323f3 DRTVWR-117_3.2.9-beta1
e9c82fca5ae6fb8a8af29012d78fb194a29323f3 3.2.9-beta1
a01ef9bed28627f4ca543fbc1d70c79cc297a90f DRTVWR-118_3.2.9-beta2
a01ef9bed28627f4ca543fbc1d70c79cc297a90f 3.2.9-beta2
987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
d5f263687f43f278107363365938f0a214920a4b DRTVWR-119
d5f263687f43f278107363365938f0a214920a4b 3.3.0-beta1
5e8d2662f38a66eca6c591295f5880d47afc73f7 viewer-release-candidate
5e8d2662f38a66eca6c591295f5880d47afc73f7 3.3.0-release
d5f263687f43f278107363365938f0a214920a4b 3.3.0-start
dffd0457ee0745de65bf95f0642a5c9e46b8e2f0 viewer-beta-candidate
d5f263687f43f278107363365938f0a214920a4b DRTVWR-119
d5f263687f43f278107363365938f0a214920a4b 3.3.0-beta1
5e8d2662f38a66eca6c591295f5880d47afc73f7 viewer-release-candidate
5e8d2662f38a66eca6c591295f5880d47afc73f7 3.3.0-release
28b95a6a28dca3338d9a1f4f204b96678df9f6a5 viewer-beta-candidate
b43cd25be49e3984ff5361cefad020e069131d98 3.3.1-start
3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 DRTVWR-125
b43cd25be49e3984ff5361cefad020e069131d98 3.3.1-start
3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 3.3.1-start
28b95a6a28dca3338d9a1f4f204b96678df9f6a5 3.3.1-beta1
0000000000000000000000000000000000000000 2.1.1-release
0000000000000000000000000000000000000000 v2start
0000000000000000000000000000000000000000 2-1rn1
@ -425,8 +467,6 @@ bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
0000000000000000000000000000000000000000 DRTVWR-86_3.0.2-beta2
0000000000000000000000000000000000000000 3.0.2-beta2
0000000000000000000000000000000000000000 3.0.3-start
0000000000000000000000000000000000000000 DRTVWR-78_3.0.0-release
0000000000000000000000000000000000000000 DRTVWR-78_3.0.0-release
0000000000000000000000000000000000000000 DRTVWR-77_3.0.0-release
0000000000000000000000000000000000000000 DRTVWR-85_3.0.3-beta1
0000000000000000000000000000000000000000 3.0.3-beta1
@ -469,6 +509,10 @@ bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
0000000000000000000000000000000000000000 3.2.3-start
0000000000000000000000000000000000000000 DRTVWR-99_3.2.1-release
0000000000000000000000000000000000000000 3.2.1-release
0000000000000000000000000000000000000000 DRTVWR-60_2.7.1-release
0000000000000000000000000000000000000000 DRTVWR-60_2.7.1-release
0000000000000000000000000000000000000000 2.7.1-release
0000000000000000000000000000000000000000 2.7.1-release
0000000000000000000000000000000000000000 3.2.4-start
0000000000000000000000000000000000000000 DRTVWR-60_2.7.1-release
0000000000000000000000000000000000000000 DRTVWR-60_2.7.1-release
@ -485,7 +529,45 @@ bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
0000000000000000000000000000000000000000 3.2.5-beta1
0000000000000000000000000000000000000000 DRTVWR-107_3.2.5-beta2
0000000000000000000000000000000000000000 3.2.5-beta2
0000000000000000000000000000000000000000 DRTVWR-105_3.2.5-release
0000000000000000000000000000000000000000 3.2.5-release
0000000000000000000000000000000000000000 3.2.6-start
0000000000000000000000000000000000000000 DRTVWR-109_3.2.6-beta1
0000000000000000000000000000000000000000 3.2.7-start
0000000000000000000000000000000000000000 3.2.6-beta1
0000000000000000000000000000000000000000 DRTVWR-105_3.2.5-release
0000000000000000000000000000000000000000 3.2.5-release
0000000000000000000000000000000000000000 DRTVWR-111_3.2.7-beta1
0000000000000000000000000000000000000000 3.2.7-beta1
0000000000000000000000000000000000000000 3.2.8-start
0000000000000000000000000000000000000000 DRTVWR-114_3.2.8-beta1
0000000000000000000000000000000000000000 3.2.8-beta1
0000000000000000000000000000000000000000 DRTVWR-115_3.2.8-beta2
0000000000000000000000000000000000000000 3.2.8-beta2
0000000000000000000000000000000000000000 DRTVWR-113_3.2.8-release
0000000000000000000000000000000000000000 3.2.8-release
0000000000000000000000000000000000000000 3.2.9-start
0000000000000000000000000000000000000000 DRTVWR-117_3.2.9-beta1
0000000000000000000000000000000000000000 3.2.9-beta1
0000000000000000000000000000000000000000 DRTVWR-118_3.2.9-beta2
0000000000000000000000000000000000000000 3.2.9-beta2
0000000000000000000000000000000000000000 3.2.8-beta2
0000000000000000000000000000000000000000 DRTVWR-119
0000000000000000000000000000000000000000 3.3.0-beta1
0000000000000000000000000000000000000000 viewer-release-candidate
0000000000000000000000000000000000000000 3.3.0-release
0000000000000000000000000000000000000000 3.3.0-start
0000000000000000000000000000000000000000 viewer-beta-candidate
0000000000000000000000000000000000000000 DRTVWR-119
0000000000000000000000000000000000000000 3.3.0-beta1
0000000000000000000000000000000000000000 viewer-release-candidate
0000000000000000000000000000000000000000 3.3.0-release
0000000000000000000000000000000000000000 viewer-beta-candidate
0000000000000000000000000000000000000000 3.3.1-start
0000000000000000000000000000000000000000 DRTVWR-125
0000000000000000000000000000000000000000 3.3.1-start
0000000000000000000000000000000000000000 3.3.1-start
0000000000000000000000000000000000000000 3.3.1-beta1
668851b2ef0f8cf8df07a0fba429e4a6c1e70abb SL-2.0.1
b03065d018b8a2e28b7de85b293a4c992cb4c12d SL-2.1.0
bb38ff1a763738609e1b3cada6d15fa61e5e84b9 SL-2.1.1
@ -515,3 +597,6 @@ ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 SL-3.1.0
3150219d229d628f0c15e58e8a51511cbd97e58d SL-3.2.0
a8c7030d6845186fac7c188be4323a0e887b4184 SL-3.2.1
bd6bcde2584491fd9228f1fa51c4575f4e764e19 SL-3.2.4
c6175c955a19e9b9353d242889ec1779b5762522 SL-3.2.5
51b2fd52e36aab8f670e0874e7e1472434ec4b4a SL-3.2.8
5e8d2662f38a66eca6c591295f5880d47afc73f7 SL-3.3.0

View File

@ -35,51 +35,27 @@ viewer-development.build_debug_release_separately = true
# Notifications - to configure email notices, add a setting like this:
# <username>_<reponame>.email = <email-address>
# =================================================================
# Viewer Development (snowstorm canonical build owned by Oz Linden)
# =================================================================
snowstorm_viewer-development.viewer_channel = "Second Life Development"
snowstorm_viewer-development.login_channel = "Second Life Development"
snowstorm_viewer-development.build_viewer_update_version_manager = false
snowstorm_viewer-development.email = viewer-development-builds@lists.secondlife.com
snowstorm_viewer-development.build_enforce_coding_policy = true
snowstorm_viewer-development.codeticket_add_context = true
Snowstorm_viewer-project-review.build_debug_release_separately = true
Snowstorm_viewer-project-review.codeticket_add_context = true
Snowstorm_viewer-project-review.viewer_channel = "Project Viewer - Snowstorm Team"
Snowstorm_viewer-project-review.login_channel = "Project Viewer - Snowstorm Team"
Snowstorm_viewer-project-review.codeticket_add_context = true
# =================================================================
# Canonical viewer integration builds - Oz Linden
# =================================================================
integration_viewer-development.viewer_channel = "Second Life Development"
integration_viewer-development.login_channel = "Second Life Development"
integration_viewer-development.build_viewer_update_version_manager = false
integration_viewer-development.email = viewer-development-builds@lists.secondlife.com
integration_viewer-development.build_enforce_coding_policy = true
integration_viewer-development.codeticket_add_context = true
# ========================================
# Viewer Beta (Owner: Dessie Linden)
# ========================================
viewer-beta.viewer_channel = "Second Life Beta Viewer"
viewer-beta.login_channel = "Second Life Beta Viewer"
viewer-beta.build_debug_release_separately = true
viewer-beta.build_viewer_update_version_manager = true
viewer-pre-beta.viewer_channel = "Second Life Beta Viewer"
viewer-pre-beta.login_channel = "Second Life Beta Viewer"
viewer-pre-beta.build_debug_release_separately = true
viewer-pre-beta.build_viewer_update_version_manager = true
# ========================================
# Viewer Release (Owner: Dessie Linden)
# ========================================
viewer-release.viewer_channel = "Second Life Release"
viewer-release.login_channel = "Second Life Release"
viewer-release.build_debug_release_separately = true
viewer-release.build_viewer_update_version_manager = true
viewer-pre-release.viewer_channel = "Second Life Release"
viewer-pre-release.login_channel = "Second Life Release"
viewer-pre-release.build_debug_release_separately = true
viewer-pre-release.build_viewer_update_version_manager = true
#viewer-pre-release.release-viewer.jira = DRTVWR-92
# ========================================
# mesh-development
# ========================================
@ -140,6 +116,12 @@ viewer-mesh.email = shining@lists.lindenlab.com
# oz
# ================
Snowstorm_viewer-project-review.build_debug_release_separately = true
Snowstorm_viewer-project-review.codeticket_add_context = true
Snowstorm_viewer-project-review.viewer_channel = "Project Viewer - Snowstorm Team"
Snowstorm_viewer-project-review.login_channel = "Project Viewer - Snowstorm Team"
Snowstorm_viewer-project-review.codeticket_add_context = true
oz_viewer-devreview.build_debug_release_separately = true
oz_viewer-devreview.codeticket_add_context = false
oz_viewer-devreview.build_enforce_coding_policy = true

View File

@ -1206,9 +1206,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>26aa7c367ffadd573f61a6a96f820f80</string>
<string>4a98d727561cd1f4ac5ee02907411df1</string>
<key>url</key>
<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>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20120228.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1218,9 +1218,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>c05a33ee8b6f253b5a744596dfc3707d</string>
<string>f50e5f0cc880c55b3f0f7e67dc8f7221</string>
<key>url</key>
<string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-qt4.6-20101013.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/Linux/installer/llqtwebkit-4.7.1-linux-20120228.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@ -1230,9 +1230,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>270db8568a0c4bab266d98e1a820aec4</string>
<string>5e3cd6af397e853a963a6de40d440ff4</string>
<key>url</key>
<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>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20120228.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>

View File

@ -132,10 +132,6 @@ if test -f scripts/update_version_files.py ; then
end_section UpdateVer
fi
# Now retrieve the version for use in the version manager
# First three parts only, $revision will be appended automatically.
build_viewer_update_version_manager_version=`python scripts/get_version.py --viewer-version | sed 's/\.[0-9]*$//'`
if [ -z "$AUTOBUILD" ]
then
export autobuild_dir="$here/../../../autobuild/bin/"

View File

@ -103,6 +103,7 @@ Aleric Inglewood
STORM-163
STORM-955
STORM-960
STORM-1793
Ales Beaumont
VWR-9352
SNOW-240
@ -395,6 +396,8 @@ Frontera Thor
Fury Rosewood
Gaberoonie Zanzibar
Ganymedes Costagravas
Geenz Spad
STORM-1823
Gene Frostbite
GeneJ Composer
Geneko Nemeth
@ -466,6 +469,8 @@ Hiro Sommambulist
VWR-132
VWR-136
VWR-143
Hitomi Tiponi
STORM-1741
Holger Gilruth
Horatio Freund
Hoze Menges
@ -594,19 +599,36 @@ Jonathan Yap
STORM-1659
STORM-1674
STORM-1685
STORM-1718
STORM-1721
STORM-1718
STORM-1727
STORM-1725
STORM-1719
STORM-1712
STORM-1728
STORM-1736
STORM-1804
STORM-1734
STORM-1731
STORM-653
STORM-1737
STORM-1733
STORM-1741
STORM-1790
STORM-1795
STORM-1788
STORM-1803
STORM-1795
STORM-1799
STORM-1796
STORM-1807
STORM-1808
STORM-637
STORM-1822
STORM-1809
STORM-1793
STORM-1810
Kadah Coba
STORM-1060
Jondan Lundquist
@ -642,6 +664,7 @@ Kitty Barnett
STORM-1001
STORM-1175
VWR-24217
STORM-1804
Kolor Fall
Komiko Okamoto
Korvel Noh
@ -849,6 +872,7 @@ Nicky Perian
OPEN-1
STORM-1087
STORM-1090
STORM-1828
Nicoladie Gymnast
Nounouch Hapmouche
VWR-238
@ -1168,6 +1192,8 @@ Unlikely Quintessa
UsikuFarasi Kanarik
Vadim Bigbear
VWR-2681
Vaalith Jinn
STORM-64
Vector Hastings
VWR-8726
Veritas Raymaker
@ -1236,6 +1262,8 @@ WolfPup Lowenhar
VWR-20741
VWR-20933
Wundur Primbee
Xellessanova Zenith
STORM-1793
Xiki Luik
xstorm Radek
YongYong Francois

View File

@ -0,0 +1,15 @@
# -*- cmake -*-
if (VIEWER)
set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
if (INCLUDE_VLD_CMAKE)
if (WINDOWS)
add_definitions(-DINCLUDE_VLD=1)
endif (WINDOWS)
endif (INCLUDE_VLD_CMAKE)
endif (VIEWER)

View File

@ -70,9 +70,10 @@ elseif (LINUX)
QtNetwork
QtGui
QtCore
qgif
qjpeg
jpeg
jscore
# qgif
# qjpeg
# jpeg
fontconfig
X11
Xrender

View File

View File

@ -215,7 +215,7 @@ BOOL LLVorbisDecodeState::initDecode()
return(FALSE);
}
S32 sample_count = ov_pcm_total(&mVF, -1);
S32 sample_count = (S32)ov_pcm_total(&mVF, -1);
size_t size_guess = (size_t)sample_count;
vorbis_info* vi = ov_info(&mVF, -1);
size_guess *= (vi? vi->channels : 1);

View File

@ -1264,6 +1264,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),
@ -1296,16 +1297,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 ;
}
}
}
}
@ -1421,6 +1431,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;
@ -1736,7 +1751,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.
@ -1752,7 +1767,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;

View File

@ -37,6 +37,7 @@
#include "lluuid.h"
#include "llframetimer.h"
#include "llassettype.h"
#include "llextendedstatus.h"
#include "lllistener.h"
@ -334,6 +335,7 @@ protected:
bool mSyncSlave;
bool mQueueSounds;
bool mPlayedOnce;
bool mCorrupted;
S32 mType;
LLVector3d mPositionGlobal;
LLVector3 mVelocity;

View File

@ -1570,7 +1570,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp)
constraint_it++)
{
U8 byte = constraint_it->mChainLength;
dp.packU8(byte, "chain_lenght");
dp.packU8(byte, "chain_length");
byte = constraint_it->mConstraintType;
dp.packU8(byte, "constraint_type");

View File

@ -126,7 +126,7 @@ public:
virtual void addDebugText( const std::string& text ) = 0;
virtual const LLUUID& getID() = 0;
virtual const LLUUID& getID() const = 0;
//-------------------------------------------------------------------------
// End Interface
//-------------------------------------------------------------------------

View File

@ -52,34 +52,11 @@
#include <ctime>
#include <iosfwd>
// Work around Microsoft compiler warnings in STL headers
#ifdef LL_WINDOWS
#pragma warning (disable : 4702) // unreachable code
#pragma warning (disable : 4244) // conversion from time_t to S32
#endif // LL_WINDOWS
// *TODO: Eliminate these, most library .cpp files don't need them.
// Add them to llviewerprecompiledheaders.h if necessary.
#include <list>
#include <map>
#include <vector>
#include <string>
#ifdef LL_WINDOWS
// Reenable warnings we disabled above
#pragma warning (3 : 4702) // unreachable code, we like level 3, not 4
// moved msvc warnings to llpreprocessor.h *TODO - delete this comment after merge conflicts are unlikely -brad
#endif // LL_WINDOWS
// Linden only libs in alpha-order other than stdtypes.h
// *NOTE: Please keep includes here to a minimum, see above.
#include "stdtypes.h"
#include "lldefs.h"
#include "llerror.h"
#include "llextendedstatus.h"
// Don't do this, adds 15K lines of header code to every library file.
//#include "llfasttimer.h"
#include "llfile.h"
#include "llformat.h"
#endif

View File

@ -106,6 +106,11 @@ std::string LLAvatarName::getCompleteName() const
std::string LLAvatarName::getLegacyName() const
{
if (mLegacyFirstName.empty() && mLegacyLastName.empty()) // display names disabled?
{
return mDisplayName;
}
std::string name;
name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() );
name = mLegacyFirstName;

View File

@ -430,13 +430,13 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL
{
// The new node isn't last. Place it between the previous node and
// the successor.
newNode = (myprev + mydmi->second)/2.0;
newNode = (myprev + mydmi->second)/2.f;
}
else
{
// The new node is last. Bump myprev up to the next integer, add
// 1.0 and use that.
newNode = std::ceil(myprev) + 1.0;
newNode = std::ceil(myprev) + 1.f;
}
// Now that newNode has a value that places it appropriately in mSignal,
// connect it.

View File

@ -175,7 +175,7 @@ void LLMD5::update(std::istream& stream){
while (stream.good()){
stream.read( (char*)buffer, BLOCK_LEN); /* Flawfinder: ignore */ // note that return value of read is unusable.
len=stream.gcount();
len=(int)stream.gcount();
update(buffer, len);
}

View File

@ -132,7 +132,7 @@
#pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual"
#pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden
#pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored
#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file
//#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file
#pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation.
#pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
#pragma warning( disable : 4996 ) // warning: deprecated
@ -152,6 +152,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

View File

@ -109,7 +109,7 @@ void LLQueuedThread::shutdown()
// MAIN THREAD
// virtual
S32 LLQueuedThread::update(U32 max_time_ms)
S32 LLQueuedThread::update(F32 max_time_ms)
{
if (!mStarted)
{
@ -122,7 +122,7 @@ S32 LLQueuedThread::update(U32 max_time_ms)
return updateQueue(max_time_ms);
}
S32 LLQueuedThread::updateQueue(U32 max_time_ms)
S32 LLQueuedThread::updateQueue(F32 max_time_ms)
{
F64 max_time = (F64)max_time_ms * .001;
LLTimer timer;

View File

@ -173,8 +173,8 @@ protected:
public:
bool waitForResult(handle_t handle, bool auto_complete = true);
virtual S32 update(U32 max_time_ms);
S32 updateQueue(U32 max_time_ms);
virtual S32 update(F32 max_time_ms);
S32 updateQueue(F32 max_time_ms);
void waitOnPending();
void printQueueStats();

View File

@ -110,7 +110,7 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
if (!strncasecmp(LEGACY_NON_HEADER, hdr_buf, strlen(LEGACY_NON_HEADER))) /* Flawfinder: ignore */
{
legacy_no_header = true;
inbuf = str.gcount();
inbuf = (int)str.gcount();
}
else
{
@ -343,7 +343,7 @@ std::istream& LLSDParser::get(
char delim) const
{
istr.get(s, n, delim);
if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount();
return istr;
}
@ -353,7 +353,7 @@ std::istream& LLSDParser::get(
char delim) const
{
istr.get(sb, delim);
if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount();
return istr;
}
@ -377,7 +377,7 @@ std::istream& LLSDParser::read(
std::streamsize n) const
{
istr.read(s, n);
if(mCheckLimits) mMaxBytesLeft -= istr.gcount();
if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount();
return istr;
}
@ -789,7 +789,7 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const
if(len)
{
value.resize(len);
account(fullread(istr, (char *)&value[0], len));
account((int)fullread(istr, (char *)&value[0], len));
}
c = get(istr); // strip off the trailing double-quote
data = value;
@ -1069,7 +1069,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data) const
if(size > 0)
{
value.resize(size);
account(fullread(istr, (char*)&value[0], size));
account((int)fullread(istr, (char*)&value[0], size));
}
data = value;
}
@ -1200,7 +1200,7 @@ bool LLSDBinaryParser::parseString(
if(size)
{
buf.resize(size);
account(fullread(istr, &buf[0], size));
account((int)fullread(istr, &buf[0], size));
value.assign(buf.begin(), buf.end());
}
return true;
@ -1642,7 +1642,7 @@ int deserialize_string_raw(
const S32 BUF_LEN = 20;
char buf[BUF_LEN]; /* Flawfinder: ignore */
istr.get(buf, BUF_LEN - 1, ')');
count += istr.gcount();
count += (int)istr.gcount();
int c = istr.get();
c = istr.get();
count += 2;
@ -1657,7 +1657,7 @@ int deserialize_string_raw(
if(len)
{
buf.resize(len);
count += fullread(istr, (char *)&buf[0], len);
count += (int)fullread(istr, (char *)&buf[0], len);
value.assign(buf.begin(), buf.end());
}
c = istr.get();

View File

@ -464,7 +464,7 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)
}
}
status = XML_ParseBuffer(mParser, num_read, false);
status = XML_ParseBuffer(mParser, (int)num_read, false);
if (status == XML_STATUS_ERROR)
{
break;

View File

@ -308,7 +308,7 @@ class LLSDParam<T> \
{ \
public: \
LLSDParam(const LLSD& value): \
_value(value.AS()) \
_value((T)value.AS()) \
{} \
\
operator T() const { return _value; } \

View File

@ -593,7 +593,7 @@ void LLStatTime::stop()
{
if ( LLStatAccum::SCALE_PER_FRAME == scale )
{
return mTotalTimeInFrame;
return (F32)mTotalTimeInFrame;
}
else
{

View File

@ -1364,11 +1364,21 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile)
src = LLFile::fopen(srcfile, "rb"); /* Flawfinder: ignore */
if (! src) goto err;
do
while ((bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE, src)) > 0)
{
bytes = (S32)fread(buffer, sizeof(U8), COMPRESS_BUFFER_SIZE,src);
gzwrite(dst, buffer, bytes);
} while(feof(src) == 0);
if (gzwrite(dst, buffer, bytes) <= 0)
{
llwarns << "gzwrite failed: " << gzerror(dst, NULL) << llendl;
goto err;
}
}
if (ferror(src))
{
llwarns << "Error reading " << srcfile << llendl;
goto err;
}
gzclose(dst);
dst = NULL;
#if LL_WINDOWS

View File

@ -337,11 +337,7 @@ LLMutex::~LLMutex()
void LLMutex::lock()
{
#if LL_DARWIN
if (mLockingThread == LLThread::currentID())
#else
if (mLockingThread == sThreadID)
#endif
if(isSelfLocked())
{ //redundant lock
mCount++;
return;
@ -398,6 +394,15 @@ bool LLMutex::isLocked()
}
}
bool LLMutex::isSelfLocked()
{
#if LL_DARWIN
return mLockingThread == LLThread::currentID();
#else
return mLockingThread == sThreadID;
#endif
}
U32 LLMutex::lockingThread() const
{
return mLockingThread;

View File

@ -151,6 +151,7 @@ public:
void lock(); // blocks
void unlock();
bool isLocked(); // non-blocking, but does do a lock/unlock so not free
bool isSelfLocked(); //return true if locked in a same thread
U32 lockingThread() const; //get ID of locking thread
protected:

View File

@ -83,7 +83,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
{
// max_yields is unused; just fiddle with it to avoid warnings.
max_yields = 0;
ms_sleep(us / 1000);
ms_sleep((U32)(us / 1000));
return 0;
}
#elif LL_LINUX || LL_SOLARIS || LL_DARWIN

View File

@ -28,8 +28,8 @@
#define LL_LLVERSIONVIEWER_H
const S32 LL_VERSION_MAJOR = 3;
const S32 LL_VERSION_MINOR = 2;
const S32 LL_VERSION_PATCH = 6;
const S32 LL_VERSION_MINOR = 3;
const S32 LL_VERSION_PATCH = 2;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";

View File

@ -81,7 +81,7 @@ void LLWorkerThread::clearDeleteList()
}
// virtual
S32 LLWorkerThread::update(U32 max_time_ms)
S32 LLWorkerThread::update(F32 max_time_ms)
{
S32 res = LLQueuedThread::update(max_time_ms);
// Delete scheduled workers

View File

@ -86,7 +86,7 @@ public:
LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false);
~LLWorkerThread();
/*virtual*/ S32 update(U32 max_time_ms);
/*virtual*/ S32 update(F32 max_time_ms);
handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL);

View File

@ -250,7 +250,7 @@ void LLCrashLogger::gatherFiles()
if(minidump_stream.is_open())
{
minidump_stream.seekg(0, std::ios::end);
size_t length = minidump_stream.tellg();
size_t length = (size_t)minidump_stream.tellg();
minidump_stream.seekg(0, std::ios::beg);
LLSD::Binary data;

View File

@ -501,10 +501,10 @@ void LLImageCompressionTester::outputTestRecord(LLSD *sd)
F32 decompressionRate = 0.0f;
F32 compressionRate = 0.0f;
F32 totalkBInDecompression = (F32)(mTotalBytesInDecompression) / 1000.0;
F32 totalkBOutDecompression = (F32)(mTotalBytesOutDecompression) / 1000.0;
F32 totalkBInCompression = (F32)(mTotalBytesInCompression) / 1000.0;
F32 totalkBOutCompression = (F32)(mTotalBytesOutCompression) / 1000.0;
F32 totalkBInDecompression = (F32)(mTotalBytesInDecompression) / 1000.f;
F32 totalkBOutDecompression = (F32)(mTotalBytesOutDecompression) / 1000.f;
F32 totalkBInCompression = (F32)(mTotalBytesInCompression) / 1000.f;
F32 totalkBOutCompression = (F32)(mTotalBytesOutCompression) / 1000.f;
if (!is_approx_zero(mTotalTimeDecompression))
{

View File

@ -60,6 +60,12 @@ BOOL LLImagePNG::updateData()
// Decode the PNG data and extract sizing information
LLPngWrapper pngWrapper;
if (!pngWrapper.isValidPng(getData()))
{
setLastError("LLImagePNG data does not have a valid PNG header!");
return FALSE;
}
LLPngWrapper::ImageInfo infop;
if (! pngWrapper.readPng(getData(), NULL, &infop))
{
@ -90,6 +96,12 @@ BOOL LLImagePNG::decode(LLImageRaw* raw_image, F32 decode_time)
// Decode the PNG data into the raw image
LLPngWrapper pngWrapper;
if (!pngWrapper.isValidPng(getData()))
{
setLastError("LLImagePNG data does not have a valid PNG header!");
return FALSE;
}
if (! pngWrapper.readPng(getData(), raw_image))
{
setLastError(pngWrapper.getErrorMessage());

View File

@ -46,7 +46,7 @@ LLImageDecodeThread::~LLImageDecodeThread()
// MAIN THREAD
// virtual
S32 LLImageDecodeThread::update(U32 max_time_ms)
S32 LLImageDecodeThread::update(F32 max_time_ms)
{
LLMutexLock lock(mCreationMutex);
for (creation_list_t::iterator iter = mCreationList.begin();

View File

@ -78,7 +78,7 @@ public:
handle_t decodeImage(LLImageFormatted* image,
U32 priority, S32 discard, BOOL needs_aux,
Responder* responder);
S32 update(U32 max_time_ms);
S32 update(F32 max_time_ms);
// Used by unit tests to check the consistency of the thread instance
S32 tut_size();

View File

@ -405,7 +405,7 @@ U32 LLInventoryItem::getCRC32() const
//lldebugs << "7 crc: " << std::hex << crc << std::dec << llendl;
crc += mSaleInfo.getCRC32();
//lldebugs << "8 crc: " << std::hex << crc << std::dec << llendl;
crc += mCreationDate;
crc += (U32)mCreationDate;
//lldebugs << "9 crc: " << std::hex << crc << std::dec << llendl;
return crc;
}
@ -521,7 +521,7 @@ void LLInventoryItem::packMessage(LLMessageSystem* msg) const
mSaleInfo.packMessage(msg);
msg->addStringFast(_PREHASH_Name, mName);
msg->addStringFast(_PREHASH_Description, mDescription);
msg->addS32Fast(_PREHASH_CreationDate, mCreationDate);
msg->addS32Fast(_PREHASH_CreationDate, (S32)mCreationDate);
U32 crc = getCRC32();
msg->addU32Fast(_PREHASH_CRC, crc);
}

View File

@ -174,7 +174,7 @@ private:
F32 _log(const F32& a) const { return log(a); }
F32 _exp(const F32& a) const { return exp(a); }
F32 _fabs(const F32& a) const { return fabs(a); }
F32 _floor(const F32& a) const { return llfloor(a); }
F32 _floor(const F32& a) const { return (F32)llfloor(a); }
F32 _ceil(const F32& a) const { return llceil(a); }
F32 _atan2(const F32& a,const F32& b) const { return atan2(a,b); }

View File

@ -26,80 +26,87 @@
#ifndef LL_LLCOORD_H
#define LL_LLCOORD_H
template<typename> class LLCoord;
struct LL_COORD_TYPE_GL;
struct LL_COORD_TYPE_WINDOW;
struct LL_COORD_TYPE_SCREEN;
typedef LLCoord<LL_COORD_TYPE_GL> LLCoordGL;
typedef LLCoord<LL_COORD_TYPE_WINDOW> LLCoordWindow;
typedef LLCoord<LL_COORD_TYPE_SCREEN> LLCoordScreen;
struct LLCoordCommon
{
LLCoordCommon(S32 x, S32 y) : mX(x), mY(y) {}
LLCoordCommon() : mX(0), mY(0) {}
S32 mX;
S32 mY;
};
// A two-dimensional pixel value
class LLCoord
template<typename COORD_FRAME>
class LLCoord : protected COORD_FRAME
{
public:
S32 mX;
S32 mY;
typedef LLCoord<COORD_FRAME> self_t;
typename COORD_FRAME::value_t mX;
typename COORD_FRAME::value_t mY;
LLCoord(): mX(0), mY(0)
{}
LLCoord(S32 x, S32 y): mX(x), mY(y)
{}
virtual ~LLCoord()
LLCoord(typename COORD_FRAME::value_t x, typename COORD_FRAME::value_t y): mX(x), mY(y)
{}
virtual void set(S32 x, S32 y) { mX = x; mY = y; }
LLCoord(const LLCoordCommon& other)
{
COORD_FRAME::convertFromCommon(other);
}
LLCoordCommon convert() const
{
return COORD_FRAME::convertToCommon();
}
void set(typename COORD_FRAME::value_t x, typename COORD_FRAME::value_t y) { mX = x; mY = y;}
bool operator==(const self_t& other) const { return mX == other.mX && mY == other.mY; }
bool operator!=(const self_t& other) const { return !(*this == other); }
static const self_t& getTypedCoords(const COORD_FRAME& self) { return static_cast<const self_t&>(self); }
static self_t& getTypedCoords(COORD_FRAME& self) { return static_cast<self_t&>(self); }
};
// GL coordinates start in the client region of a window,
// with left, bottom = 0, 0
class LLCoordGL : public LLCoord
struct LL_COORD_TYPE_GL
{
public:
LLCoordGL() : LLCoord()
{}
LLCoordGL(S32 x, S32 y) : LLCoord(x, y)
{}
bool operator==(const LLCoordGL& other) const { return mX == other.mX && mY == other.mY; }
bool operator!=(const LLCoordGL& other) const { return !(*this == other); }
typedef S32 value_t;
LLCoordCommon convertToCommon() const
{
const LLCoordGL& self = LLCoordGL::getTypedCoords(*this);
return LLCoordCommon(self.mX, self.mY);
}
void convertFromCommon(const LLCoordCommon& from)
{
LLCoordGL& self = LLCoordGL::getTypedCoords(*this);
self.mX = from.mX;
self.mY = from.mY;
}
};
//bool operator ==(const LLCoordGL& a, const LLCoordGL& b);
// Window coords include things like window borders,
// menu regions, etc.
class LLCoordWindow : public LLCoord
struct LL_COORD_TYPE_WINDOW
{
public:
LLCoordWindow() : LLCoord()
{}
LLCoordWindow(S32 x, S32 y) : LLCoord(x, y)
{}
bool operator==(const LLCoordWindow& other) const { return mX == other.mX && mY == other.mY; }
bool operator!=(const LLCoordWindow& other) const { return !(*this == other); }
typedef S32 value_t;
LLCoordCommon convertToCommon() const;
void convertFromCommon(const LLCoordCommon& from);
};
// Screen coords start at left, top = 0, 0
class LLCoordScreen : public LLCoord
struct LL_COORD_TYPE_SCREEN
{
public:
LLCoordScreen() : LLCoord()
{}
LLCoordScreen(S32 x, S32 y) : LLCoord(x, y)
{}
bool operator==(const LLCoordScreen& other) const { return mX == other.mX && mY == other.mY; }
bool operator!=(const LLCoordScreen& other) const { return !(*this == other); }
};
typedef S32 value_t;
class LLCoordFont : public LLCoord
{
public:
F32 mZ;
LLCoordFont() : LLCoord(), mZ(0.f)
{}
LLCoordFont(S32 x, S32 y, F32 z = 0) : LLCoord(x,y), mZ(z)
{}
void set(S32 x, S32 y) { LLCoord::set(x,y); mZ = 0.f; }
void set(S32 x, S32 y, F32 z) { mX = x; mY = y; mZ = z; }
bool operator==(const LLCoordFont& other) const { return mX == other.mX && mY == other.mY; }
bool operator!=(const LLCoordFont& other) const { return !(*this == other); }
LLCoordCommon convertToCommon() const;
void convertFromCommon(const LLCoordCommon& from);
};
#endif

View File

@ -80,8 +80,8 @@ public:
typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
typedef typename std::set<LLPointer<T> > element_list;
typedef typename std::set<LLPointer<T> >::iterator element_iter;
typedef typename std::set<LLPointer<T> >::const_iterator const_element_iter;
typedef typename element_list::iterator element_iter;
typedef typename element_list::const_iterator const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
typedef typename std::vector<LLOctreeNode<T>* > child_list;
typedef LLTreeNode<T> BaseType;
@ -114,6 +114,8 @@ public:
mOctant = ((oct_node*) mParent)->getOctant(mCenter);
}
mElementCount = 0;
clearChildren();
}
@ -219,11 +221,11 @@ public:
void accept(oct_traveler* visitor) { visitor->visit(this); }
virtual bool isLeaf() const { return mChild.empty(); }
U32 getElementCount() const { return mData.size(); }
U32 getElementCount() const { return mElementCount; }
element_list& getData() { return mData; }
const element_list& getData() const { return mData; }
U32 getChildCount() const { return mChild.size(); }
U32 getChildCount() const { return mChildCount; }
oct_node* getChild(U32 index) { return mChild[index]; }
const oct_node* getChild(U32 index) const { return mChild[index]; }
child_list& getChildren() { return mChild; }
@ -300,17 +302,13 @@ public:
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
{ //it belongs here
#if LL_OCTREE_PARANOIA_CHECK
//if this is a redundant insertion, error out (should never happen)
if (mData.find(data) != mData.end())
{
llwarns << "Redundant octree insertion detected. " << data << llendl;
return false;
}
#endif
llassert(mData.find(data) == mData.end());
mData.insert(data);
BaseType::insert(data);
mElementCount = mData.size();
return true;
}
else
@ -346,6 +344,8 @@ public:
{
mData.insert(data);
BaseType::insert(data);
mElementCount = mData.size();
return true;
}
@ -399,6 +399,7 @@ public:
if (mData.find(data) != mData.end())
{ //we have data
mData.erase(data);
mElementCount = mData.size();
notifyRemoval(data);
checkAlive();
return true;
@ -436,6 +437,7 @@ public:
if (mData.find(data) != mData.end())
{
mData.erase(data);
mElementCount = mData.size();
notifyRemoval(data);
llwarns << "FOUND!" << llendl;
checkAlive();
@ -452,7 +454,7 @@ public:
void clearChildren()
{
mChild.clear();
mChildCount = 0;
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
}
@ -512,9 +514,10 @@ public:
}
#endif
mChildMap[child->getOctant()] = (U8) mChild.size();
mChildMap[child->getOctant()] = mChildCount;
mChild.push_back(child);
++mChildCount;
child->setParent(this);
if (!silent)
@ -534,21 +537,20 @@ public:
oct_listener* listener = getOctListener(i);
listener->handleChildRemoval(this, getChild(index));
}
if (destroy)
{
mChild[index]->destroy();
delete mChild[index];
}
mChild.erase(mChild.begin() + index);
--mChildCount;
//rebuild child map
U32* foo = (U32*) mChildMap;
foo[0] = foo[1] = 0xFFFFFFFF;
for (U32 i = 0; i < mChild.size(); ++i)
for (U32 i = 0; i < mChildCount; ++i)
{
mChildMap[mChild[i]->getOctant()] = i;
}
@ -601,8 +603,10 @@ protected:
child_list mChild;
U8 mChildMap[8];
U32 mChildCount;
element_list mData;
U32 mElementCount;
};

View File

@ -2078,6 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mFaceMask = 0x0;
mDetail = detail;
mSculptLevel = -2;
mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims
mIsMeshAssetLoaded = FALSE;
mLODScaleBias.setVec(1,1,1);
mHullPoints = NULL;
@ -2903,7 +2904,7 @@ F32 LLVolume::sculptGetSurfaceArea()
// compute the area of the quad by taking the length of the cross product of the two triangles
LLVector3 cross1 = (p1 - p2) % (p1 - p3);
LLVector3 cross2 = (p4 - p2) % (p4 - p3);
area += (cross1.magVec() + cross2.magVec()) / 2.0;
area += (cross1.magVec() + cross2.magVec()) / 2.f;
}
}
@ -3144,6 +3145,8 @@ void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
{
F32 area = sculptGetSurfaceArea();
mSurfaceArea = area;
const F32 SCULPT_MAX_AREA = 384.f;
if (area < SCULPT_MIN_AREA || area > SCULPT_MAX_AREA)
@ -4617,18 +4620,83 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en
genBinormals(i);
}
if (!face.mOctree)
{
face.createOctree();
}
//LLVector4a* p = (LLVector4a*) face.mPositions;
if (isUnique())
{ //don't bother with an octree for flexi volumes
U32 tri_count = face.mNumIndices/3;
LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
intersect.traverse(face.mOctree);
if (intersect.mHitFace)
for (U32 j = 0; j < tri_count; ++j)
{
U16 idx0 = face.mIndices[j*3+0];
U16 idx1 = face.mIndices[j*3+1];
U16 idx2 = face.mIndices[j*3+2];
const LLVector4a& v0 = face.mPositions[idx0];
const LLVector4a& v1 = face.mPositions[idx1];
const LLVector4a& v2 = face.mPositions[idx2];
F32 a,b,t;
if (LLTriangleRayIntersect(v0, v1, v2,
start, dir, a, b, t))
{
if ((t >= 0.f) && // if hit is after start
(t <= 1.f) && // and before end
(t < closest_t)) // and this hit is closer
{
closest_t = t;
hit_face = i;
if (intersection != NULL)
{
LLVector4a intersect = dir;
intersect.mul(closest_t);
intersect.add(start);
intersection->set(intersect.getF32ptr());
}
if (tex_coord != NULL)
{
LLVector2* tc = (LLVector2*) face.mTexCoords;
*tex_coord = ((1.f - a - b) * tc[idx0] +
a * tc[idx1] +
b * tc[idx2]);
}
if (normal!= NULL)
{
LLVector4* norm = (LLVector4*) face.mNormals;
*normal = ((1.f - a - b) * LLVector3(norm[idx0]) +
a * LLVector3(norm[idx1]) +
b * LLVector3(norm[idx2]));
}
if (bi_normal != NULL)
{
LLVector4* binormal = (LLVector4*) face.mBinormals;
*bi_normal = ((1.f - a - b) * LLVector3(binormal[idx0]) +
a * LLVector3(binormal[idx1]) +
b * LLVector3(binormal[idx2]));
}
}
}
}
}
else
{
hit_face = i;
if (!face.mOctree)
{
face.createOctree();
}
LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, bi_normal);
intersect.traverse(face.mOctree);
if (intersect.mHitFace)
{
hit_face = i;
}
}
}
}
@ -5822,7 +5890,7 @@ F32 find_vertex_score(LLVCacheVertexData& data)
}
//bonus points for having low valence
F32 valence_boost = powf(data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
F32 valence_boost = powf((F32)data.mActiveTriangles, -FindVertexScore_ValenceBoostPower);
score += FindVertexScore_ValenceBoostScale * valence_boost;
return score;

View File

@ -963,6 +963,7 @@ public:
S32 getNumFaces() const;
S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
F32 getDetail() const { return mDetail; }
F32 getSurfaceArea() const { return mSurfaceArea; }
const LLVolumeParams& getParams() const { return mParams; }
LLVolumeParams getCopyOfParams() const { return mParams; }
const LLProfile& getProfile() const { return *mProfilep; }
@ -1065,6 +1066,7 @@ public:
BOOL mUnique;
F32 mDetail;
S32 mSculptLevel;
F32 mSurfaceArea; //unscaled surface area
BOOL mIsMeshAssetLoaded;
LLVolumeParams mParams;

View File

@ -858,25 +858,25 @@ LLSD LLMatrix4::getValue() const
void LLMatrix4::setValue(const LLSD& data)
{
mMatrix[0][0] = data[0].asReal();
mMatrix[0][1] = data[1].asReal();
mMatrix[0][2] = data[2].asReal();
mMatrix[0][3] = data[3].asReal();
mMatrix[0][0] = (F32)data[0].asReal();
mMatrix[0][1] = (F32)data[1].asReal();
mMatrix[0][2] = (F32)data[2].asReal();
mMatrix[0][3] = (F32)data[3].asReal();
mMatrix[1][0] = data[4].asReal();
mMatrix[1][1] = data[5].asReal();
mMatrix[1][2] = data[6].asReal();
mMatrix[1][3] = data[7].asReal();
mMatrix[1][0] = (F32)data[4].asReal();
mMatrix[1][1] = (F32)data[5].asReal();
mMatrix[1][2] = (F32)data[6].asReal();
mMatrix[1][3] = (F32)data[7].asReal();
mMatrix[2][0] = data[8].asReal();
mMatrix[2][1] = data[9].asReal();
mMatrix[2][2] = data[10].asReal();
mMatrix[2][3] = data[11].asReal();
mMatrix[2][0] = (F32)data[8].asReal();
mMatrix[2][1] = (F32)data[9].asReal();
mMatrix[2][2] = (F32)data[10].asReal();
mMatrix[2][3] = (F32)data[11].asReal();
mMatrix[3][0] = data[12].asReal();
mMatrix[3][1] = data[13].asReal();
mMatrix[3][2] = data[14].asReal();
mMatrix[3][3] = data[15].asReal();
mMatrix[3][0] = (F32)data[12].asReal();
mMatrix[3][1] = (F32)data[13].asReal();
mMatrix[3][2] = (F32)data[14].asReal();
mMatrix[3][3] = (F32)data[15].asReal();
}

View File

@ -32,6 +32,9 @@
#include "llmath.h"
#include "llmemtype.h"
#include "llstl.h"
#include "llthread.h"
#define ASSERT_LLBUFFERARRAY_MUTEX_LOCKED llassert(!mMutexp || mMutexp->isSelfLocked());
/**
* LLSegment
@ -224,7 +227,8 @@ void LLHeapBuffer::allocate(S32 size)
* LLBufferArray
*/
LLBufferArray::LLBufferArray() :
mNextBaseChannel(0)
mNextBaseChannel(0),
mMutexp(NULL)
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
}
@ -233,6 +237,8 @@ LLBufferArray::~LLBufferArray()
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer());
delete mMutexp;
}
// static
@ -243,14 +249,57 @@ LLChannelDescriptors LLBufferArray::makeChannelConsumer(
return rv;
}
void LLBufferArray::lock()
{
if(mMutexp)
{
mMutexp->lock() ;
}
}
void LLBufferArray::unlock()
{
if(mMutexp)
{
mMutexp->unlock() ;
}
}
LLMutex* LLBufferArray::getMutex()
{
return mMutexp ;
}
void LLBufferArray::setThreaded(bool threaded)
{
if(threaded)
{
if(!mMutexp)
{
mMutexp = new LLMutex(NULL);
}
}
else
{
if(mMutexp)
{
delete mMutexp ;
mMutexp = NULL ;
}
}
}
LLChannelDescriptors LLBufferArray::nextChannel()
{
LLChannelDescriptors rv(mNextBaseChannel++);
return rv;
}
//mMutexp should be locked before calling this.
S32 LLBufferArray::capacity() const
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
S32 total = 0;
const_buffer_iterator_t iter = mBuffers.begin();
const_buffer_iterator_t end = mBuffers.end();
@ -263,6 +312,8 @@ S32 LLBufferArray::capacity() const
bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
{
LLMutexLock lock(mMutexp) ;
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
if(copyIntoBuffers(channel, src, len, segments))
@ -273,8 +324,11 @@ bool LLBufferArray::append(S32 channel, const U8* src, S32 len)
return false;
}
//mMutexp should be locked before calling this.
bool LLBufferArray::prepend(S32 channel, const U8* src, S32 len)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
if(copyIntoBuffers(channel, src, len, segments))
@ -293,6 +347,8 @@ bool LLBufferArray::insertAfter(
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
std::vector<LLSegment> segments;
LLMutexLock lock(mMutexp) ;
if(mSegments.end() != segment)
{
++segment;
@ -305,8 +361,11 @@ bool LLBufferArray::insertAfter(
return false;
}
//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
segment_iterator_t end = mSegments.end();
segment_iterator_t it = getSegment(address);
@ -335,20 +394,26 @@ LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
return rv;
}
//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::beginSegment()
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
return mSegments.begin();
}
//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::endSegment()
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
return mSegments.end();
}
//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
U8* address,
LLSegment& segment)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
segment_iterator_t rv = mSegments.begin();
segment_iterator_t end = mSegments.end();
@ -395,8 +460,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
return rv;
}
//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
segment_iterator_t end = mSegments.end();
if(!address)
{
@ -414,9 +481,11 @@ LLBufferArray::segment_iterator_t LLBufferArray::getSegment(U8* address)
return end;
}
//mMutexp should be locked before calling this.
LLBufferArray::const_segment_iterator_t LLBufferArray::getSegment(
U8* address) const
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
const_segment_iterator_t end = mSegments.end();
if(!address)
{
@ -466,6 +535,8 @@ S32 LLBufferArray::countAfter(S32 channel, U8* start) const
S32 count = 0;
S32 offset = 0;
const_segment_iterator_t it;
LLMutexLock lock(mMutexp) ;
const_segment_iterator_t end = mSegments.end();
if(start)
{
@ -517,6 +588,8 @@ U8* LLBufferArray::readAfter(
len = 0;
S32 bytes_to_copy = 0;
const_segment_iterator_t it;
LLMutexLock lock(mMutexp) ;
const_segment_iterator_t end = mSegments.end();
if(start)
{
@ -568,6 +641,7 @@ U8* LLBufferArray::seek(
U8* start,
S32 delta) const
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
const_segment_iterator_t it;
const_segment_iterator_t end = mSegments.end();
@ -709,9 +783,14 @@ U8* LLBufferArray::seek(
return rv;
}
//test use only
bool LLBufferArray::takeContents(LLBufferArray& source)
{
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
LLMutexLock lock(mMutexp);
source.lock();
std::copy(
source.mBuffers.begin(),
source.mBuffers.end(),
@ -723,13 +802,17 @@ bool LLBufferArray::takeContents(LLBufferArray& source)
std::back_insert_iterator<segment_list_t>(mSegments));
source.mSegments.clear();
source.mNextBaseChannel = 0;
source.unlock();
return true;
}
//mMutexp should be locked before calling this.
LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
S32 channel,
S32 len)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// start at the end of the buffers, because it is the most likely
// to have free space.
@ -765,8 +848,10 @@ LLBufferArray::segment_iterator_t LLBufferArray::makeSegment(
return send;
}
//mMutexp should be locked before calling this.
bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
// Find out which buffer contains the segment, and if it is found,
@ -792,13 +877,14 @@ bool LLBufferArray::eraseSegment(const segment_iterator_t& erase_iter)
return rv;
}
//mMutexp should be locked before calling this.
bool LLBufferArray::copyIntoBuffers(
S32 channel,
const U8* src,
S32 len,
std::vector<LLSegment>& segments)
{
ASSERT_LLBUFFERARRAY_MUTEX_LOCKED
LLMemType m1(LLMemType::MTYPE_IO_BUFFER);
if(!src || !len) return false;
S32 copied = 0;

View File

@ -39,6 +39,7 @@
#include <list>
#include <vector>
class LLMutex;
/**
* @class LLChannelDescriptors
* @brief A way simple interface to accesss channels inside a buffer
@ -564,6 +565,29 @@ public:
* @return Returns true on success.
*/
bool eraseSegment(const segment_iterator_t& iter);
/**
* @brief Lock the mutex if it exists
* This method locks mMutexp to make accessing LLBufferArray thread-safe
*/
void lock();
/**
* @brief Unlock the mutex if it exists
*/
void unlock();
/**
* @brief Return mMutexp
*/
LLMutex* getMutex();
/**
* @brief Set LLBufferArray to be shared across threads or not
* This method is to create mMutexp if is threaded.
* @param threaded Indicates this LLBufferArray instance is shared across threads if true.
*/
void setThreaded(bool threaded);
//@}
protected:
@ -595,6 +619,7 @@ protected:
S32 mNextBaseChannel;
buffer_list_t mBuffers;
segment_list_t mSegments;
LLMutex* mMutexp;
};
#endif // LL_LLBUFFER_H

View File

@ -31,6 +31,7 @@
#include "llbuffer.h"
#include "llmemtype.h"
#include "llthread.h"
static const S32 DEFAULT_OUTPUT_SEGMENT_SIZE = 1024 * 4;
@ -62,6 +63,7 @@ int LLBufferStreamBuf::underflow()
return EOF;
}
LLMutexLock lock(mBuffer->getMutex());
LLBufferArray::segment_iterator_t iter;
LLBufferArray::segment_iterator_t end = mBuffer->endSegment();
U8* last_pos = (U8*)gptr();
@ -149,6 +151,7 @@ int LLBufferStreamBuf::overflow(int c)
// since we got here, we have a buffer, and we have a character to
// put on it.
LLBufferArray::segment_iterator_t it;
LLMutexLock lock(mBuffer->getMutex());
it = mBuffer->makeSegment(mChannels.out(), DEFAULT_OUTPUT_SEGMENT_SIZE);
if(it != mBuffer->endSegment())
{
@ -210,6 +213,7 @@ int LLBufferStreamBuf::sync()
// *NOTE: I bet we could just --address if address is not NULL.
// Need to think about that.
LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.out(), address, -1);
if(address)
{
@ -273,6 +277,8 @@ streampos LLBufferStreamBuf::seekoff(
// NULL is fine
break;
}
LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.in(), base_addr, off);
if(address)
{
@ -304,6 +310,8 @@ streampos LLBufferStreamBuf::seekoff(
// NULL is fine
break;
}
LLMutexLock lock(mBuffer->getMutex());
address = mBuffer->seek(mChannels.out(), base_addr, off);
if(address)
{

View File

@ -72,10 +72,9 @@
static const U32 EASY_HANDLE_POOL_SIZE = 5;
static const S32 MULTI_PERFORM_CALL_REPEAT = 5;
static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds
static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation
static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
static
// DEBUG //
S32 gCurlEasyCount = 0;
S32 gCurlMultiCount = 0;
@ -87,6 +86,11 @@ std::vector<LLMutex*> LLCurl::sSSLMutex;
std::string LLCurl::sCAPath;
std::string LLCurl::sCAFile;
LLCurlThread* LLCurl::sCurlThread = NULL ;
LLMutex* LLCurl::sHandleMutexp = NULL ;
S32 LLCurl::sTotalHandles = 0 ;
bool LLCurl::sNotQuitting = true;
F32 LLCurl::sCurlRequestTimeOut = 120.f; //seonds
S32 LLCurl::sMaxHandles = 256; //max number of handles, (multi handles and easy handles combined).
void check_curl_code(CURLcode code)
{
@ -224,13 +228,15 @@ LLMutex* LLCurl::Easy::sHandleMutexp = NULL ;
//static
CURL* LLCurl::Easy::allocEasyHandle()
{
llassert(LLCurl::getCurlThread()) ;
CURL* ret = NULL;
LLMutexLock lock(sHandleMutexp) ;
if (sFreeHandles.empty())
{
ret = curl_easy_init();
ret = LLCurl::newEasyHandle();
}
else
{
@ -250,18 +256,29 @@ CURL* LLCurl::Easy::allocEasyHandle()
//static
void LLCurl::Easy::releaseEasyHandle(CURL* handle)
{
static const S32 MAX_NUM_FREE_HANDLES = 32 ;
if (!handle)
{
llerrs << "handle cannot be NULL!" << llendl;
return ; //handle allocation failed.
//llerrs << "handle cannot be NULL!" << llendl;
}
LLMutexLock lock(sHandleMutexp) ;
if (sActiveHandles.find(handle) != sActiveHandles.end())
{
sActiveHandles.erase(handle);
if(sFreeHandles.size() < MAX_NUM_FREE_HANDLES)
{
sFreeHandles.insert(handle);
}
else
{
LLCurl::deleteEasyHandle(handle) ;
}
}
else
{
llerrs << "Invalid handle." << llendl;
}
@ -302,6 +319,14 @@ LLCurl::Easy::~Easy()
--gCurlEasyCount;
curl_slist_free_all(mHeaders);
for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
if (mResponder && LLCurl::sNotQuitting) //aborted
{
std::string reason("Request timeout, aborted.") ;
mResponder->completedRaw(408, //HTTP_REQUEST_TIME_OUT, timeout, abort
reason, mChannels, mOutput);
}
mResponder = NULL;
}
void LLCurl::Easy::resetState()
@ -428,9 +453,9 @@ size_t curlReadCallback(char* data, size_t size, size_t nmemb, void* user_data)
LLCurl::Easy* easy = (LLCurl::Easy*)user_data;
S32 n = size * nmemb;
S32 startpos = easy->getInput().tellg();
S32 startpos = (S32)easy->getInput().tellg();
easy->getInput().seekg(0, std::ios::end);
S32 endpos = easy->getInput().tellg();
S32 endpos = (S32)easy->getInput().tellg();
easy->getInput().seekg(startpos, std::ios::beg);
S32 maxn = endpos - startpos;
n = llmin(n, maxn);
@ -474,6 +499,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
LLProxy::getInstance()->applyProxySettings(this);
mOutput.reset(new LLBufferArray);
mOutput->setThreaded(true);
setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback);
setopt(CURLOPT_WRITEDATA, (void*)this);
@ -517,8 +543,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
}
////////////////////////////////////////////////////////////////////////////
LLMutex* LLCurl::Multi::sMultiInitMutexp = NULL ;
LLCurl::Multi::Multi()
LLCurl::Multi::Multi(F32 idle_time_out)
: mQueued(0),
mErrorCount(0),
mState(STATE_READY),
@ -527,15 +552,17 @@ LLCurl::Multi::Multi()
mDeletionMutexp(NULL),
mEasyMutexp(NULL)
{
mCurlMultiHandle = initMulti();
mCurlMultiHandle = LLCurl::newMultiHandle();
if (!mCurlMultiHandle)
{
llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
mCurlMultiHandle = initMulti();
mCurlMultiHandle = LLCurl::newMultiHandle();
}
llassert_always(mCurlMultiHandle);
//llassert_always(mCurlMultiHandle);
if(mCurlMultiHandle)
{
if(LLCurl::getCurlThread()->getThreaded())
{
mMutexp = new LLMutex(NULL) ;
@ -544,11 +571,28 @@ LLCurl::Multi::Multi()
}
LLCurl::getCurlThread()->addMulti(this) ;
mIdleTimeOut = idle_time_out ;
if(mIdleTimeOut < LLCurl::sCurlRequestTimeOut)
{
mIdleTimeOut = LLCurl::sCurlRequestTimeOut ;
}
++gCurlMultiCount;
}
}
LLCurl::Multi::~Multi()
{
cleanup() ;
}
void LLCurl::Multi::cleanup()
{
if(!mCurlMultiHandle)
{
return ; //nothing to clean.
}
// Clean up active
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
iter != mEasyActiveList.end(); ++iter)
@ -564,7 +608,8 @@ LLCurl::Multi::~Multi()
for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());
mEasyFreeList.clear();
check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));
check_curl_multi_code(LLCurl::deleteMultiHandle(mCurlMultiHandle));
mCurlMultiHandle = NULL ;
delete mMutexp ;
mMutexp = NULL ;
@ -573,14 +618,12 @@ LLCurl::Multi::~Multi()
delete mEasyMutexp ;
mEasyMutexp = NULL ;
mQueued = 0 ;
mState = STATE_COMPLETED;
--gCurlMultiCount;
}
CURLM* LLCurl::Multi::initMulti()
{
LLMutexLock lock(sMultiInitMutexp) ;
return curl_multi_init() ;
return ;
}
void LLCurl::Multi::lock()
@ -604,6 +647,7 @@ void LLCurl::Multi::markDead()
LLMutexLock lock(mDeletionMutexp) ;
mDead = TRUE ;
LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
}
void LLCurl::Multi::setState(LLCurl::Multi::ePerformState state)
@ -630,6 +674,11 @@ bool LLCurl::Multi::isCompleted()
bool LLCurl::Multi::waitToComplete()
{
if(!isValid())
{
return true ;
}
if(!mMutexp) //not threaded
{
doPerform() ;
@ -639,7 +688,7 @@ bool LLCurl::Multi::waitToComplete()
bool completed = (STATE_COMPLETED == mState) ;
if(!completed)
{
LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_URGENT) ;
LLCurl::getCurlThread()->setPriority(mHandle, LLQueuedThread::PRIORITY_HIGH) ;
}
return completed;
@ -675,6 +724,10 @@ bool LLCurl::Multi::doPerform()
call_count++)
{
LLMutexLock lock(mMutexp) ;
//WARNING: curl_multi_perform will block for many hundreds of milliseconds
// NEVER call this from the main thread, and NEVER allow the main thread to
// wait on a mutex held by this thread while curl_multi_perform is executing
CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
{
@ -686,6 +739,11 @@ bool LLCurl::Multi::doPerform()
mQueued = q;
setState(STATE_COMPLETED) ;
mIdleTimer.reset() ;
}
else if(mIdleTimer.getElapsedTimeF32() > mIdleTimeOut) //idle for too long, remove it.
{
dead = true ;
}
return dead ;
@ -693,6 +751,11 @@ bool LLCurl::Multi::doPerform()
S32 LLCurl::Multi::process()
{
if(!isValid())
{
return 0 ;
}
waitToComplete() ;
if (getState() != STATE_COMPLETED)
@ -845,35 +908,41 @@ bool LLCurlThread::CurlRequest::processRequest()
if(mMulti)
{
completed = mCurlThread->doMultiPerform(mMulti) ;
if(!completed)
{
setPriority(LLQueuedThread::PRIORITY_LOW) ;
}
}
return completed ;
}
void LLCurlThread::CurlRequest::finishRequest(bool completed)
{
if(mMulti->isDead())
{
mCurlThread->deleteMulti(mMulti) ;
}
else
{
mCurlThread->cleanupMulti(mMulti) ; //being idle too long, remove the request.
}
mMulti = NULL ;
}
LLCurlThread::LLCurlThread(bool threaded) :
LLQueuedThread("curlthread", threaded)
{
if(!LLCurl::Multi::sMultiInitMutexp)
{
LLCurl::Multi::sMultiInitMutexp = new LLMutex(NULL) ;
}
}
//virtual
LLCurlThread::~LLCurlThread()
{
delete LLCurl::Multi::sMultiInitMutexp ;
LLCurl::Multi::sMultiInitMutexp = NULL ;
}
S32 LLCurlThread::update(U32 max_time_ms)
S32 LLCurlThread::update(F32 max_time_ms)
{
return LLQueuedThread::update(max_time_ms);
}
@ -892,8 +961,20 @@ void LLCurlThread::addMulti(LLCurl::Multi* multi)
void LLCurlThread::killMulti(LLCurl::Multi* multi)
{
if(!multi)
{
return ;
}
if(multi->isValid())
{
multi->markDead() ;
}
else
{
deleteMulti(multi) ;
}
}
//private
bool LLCurlThread::doMultiPerform(LLCurl::Multi* multi)
@ -906,6 +987,13 @@ void LLCurlThread::deleteMulti(LLCurl::Multi* multi)
{
delete multi ;
}
//private
void LLCurlThread::cleanupMulti(LLCurl::Multi* multi)
{
multi->cleanup() ;
}
//------------------------------------------------------------
//static
@ -938,6 +1026,13 @@ LLCurlRequest::~LLCurlRequest()
void LLCurlRequest::addMulti()
{
LLCurl::Multi* multi = new LLCurl::Multi();
if(!multi->isValid())
{
LLCurl::getCurlThread()->killMulti(multi) ;
mActiveMulti = NULL ;
mActiveRequestCount = 0 ;
return;
}
mMultiSet.insert(multi);
mActiveMulti = multi;
@ -952,7 +1047,12 @@ LLCurl::Easy* LLCurlRequest::allocEasy()
{
addMulti();
}
llassert_always(mActiveMulti);
if(!mActiveMulti)
{
return NULL ;
}
//llassert_always(mActiveMulti);
++mActiveRequestCount;
LLCurl::Easy* easy = mActiveMulti->allocEasy();
return easy;
@ -1062,6 +1162,19 @@ S32 LLCurlRequest::process()
{
curlmulti_set_t::iterator curiter = iter++;
LLCurl::Multi* multi = *curiter;
if(!multi->isValid())
{
if(multi == mActiveMulti)
{
mActiveMulti = NULL ;
mActiveRequestCount = 0 ;
}
mMultiSet.erase(curiter) ;
LLCurl::getCurlThread()->killMulti(multi) ;
continue ;
}
S32 tres = multi->process();
res += tres;
if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
@ -1082,6 +1195,19 @@ S32 LLCurlRequest::getQueued()
{
curlmulti_set_t::iterator curiter = iter++;
LLCurl::Multi* multi = *curiter;
if(!multi->isValid())
{
if(multi == mActiveMulti)
{
mActiveMulti = NULL ;
mActiveRequestCount = 0 ;
}
LLCurl::getCurlThread()->killMulti(multi);
mMultiSet.erase(curiter) ;
continue ;
}
queued += multi->mQueued;
if (multi->getState() != LLCurl::Multi::STATE_READY)
{
@ -1101,6 +1227,8 @@ LLCurlEasyRequest::LLCurlEasyRequest()
{
mMulti = new LLCurl::Multi();
if(mMulti->isValid())
{
mEasy = mMulti->allocEasy();
if (mEasy)
{
@ -1110,6 +1238,13 @@ LLCurlEasyRequest::LLCurlEasyRequest()
LLProxy::getInstance()->applyProxySettings(mEasy);
}
}
else
{
LLCurl::getCurlThread()->killMulti(mMulti) ;
mEasy = NULL ;
mMulti = NULL ;
}
}
LLCurlEasyRequest::~LLCurlEasyRequest()
{
@ -1118,7 +1253,7 @@ LLCurlEasyRequest::~LLCurlEasyRequest()
void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
{
if (mEasy)
if (isValid() && mEasy)
{
mEasy->setopt(option, value);
}
@ -1126,7 +1261,7 @@ void LLCurlEasyRequest::setopt(CURLoption option, S32 value)
void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value)
{
if (mEasy)
if (isValid() && mEasy)
{
mEasy->setoptString(option, value);
}
@ -1134,7 +1269,7 @@ void LLCurlEasyRequest::setoptString(CURLoption option, const std::string& value
void LLCurlEasyRequest::setPost(char* postdata, S32 size)
{
if (mEasy)
if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_POST, 1);
mEasy->setopt(CURLOPT_POSTFIELDS, postdata);
@ -1144,7 +1279,7 @@ void LLCurlEasyRequest::setPost(char* postdata, S32 size)
void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* userdata)
{
if (mEasy)
if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_HEADERFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_HEADERDATA, userdata); // aka CURLOPT_WRITEHEADER
@ -1153,7 +1288,7 @@ void LLCurlEasyRequest::setHeaderCallback(curl_header_callback callback, void* u
void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* userdata)
{
if (mEasy)
if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_WRITEFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_WRITEDATA, userdata);
@ -1162,7 +1297,7 @@ void LLCurlEasyRequest::setWriteCallback(curl_write_callback callback, void* use
void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userdata)
{
if (mEasy)
if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_READFUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_READDATA, userdata);
@ -1171,7 +1306,7 @@ void LLCurlEasyRequest::setReadCallback(curl_read_callback callback, void* userd
void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void* userdata)
{
if (mEasy)
if (isValid() && mEasy)
{
mEasy->setopt(CURLOPT_SSL_CTX_FUNCTION, (void*)callback);
mEasy->setopt(CURLOPT_SSL_CTX_DATA, userdata);
@ -1180,7 +1315,7 @@ void LLCurlEasyRequest::setSSLCtxCallback(curl_ssl_ctx_callback callback, void*
void LLCurlEasyRequest::slist_append(const char* str)
{
if (mEasy)
if (isValid() && mEasy)
{
mEasy->slist_append(str);
}
@ -1191,7 +1326,7 @@ void LLCurlEasyRequest::sendRequest(const std::string& url)
llassert_always(!mRequestSent);
mRequestSent = true;
lldebugs << url << llendl;
if (mEasy)
if (isValid() && mEasy)
{
mEasy->setHeaders();
mEasy->setoptString(CURLOPT_URL, url);
@ -1203,7 +1338,7 @@ void LLCurlEasyRequest::requestComplete()
{
llassert_always(mRequestSent);
mRequestSent = false;
if (mEasy)
if (isValid() && mEasy)
{
mMulti->removeEasy(mEasy);
}
@ -1212,6 +1347,10 @@ void LLCurlEasyRequest::requestComplete()
// Usage: Call getRestult until it returns false (no more messages)
bool LLCurlEasyRequest::getResult(CURLcode* result, LLCurl::TransferInfo* info)
{
if(!isValid())
{
return false ;
}
if (!mMulti->isCompleted())
{ //we're busy, try again later
return false;
@ -1276,7 +1415,7 @@ CURLMsg* LLCurlEasyRequest::info_read(S32* q, LLCurl::TransferInfo* info)
std::string LLCurlEasyRequest::getErrorString()
{
return mEasy ? std::string(mEasy->getErrorBuffer()) : std::string();
return isValid() && mEasy ? std::string(mEasy->getErrorBuffer()) : std::string();
}
////////////////////////////////////////////////////////////////////////////
@ -1302,8 +1441,11 @@ unsigned long LLCurl::ssl_thread_id(void)
}
#endif
void LLCurl::initClass(bool multi_threaded)
void LLCurl::initClass(F32 curl_reuest_timeout, S32 max_number_handles, bool multi_threaded)
{
sCurlRequestTimeOut = curl_reuest_timeout ; //seconds
sMaxHandles = max_number_handles ; //max number of handles, (multi handles and easy handles combined).
// Do not change this "unless you are familiar with and mean to control
// internal operations of libcurl"
// - http://curl.haxx.se/libcurl/c/curl_global_init.html
@ -1324,12 +1466,15 @@ void LLCurl::initClass(bool multi_threaded)
sCurlThread = new LLCurlThread(multi_threaded) ;
if(multi_threaded)
{
sHandleMutexp = new LLMutex(NULL) ;
Easy::sHandleMutexp = new LLMutex(NULL) ;
}
}
void LLCurl::cleanupClass()
{
sNotQuitting = false; //set quitting
//shut down curl thread
while(1)
{
@ -1350,7 +1495,7 @@ void LLCurl::cleanupClass()
for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
{
CURL* curl = *iter;
curl_easy_cleanup(curl);
LLCurl::deleteEasyHandle(curl);
}
Easy::sFreeHandles.clear();
@ -1358,9 +1503,77 @@ void LLCurl::cleanupClass()
delete Easy::sHandleMutexp ;
Easy::sHandleMutexp = NULL ;
delete sHandleMutexp ;
sHandleMutexp = NULL ;
llassert(Easy::sActiveHandles.empty());
}
//static
CURLM* LLCurl::newMultiHandle()
{
LLMutexLock lock(sHandleMutexp) ;
if(sTotalHandles + 1 > sMaxHandles)
{
llwarns << "no more handles available." << llendl ;
return NULL ; //failed
}
sTotalHandles++;
CURLM* ret = curl_multi_init() ;
if(!ret)
{
llwarns << "curl_multi_init failed." << llendl ;
}
return ret ;
}
//static
CURLMcode LLCurl::deleteMultiHandle(CURLM* handle)
{
if(handle)
{
LLMutexLock lock(sHandleMutexp) ;
sTotalHandles-- ;
return curl_multi_cleanup(handle) ;
}
return CURLM_OK ;
}
//static
CURL* LLCurl::newEasyHandle()
{
LLMutexLock lock(sHandleMutexp) ;
if(sTotalHandles + 1 > sMaxHandles)
{
llwarns << "no more handles available." << llendl ;
return NULL ; //failed
}
sTotalHandles++;
CURL* ret = curl_easy_init() ;
if(!ret)
{
llwarns << "curl_easy_init failed." << llendl ;
}
return ret ;
}
//static
void LLCurl::deleteEasyHandle(CURL* handle)
{
if(handle)
{
LLMutexLock lock(sHandleMutexp) ;
curl_easy_cleanup(handle) ;
sTotalHandles-- ;
}
}
const unsigned int LLCurl::MAX_REDIRECTS = 5;
// Provide access to LLCurl free functions outside of llcurl.cpp without polluting the global namespace.

View File

@ -43,6 +43,7 @@
#include "llsd.h"
#include "llthread.h"
#include "llqueuedthread.h"
#include "llframetimer.h"
class LLMutex;
class LLCurlThread;
@ -162,7 +163,7 @@ public:
/**
* @ brief Initialize LLCurl class
*/
static void initClass(bool multi_threaded = false);
static void initClass(F32 curl_reuest_timeout = 120.f, S32 max_number_handles = 256, bool multi_threaded = false);
/**
* @ brief Cleanup LLCurl class
@ -182,11 +183,24 @@ public:
static unsigned long ssl_thread_id(void);
static LLCurlThread* getCurlThread() { return sCurlThread ;}
static CURLM* newMultiHandle() ;
static CURLMcode deleteMultiHandle(CURLM* handle) ;
static CURL* newEasyHandle() ;
static void deleteEasyHandle(CURL* handle) ;
private:
static std::string sCAPath;
static std::string sCAFile;
static const unsigned int MAX_REDIRECTS;
static LLCurlThread* sCurlThread;
static LLMutex* sHandleMutexp ;
static S32 sTotalHandles ;
static S32 sMaxHandles;
public:
static bool sNotQuitting;
static F32 sCurlRequestTimeOut;
};
class LLCurl::Easy
@ -277,7 +291,7 @@ public:
STATE_COMPLETED=2
} ePerformState;
Multi();
Multi(F32 idle_time_out = 0.f);
LLCurl::Easy* allocEasy();
bool addEasy(LLCurl::Easy* easy);
@ -288,7 +302,10 @@ public:
void setState(ePerformState state) ;
ePerformState getState() ;
bool isCompleted() ;
bool isValid() {return mCurlMultiHandle != NULL ;}
bool isDead() {return mDead;}
bool waitToComplete() ;
@ -299,9 +316,9 @@ public:
S32 mQueued;
S32 mErrorCount;
static CURLM* initMulti() ;
private:
void easyFree(LLCurl::Easy*);
void cleanup() ;
CURLM* mCurlMultiHandle;
@ -319,8 +336,8 @@ private:
LLMutex* mMutexp ;
LLMutex* mDeletionMutexp ;
LLMutex* mEasyMutexp ;
static LLMutex* sMultiInitMutexp ;
LLFrameTimer mIdleTimer ;
F32 mIdleTimeOut;
};
class LLCurlThread : public LLQueuedThread
@ -349,7 +366,7 @@ public:
LLCurlThread(bool threaded = true) ;
virtual ~LLCurlThread() ;
S32 update(U32 max_time_ms);
S32 update(F32 max_time_ms);
void addMulti(LLCurl::Multi* multi) ;
void killMulti(LLCurl::Multi* multi) ;
@ -357,6 +374,7 @@ public:
private:
bool doMultiPerform(LLCurl::Multi* multi) ;
void deleteMulti(LLCurl::Multi* multi) ;
void cleanupMulti(LLCurl::Multi* multi) ;
} ;
namespace boost
@ -414,6 +432,7 @@ public:
std::string getErrorString();
bool isCompleted() {return mMulti->isCompleted() ;}
bool wait() { return mMulti->waitToComplete(); }
bool isValid() {return mMulti && mMulti->isValid(); }
LLCurl::Easy* getEasy() const { return mEasy; }

View File

@ -232,7 +232,8 @@ LLSD LLHTTPAssetRequest::getFullDetails() const
void LLHTTPAssetRequest::setupCurlHandle()
{
// *NOTE: Similar code exists in mapserver/llcurlutil.cpp JC
mCurlHandle = curl_easy_init();
mCurlHandle = LLCurl::newEasyHandle();
llassert_always(mCurlHandle != NULL) ;
// Apply proxy settings if configured to do so
LLProxy::getInstance()->applyProxySettings(mCurlHandle);
@ -278,7 +279,7 @@ void LLHTTPAssetRequest::setupCurlHandle()
void LLHTTPAssetRequest::cleanupCurlHandle()
{
curl_easy_cleanup(mCurlHandle);
LLCurl::deleteEasyHandle(mCurlHandle);
if (mAssetStoragep)
{
// Terminating a request. Thus upload or download is no longer pending.
@ -429,12 +430,13 @@ void LLHTTPAssetStorage::_init(const std::string& web_host, const std::string& l
// curl_global_init moved to LLCurl::initClass()
mCurlMultiHandle = curl_multi_init();
mCurlMultiHandle = LLCurl::newMultiHandle() ;
llassert_always(mCurlMultiHandle != NULL) ;
}
LLHTTPAssetStorage::~LLHTTPAssetStorage()
{
curl_multi_cleanup(mCurlMultiHandle);
LLCurl::deleteMultiHandle(mCurlMultiHandle);
mCurlMultiHandle = NULL;
// curl_global_cleanup moved to LLCurl::initClass()

View File

@ -158,7 +158,7 @@ namespace
if(fstream.is_open())
{
fstream.seekg(0, std::ios::end);
U32 fileSize = fstream.tellg();
U32 fileSize = (U32)fstream.tellg();
fstream.seekg(0, std::ios::beg);
std::vector<char> fileBuffer(fileSize);
fstream.read(&fileBuffer[0], fileSize);
@ -228,6 +228,12 @@ static void request(
LLPumpIO::chain_t chain;
LLURLRequest* req = new LLURLRequest(method, url);
if(!req->isValid())//failed
{
delete req ;
return ;
}
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
@ -423,7 +429,9 @@ static LLSD blocking_request(
{
lldebugs << "blockingRequest of " << url << llendl;
char curl_error_buffer[CURL_ERROR_SIZE] = "\0";
CURL* curlp = curl_easy_init();
CURL* curlp = LLCurl::newEasyHandle();
llassert_always(curlp != NULL) ;
LLHTTPBuffer http_buffer;
std::string body_str;
@ -517,7 +525,7 @@ static LLSD blocking_request(
}
// * Cleanup
curl_easy_cleanup(curlp);
LLCurl::deleteEasyHandle(curlp);
return response;
}

View File

@ -818,6 +818,8 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
// Copy everything after mLast read to the out.
LLBufferArray::segment_iterator_t seg_iter;
buffer->lock();
seg_iter = buffer->splitAfter(mLastRead);
if(seg_iter != buffer->endSegment())
{
@ -838,7 +840,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(
}
#endif
}
buffer->unlock();
//
// *FIX: get rid of extra bytes off the end
//

View File

@ -75,6 +75,12 @@ LLIOPipe::~LLIOPipe()
//lldebugs << "destroying LLIOPipe" << llendl;
}
//virtual
bool LLIOPipe::isValid()
{
return true ;
}
// static
std::string LLIOPipe::lookupStatusString(EStatus status)
{

View File

@ -231,6 +231,8 @@ public:
*/
virtual ~LLIOPipe();
virtual bool isValid() ;
protected:
/**
* @brief Base Constructor.

View File

@ -445,6 +445,7 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
// efficient - not only because writev() is better, but also
// because we won't have to do as much work to find the start
// address.
buffer->lock();
LLBufferArray::segment_iterator_t it;
LLBufferArray::segment_iterator_t end = buffer->endSegment();
LLSegment segment;
@ -524,6 +525,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
}
}
buffer->unlock();
PUMP_DEBUG;
if(done && eos)
{

View File

@ -388,7 +388,7 @@ bool LLMimeParser::Impl::parseHeaders(
// not to read past limit when we get() the newline.
S32 max_get = llmin((S32)LINE_BUFFER_LENGTH, limit - mScanCount - 1);
istr.getline(mBuffer, max_get, '\r');
mScanCount += istr.gcount();
mScanCount += (S32)istr.gcount();
int c = istr.get();
if(EOF == c)
{
@ -496,7 +496,7 @@ void LLMimeParser::Impl::scanPastSeparator(
// past limit when we get() the newline.
S32 max_get = llmin((S32)LINE_BUFFER_LENGTH, limit - mScanCount - 1);
istr.getline(mBuffer, max_get, '\r');
mScanCount += istr.gcount();
mScanCount += (S32)istr.gcount();
if(istr.gcount() >= LINE_BUFFER_LENGTH - 1)
{
// that's way too long to be a separator, so ignore it.

View File

@ -195,7 +195,7 @@ bool LLPumpIO::prime(apr_pool_t* pool)
return ((pool == NULL) ? false : true);
}
bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
if(chain.empty()) return false;
@ -204,8 +204,10 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout)
LLScopedLock lock(mChainsMutex);
#endif
LLChainInfo info;
info.mHasCurlRequest = has_curl_request;
info.setTimeoutSeconds(timeout);
info.mData = LLIOPipe::buffer_ptr_t(new LLBufferArray);
info.mData->setThreaded(has_curl_request);
LLLinkInfo link;
#if LL_DEBUG_PIPE_TYPE_IN_PUMP
lldebugs << "LLPumpIO::addChain() " << chain[0] << " '"
@ -440,6 +442,15 @@ void LLPumpIO::pump()
static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain)
{
std::for_each(
(*run_chain).mDescriptors.begin(),
(*run_chain).mDescriptors.end(),
ll_delete_apr_pollset_fd_client_data());
return mRunningChains.erase(run_chain);
}
//timeout is in microseconds
void LLPumpIO::pump(const S32& poll_timeout)
{
@ -585,10 +596,16 @@ void LLPumpIO::pump(const S32& poll_timeout)
// << (*run_chain).mChainLinks[0].mPipe
// << " because we reached the end." << llendl;
#endif
run_chain = mRunningChains.erase(run_chain);
run_chain = removeRunningChain(run_chain);
continue;
}
}
else if(isChainExpired(*run_chain))
{
run_chain = removeRunningChain(run_chain);
continue;
}
PUMP_DEBUG;
if((*run_chain).mLock)
{
@ -696,11 +713,7 @@ void LLPumpIO::pump(const S32& poll_timeout)
PUMP_DEBUG;
// This chain is done. Clean up any allocated memory and
// erase the chain info.
std::for_each(
(*run_chain).mDescriptors.begin(),
(*run_chain).mDescriptors.end(),
ll_delete_apr_pollset_fd_client_data());
run_chain = mRunningChains.erase(run_chain);
run_chain = removeRunningChain(run_chain);
// *NOTE: may not always need to rebuild the pollset.
mRebuildPollset = true;
@ -1095,6 +1108,24 @@ void LLPumpIO::processChain(LLChainInfo& chain)
PUMP_DEBUG;
}
bool LLPumpIO::isChainExpired(LLChainInfo& chain)
{
if(!chain.mHasCurlRequest)
{
return false ;
}
for(links_t::iterator iter = chain.mChainLinks.begin(); iter != chain.mChainLinks.end(); ++iter)
{
if(!(*iter).mPipe->isValid())
{
return true ;
}
}
return false ;
}
bool LLPumpIO::handleChainError(
LLChainInfo& chain,
LLIOPipe::EStatus error)
@ -1136,6 +1167,9 @@ bool LLPumpIO::handleChainError(
#endif
keep_going = false;
break;
case LLIOPipe::STATUS_EXPIRED:
keep_going = false;
break ;
default:
if(LLIOPipe::isSuccess(error))
{
@ -1157,7 +1191,8 @@ bool LLPumpIO::handleChainError(
LLPumpIO::LLChainInfo::LLChainInfo() :
mInit(false),
mLock(0),
mEOS(false)
mEOS(false),
mHasCurlRequest(false)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS);

View File

@ -111,9 +111,10 @@ public:
* @param chain The pipes for the chain
* @param timeout The number of seconds in the future to
* expire. Pass in 0.0f to never expire.
* @param has_curl_request The chain contains LLURLRequest if true.
* @return Returns true if anything was added to the pump.
*/
bool addChain(const chain_t& chain, F32 timeout);
bool addChain(const chain_t& chain, F32 timeout, bool has_curl_request = false);
/**
* @brief Struct to associate a pipe with it's buffer io indexes.
@ -356,12 +357,13 @@ protected:
// basic member data
bool mInit;
bool mEOS;
bool mHasCurlRequest;
S32 mLock;
LLFrameTimer mTimer;
links_t::iterator mHead;
links_t mChainLinks;
LLIOPipe::buffer_ptr_t mData;
bool mEOS;
LLIOPipe::buffer_ptr_t mData;
LLSD mContext;
// tracking inside the pump
@ -402,7 +404,7 @@ protected:
protected:
void initialize(apr_pool_t* pool);
void cleanup();
current_chain_t removeRunningChain(current_chain_t& chain) ;
/**
* @brief Given the internal state of the chains, rebuild the pollset
* @see setConditional()
@ -429,6 +431,9 @@ protected:
*/
bool handleChainError(LLChainInfo& chain, LLIOPipe::EStatus error);
//if the chain is expired, remove it
bool isChainExpired(LLChainInfo& chain) ;
public:
/**
* @brief Return number of running chains.

View File

@ -88,7 +88,7 @@ bool LLSDMessage::httpListener(const LLSD& request)
request,
url, "POST", reply, error),
LLSD(), // headers
timeout);
(F32)timeout);
return false;
}

View File

@ -317,7 +317,7 @@ void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data)
// S64 not supported in LLSD so we just truncate it
case MVT_S64:
addS32(varname, *(S64*)mvci.getData());
addS32(varname, (S32)*(S64*)mvci.getData());
break;
case MVT_F32:

View File

@ -240,9 +240,16 @@ public:
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
{
lldebugs << "LLSDRPCClientFactory::build" << llendl;
LLIOPipe::ptr_t service(new Client);
chain.push_back(service);
LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
if(!http->isValid())
{
llwarns << "Creating LLURLRequest failed." << llendl ;
delete http;
return false;
}
LLIOPipe::ptr_t service(new Client);
chain.push_back(service);
LLIOPipe::ptr_t http_pipe(http);
http->addHeader("Content-Type: text/llsd");
if(mURL.empty())
@ -283,9 +290,16 @@ public:
virtual bool build(LLPumpIO::chain_t& chain, LLSD context) const
{
lldebugs << "LLXMLSDRPCClientFactory::build" << llendl;
LLIOPipe::ptr_t service(new Client);
chain.push_back(service);
LLURLRequest* http(new LLURLRequest(LLURLRequest::HTTP_POST));
if(!http->isValid())
{
llwarns << "Creating LLURLRequest failed." << llendl ;
delete http;
return false ;
}
LLIOPipe::ptr_t service(new Client);
chain.push_back(service);
LLIOPipe::ptr_t http_pipe(http);
http->addHeader("Content-Type: text/xml");
if(mURL.empty())

View File

@ -64,7 +64,7 @@ public:
~LLURLRequestDetail();
std::string mURL;
LLCurlEasyRequest* mCurlRequest;
LLBufferArray* mResponseBuffer;
LLIOPipe::buffer_ptr_t mResponseBuffer;
LLChannelDescriptors mChannels;
U8* mLastRead;
U32 mBodyLimit;
@ -75,7 +75,6 @@ public:
LLURLRequestDetail::LLURLRequestDetail() :
mCurlRequest(NULL),
mResponseBuffer(NULL),
mLastRead(NULL),
mBodyLimit(0),
mByteAccumulator(0),
@ -84,13 +83,18 @@ LLURLRequestDetail::LLURLRequestDetail() :
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mCurlRequest = new LLCurlEasyRequest();
if(!mCurlRequest->isValid()) //failed.
{
delete mCurlRequest ;
mCurlRequest = NULL ;
}
}
LLURLRequestDetail::~LLURLRequestDetail()
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
delete mCurlRequest;
mResponseBuffer = NULL;
mLastRead = NULL;
}
@ -252,12 +256,24 @@ void LLURLRequest::allowCookies()
mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
}
//virtual
bool LLURLRequest::isValid()
{
return mDetail->mCurlRequest && mDetail->mCurlRequest->isValid();
}
// virtual
LLIOPipe::EStatus LLURLRequest::handleError(
LLIOPipe::EStatus status,
LLPumpIO* pump)
{
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
if(!isValid())
{
return STATUS_EXPIRED ;
}
if(mCompletionCallback && pump)
{
LLURLRequestComplete* complete = NULL;
@ -326,7 +342,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
// *FIX: bit of a hack, but it should work. The configure and
// callback method expect this information to be ready.
mDetail->mResponseBuffer = buffer.get();
mDetail->mResponseBuffer = buffer;
mDetail->mChannels = channels;
if(!configure())
{
@ -443,6 +459,12 @@ void LLURLRequest::initialize()
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
mState = STATE_INITIALIZED;
mDetail = new LLURLRequestDetail;
if(!isValid())
{
return ;
}
mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);

View File

@ -188,6 +188,8 @@ public:
*/
void allowCookies();
/*virtual*/ bool isValid() ;
public:
/**
* @brief Give this pipe a chance to handle a generated error

View File

@ -29,6 +29,7 @@
#include "message.h"
#include "lltimer.h"
#include "llextendedstatus.h"
const S32 LL_XFER_LARGE_PAYLOAD = 7680;

View File

@ -3147,7 +3147,7 @@ bool LLMessageSystem::generateDigestForWindowAndUUIDs(char* digest, const S32 wi
LL_ERRS("Messaging") << "Trying to generate complex digest on a machine without a shared secret!" << llendl;
}
U32 now = time(NULL);
U32 now = (U32)time(NULL);
now /= window;
@ -3167,7 +3167,7 @@ bool LLMessageSystem::isMatchingDigestForWindowAndUUIDs(const char* digest, cons
}
char our_digest[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
U32 now = time(NULL);
U32 now = (U32)time(NULL);
now /= window;
@ -3213,7 +3213,7 @@ bool LLMessageSystem::generateDigestForWindow(char* digest, const S32 window) co
LL_ERRS("Messaging") << "Trying to generate simple digest on a machine without a shared secret!" << llendl;
}
U32 now = time(NULL);
U32 now = (U32)time(NULL);
now /= window;

View File

@ -56,8 +56,9 @@ std::string LLFontGL::sAppDir;
LLColor4 LLFontGL::sShadowColor(0.f, 0.f, 0.f, 1.f);
LLFontRegistry* LLFontGL::sFontRegistry = NULL;
LLCoordFont LLFontGL::sCurOrigin;
std::vector<LLCoordFont> LLFontGL::sOriginStack;
LLCoordGL LLFontGL::sCurOrigin;
F32 LLFontGL::sCurDepth;
std::vector<std::pair<LLCoordGL, F32> > LLFontGL::sOriginStack;
const F32 EXT_X_BEARING = 1.f;
const F32 EXT_Y_BEARING = 0.f;
@ -68,20 +69,6 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f;
const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture
const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f;
static F32 llfont_round_x(F32 x)
{
//return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX;
//return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY;
return x;
}
static F32 llfont_round_y(F32 y)
{
//return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY;
//return llfloor(y+0.5f);
return y;
}
LLFontGL::LLFontGL()
{
}
@ -115,23 +102,23 @@ static LLFastTimer::DeclareTimer FTM_RENDER_FONTS("Fonts");
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const
{
F32 x = rect.mLeft;
F32 x = (F32)rect.mLeft;
F32 y = 0.f;
switch(valign)
{
case TOP:
y = rect.mTop;
y = (F32)rect.mTop;
break;
case VCENTER:
y = rect.getCenterY();
y = (F32)rect.getCenterY();
break;
case BASELINE:
case BOTTOM:
y = rect.mBottom;
y = (F32)rect.mBottom;
break;
default:
y = rect.mBottom;
y = (F32)rect.mBottom;
break;
}
return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses);
@ -177,21 +164,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
gGL.loadUIIdentity();
//gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ);
// this code snaps the text origin to a pixel grid to start with
//F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
//F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
//gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f);
LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY));
// snap the text origin to a pixel grid to start with
origin.mV[VX] -= llround((F32)sCurOrigin.mX) - (sCurOrigin.mX);
origin.mV[VY] -= llround((F32)sCurOrigin.mY) - (sCurOrigin.mY);
// Depth translation, so that floating text appears 'inworld'
// and is correclty occluded.
gGL.translatef(0.f,0.f,sCurOrigin.mZ);
// Depth translation, so that floating text appears 'in-world'
// and is correctly occluded.
gGL.translatef(0.f,0.f,sCurDepth);
S32 chars_drawn = 0;
S32 i;
@ -215,16 +192,17 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
cur_y = ((F32)y * sScaleY) + origin.mV[VY];
// Offset y by vertical alignment.
// use unscaled font metrics here
switch (valign)
{
case TOP:
cur_y -= mFontFreetype->getAscenderHeight();
cur_y -= llceil(mFontFreetype->getAscenderHeight());
break;
case BOTTOM:
cur_y += mFontFreetype->getDescenderHeight();
cur_y += llceil(mFontFreetype->getDescenderHeight());
break;
case VCENTER:
cur_y -= (mFontFreetype->getAscenderHeight() - mFontFreetype->getDescenderHeight()) / 2.f;
cur_y -= llceil((llceil(mFontFreetype->getAscenderHeight()) - llceil(mFontFreetype->getDescenderHeight())) / 2.f);
break;
case BASELINE:
// Baseline, do nothing.
@ -250,7 +228,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
cur_render_y = cur_y;
cur_render_x = cur_x;
F32 start_x = llround(cur_x);
F32 start_x = (F32)llround(cur_x);
const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
@ -334,10 +312,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
(fgi->mXBitmapOffset + fgi->mWidth) * inv_width,
(fgi->mYBitmapOffset - PAD_UVY) * inv_height);
// snap glyph origin to whole screen pixel
LLRectf screen_rect(llround(cur_render_x + (F32)fgi->mXBearing),
llround(cur_render_y + (F32)fgi->mYBearing),
llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
LLRectf screen_rect((F32)llround(cur_render_x + (F32)fgi->mXBearing),
(F32)llround(cur_render_y + (F32)fgi->mYBearing),
(F32)llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
(F32)llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
if (glyph_count >= GLYPH_BATCH_SIZE)
{
@ -390,12 +368,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
//FIXME: add underline as glyph?
if (style_to_add & UNDERLINE)
{
F32 descender = mFontFreetype->getDescenderHeight();
F32 descender = (F32)llfloor(mFontFreetype->getDescenderHeight());
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.begin(LLRender::LINES);
gGL.vertex2f(start_x, cur_y - (descender));
gGL.vertex2f(cur_x, cur_y - (descender));
gGL.vertex2f(start_x, cur_y - descender);
gGL.vertex2f(cur_x, cur_y - descender);
gGL.end();
}
@ -444,19 +422,9 @@ S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y
}
// font metrics - override for LLFontFreetype that returns units of virtual pixels
F32 LLFontGL::getLineHeight() const
S32 LLFontGL::getLineHeight() const
{
return (F32)llround(mFontFreetype->getLineHeight() / sScaleY);
}
F32 LLFontGL::getAscenderHeight() const
{
return (F32)llround(mFontFreetype->getAscenderHeight() / sScaleY);
}
F32 LLFontGL::getDescenderHeight() const
{
return (F32)llround(mFontFreetype->getDescenderHeight() / sScaleY);
return llceil(mFontFreetype->getAscenderHeight() / sScaleY) + llceil(mFontFreetype->getDescenderHeight() / sScaleY);
}
S32 LLFontGL::getWidth(const std::string& utf8text) const
@ -645,7 +613,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
}
// Round after kerning.
cur_x = llround(cur_x);
cur_x = (F32)llround(cur_x);
drawn_x = cur_x;
}
@ -716,7 +684,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
}
// Round after kerning.
total_width = llround(total_width);
total_width = (F32)llround(total_width);
}
if (drawable_chars == 0)
@ -799,7 +767,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
// Round after kerning.
cur_x = llround(cur_x);
cur_x = (F32)llround(cur_x);
}
return llmin(max_chars, pos - begin_offset);
@ -1146,22 +1114,22 @@ void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* c
{
S32 index = 0;
vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mTop), 0.f);
vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mTop, 0.f);
uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
colors_out[index] = color;
index++;
vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mTop), 0.f);
vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 0.f);
uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
colors_out[index] = color;
index++;
vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mLeft), llfont_round_y(screen_rect.mBottom), 0.f);
vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 0.f);
uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
colors_out[index] = color;
index++;
vertex_out[index] = LLVector3(llfont_round_x(screen_rect.mRight), llfont_round_y(screen_rect.mBottom), 0.f);
vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 0.f);
uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
colors_out[index] = color;
}

View File

@ -115,9 +115,7 @@ public:
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
// font metrics - override for LLFontFreetype that returns units of virtual pixels
F32 getLineHeight() const;
F32 getAscenderHeight() const;
F32 getDescenderHeight() const;
S32 getLineHeight() const;
S32 getWidth(const std::string& utf8text) const;
S32 getWidth(const llwchar* wchars) const;
@ -188,8 +186,9 @@ public:
static std::string getFontPathLocal();
static std::string getFontPathSystem();
static LLCoordFont sCurOrigin;
static std::vector<LLCoordFont> sOriginStack;
static LLCoordGL sCurOrigin;
static F32 sCurDepth;
static std::vector<std::pair<LLCoordGL, F32> > sOriginStack;
static LLColor4 sShadowColor;

View File

@ -97,6 +97,8 @@ void APIENTRY gl_debug_callback(GLenum source,
}
#endif
void parse_glsl_version(S32& major, S32& minor);
void ll_init_fail_log(std::string filename)
{
gFailLog.open(filename.c_str());
@ -295,6 +297,7 @@ PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB = NULL;
PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = NULL;
#if LL_WINDOWS
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
@ -443,7 +446,8 @@ LLGLManager::LLGLManager() :
mDriverVersionMinor(0),
mDriverVersionRelease(0),
mGLVersion(1.0f),
mGLSLVersionMajor(0),
mGLSLVersionMinor(0),
mVRAM(0),
mGLMaxVertexRange(0),
mGLMaxIndexRange(0)
@ -554,6 +558,20 @@ bool LLGLManager::initGL()
mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
if (mGLVersion >= 2.f)
{
parse_glsl_version(mGLSLVersionMajor, mGLSLVersionMinor);
#if LL_DARWIN
//never use GLSL greater than 1.20 on OSX
if (mGLSLVersionMajor > 1 || mGLSLVersionMinor >= 30)
{
mGLSLVersionMajor = 1;
mGLSLVersionMinor = 20;
}
#endif
}
// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
// from being recognized as ATI.
if (mGLVendor.substr(0,4) == "ATI ")
@ -1300,6 +1318,7 @@ void LLGLManager::initExtensions()
glVertexAttrib4uivARB = (PFNGLVERTEXATTRIB4UIVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4uivARB");
glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttrib4usvARB");
glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribPointerARB");
glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) GLH_EXT_GET_PROC_ADDRESS("glVertexAttribIPointer");
glEnableVertexAttribArrayARB = (PFNGLENABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glEnableVertexAttribArrayARB");
glDisableVertexAttribArrayARB = (PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDisableVertexAttribArrayARB");
glProgramStringARB = (PFNGLPROGRAMSTRINGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glProgramStringARB");
@ -2098,6 +2117,55 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
}
}
void parse_glsl_version(S32& major, S32& minor)
{
// GL_SHADING_LANGUAGE_VERSION returns a null-terminated string with the format:
// <major>.<minor>[.<release>] [<vendor specific>]
const char* version = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
major = 0;
minor = 0;
if( !version )
{
return;
}
std::string ver_copy( version );
S32 len = (S32)strlen( version ); /* Flawfinder: ignore */
S32 i = 0;
S32 start;
// Find the major version
start = i;
for( ; i < len; i++ )
{
if( '.' == version[i] )
{
break;
}
}
std::string major_str = ver_copy.substr(start,i-start);
LLStringUtil::convertToS32(major_str, major);
if( '.' == version[i] )
{
i++;
}
// Find the minor version
start = i;
for( ; i < len; i++ )
{
if( ('.' == version[i]) || isspace(version[i]) )
{
break;
}
}
std::string minor_str = ver_copy.substr(start,i-start);
LLStringUtil::convertToS32(minor_str, minor);
}
LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply)
{
mApply = apply;

View File

@ -138,6 +138,8 @@ public:
S32 mDriverVersionMinor;
S32 mDriverVersionRelease;
F32 mGLVersion; // e.g = 1.4
S32 mGLSLVersionMajor;
S32 mGLSLVersionMinor;
std::string mDriverVersionVendorString;
S32 mVRAM; // VRAM in MB

View File

@ -199,6 +199,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
@ -460,6 +461,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
@ -693,6 +695,7 @@ extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;

View File

@ -64,10 +64,23 @@ BOOL shouldChange(const LLVector4& v1, const LLVector4& v2)
}
LLShaderFeatures::LLShaderFeatures()
: calculatesLighting(false), isShiny(false), isFullbright(false), hasWaterFog(false),
hasTransport(false), hasSkinning(false), hasObjectSkinning(false), hasAtmospherics(false), isSpecular(false),
hasGamma(false), hasLighting(false), calculatesAtmospherics(false), mIndexedTextureChannels(0), disableTextureIndex(false),
hasAlphaMask(false)
: atmosphericHelpers(false)
, calculatesLighting(false)
, calculatesAtmospherics(false)
, hasLighting(false)
, isAlphaLighting(false)
, isShiny(false)
, isFullbright(false)
, isSpecular(false)
, hasWaterFog(false)
, hasTransport(false)
, hasSkinning(false)
, hasObjectSkinning(false)
, hasAtmospherics(false)
, hasGamma(false)
, mIndexedTextureChannels(0)
, disableTextureIndex(false)
, hasAlphaMask(false)
{
}
@ -96,7 +109,12 @@ void LLGLSLShader::unload()
glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
for (GLsizei i = 0; i < count; i++)
{
glDeleteObjectARB(obj[i]);
#if !LL_DARWIN
if (glIsProgramARB(obj[i]))
#endif
{
glDeleteObjectARB(obj[i]);
}
}
glDeleteObjectARB(mProgramObject);
@ -148,8 +166,9 @@ BOOL LLGLSLShader::createShader(vector<string> * attributes,
return FALSE;
}
if (gGLManager.mGLVersion < 3.1f)
{ //attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 3)
{ //indexed texture rendering requires GLSL 1.3 or later
//attachShaderFeatures may have set the number of indexed texture channels, so set to 1 again
mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
}

View File

@ -33,9 +33,11 @@
class LLShaderFeatures
{
public:
bool atmosphericHelpers;
bool calculatesLighting;
bool calculatesAtmospherics;
bool hasLighting; // implies no transport (it's possible to have neither though)
bool isAlphaLighting; // indicates lighting shaders need not be linked in (lighting performed directly in alpha shader to match deferred lighting functions)
bool isShiny;
bool isFullbright; // implies no lighting
bool isSpecular;

View File

@ -997,7 +997,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction)
const glh::matrix4f& mat = gGL.getModelviewMatrix();
mat.mult_matrix_dir(dir);
mSpotDirection.set(direction);
mSpotDirection.set(dir.v);
}
}
@ -1434,6 +1434,8 @@ void LLRender::loadIdentity()
flush();
{
llassert_always(mMatrixMode < NUM_MATRIX_MODES) ;
mMatrix[mMatrixMode][mMatIdx[mMatrixMode]].make_identity();
mMatHash[mMatrixMode]++;
}

View File

@ -457,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;
}

View File

@ -94,23 +94,29 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
if (features->calculatesLighting)
if (features->calculatesLighting || features->atmosphericHelpers)
{
if (!shader->attachObject("windlight/atmosphericsHelpersV.glsl"))
{
return FALSE;
}
}
if (features->calculatesLighting)
{
if (features->isSpecular)
{
if (!shader->attachObject("lighting/lightFuncSpecularV.glsl"))
{
return FALSE;
}
if (!shader->attachObject("lighting/sumLightsSpecularV.glsl"))
if (!features->isAlphaLighting)
{
return FALSE;
if (!shader->attachObject("lighting/sumLightsSpecularV.glsl"))
{
return FALSE;
}
}
if (!shader->attachObject("lighting/lightSpecularV.glsl"))
@ -125,9 +131,12 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
return FALSE;
}
if (!shader->attachObject("lighting/sumLightsV.glsl"))
if (!features->isAlphaLighting)
{
return FALSE;
if (!shader->attachObject("lighting/sumLightsV.glsl"))
{
return FALSE;
}
}
if (!shader->attachObject("lighting/lightV.glsl"))
@ -296,7 +305,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
}
}
// NOTE order of shader object attaching is VERY IMPORTANT!!!
@ -566,34 +575,46 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
GLcharARB* text[4096];
GLuint count = 0;
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)
S32 major_version = gGLManager.mGLSLVersionMajor;
S32 minor_version = gGLManager.mGLSLVersionMinor;
if (major_version == 1 && minor_version < 30)
{
text[count++] = strdup("#version 110\n");
text[count++] = strdup("#define ATTRIBUTE attribute\n");
text[count++] = strdup("#define VARYING varying\n");
}
else if (version < 3.f)
{
//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");
if (minor_version < 10)
{
//should NEVER get here -- if major version is 1 and minor version is less than 10,
// viewer should never attempt to use shaders, continuing will result in undefined behavior
llerrs << "Unsupported GLSL Version." << llendl;
}
if (minor_version <= 19)
{
text[count++] = strdup("#version 110\n");
text[count++] = strdup("#define ATTRIBUTE attribute\n");
text[count++] = strdup("#define VARYING varying\n");
text[count++] = strdup("#define VARYING_FLAT varying\n");
}
else if (minor_version <= 29)
{
//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");
text[count++] = strdup("#define VARYING_FLAT varying\n");
}
}
else
{
if (version < 4.f)
if (major_version < 4)
{
//set version to 1.30
text[count++] = strdup("#version 130\n");
//some implementations of GLSL 1.30 require integer precision be explicitly declared
text[count++] = strdup("precision mediump int;\n");
text[count++] = strdup("precision highp float;\n");
}
else
{ //set version to 400
@ -609,16 +630,25 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
{ //"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");
text[count++] = strdup("#define VARYING_FLAT flat out\n");
}
else
{
text[count++] = strdup("#define VARYING in\n");
text[count++] = strdup("#define VARYING_FLAT flat in\n");
}
//backwards compatibility with legacy texture lookup syntax
text[count++] = strdup("#define texture2D texture\n");
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");
if (major_version > 1 || minor_version >= 40)
{ //GLSL 1.40 replaces texture2DRect et al with texture
text[count++] = strdup("#define texture2DRect texture\n");
text[count++] = strdup("#define shadow2DRect(a,b) vec2(texture(a,b))\n");
}
}
//copy preprocessor definitions into buffer
@ -642,22 +672,24 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
.
uniform sampler2D texN;
VARYING float vary_texture_index;
VARYING_FLAT ivec4 vary_texture_index;
vec4 ret = vec4(1,0,1,1);
vec4 diffuseLookup(vec2 texcoord)
{
switch (int(vary_texture_index+0.25))
switch (vary_texture_index.r))
{
case 0: return texture2D(tex0, texcoord);
case 1: return texture2D(tex1, texcoord);
case 2: return texture2D(tex2, texcoord);
case 0: ret = texture2D(tex0, texcoord); break;
case 1: ret = texture2D(tex1, texcoord); break;
case 2: ret = texture2D(tex2, texcoord); break;
.
.
.
case N: return texture2D(texN, texcoord);
case N: return texture2D(texN, texcoord); break;
}
return vec4(0,0,0,0);
return ret;
}
*/
@ -670,7 +702,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
if (texture_index_channels > 1)
{
text[count++] = strdup("VARYING float vary_texture_index;\n");
text[count++] = strdup("VARYING_FLAT ivec4 vary_texture_index;\n");
}
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
@ -682,45 +714,28 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
text[count++] = strdup("return texture2D(tex0, texcoord);\n");
text[count++] = strdup("}\n");
}
else if (gGLManager.mGLVersion >= 3.f)
{
text[count++] = strdup("\tswitch (int(vary_texture_index+0.25))\n");
else if (major_version > 1 || minor_version >= 30)
{ //switches are supported in GLSL 1.30 and later
text[count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
text[count++] = strdup("\tswitch (vary_texture_index.r)\n");
text[count++] = strdup("\t{\n");
//switch body
for (S32 i = 0; i < texture_index_channels; ++i)
{
std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
std::string case_str = llformat("\t\tcase %d: ret = texture2D(tex%d, texcoord); break;\n", i, i);
text[count++] = strdup(case_str.c_str());
}
text[count++] = strdup("\t}\n");
text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
text[count++] = strdup("\treturn ret;\n");
text[count++] = strdup("}\n");
}
else
{
//switches aren't supported, make block that looks like:
/*
int ti = int(vary_texture_index+0.25);
if (ti == 0) return texture2D(tex0, texcoord);
if (ti == 1) return texture2D(tex1, texcoord);
.
.
.
if (ti == N) return texture2D(texN, texcoord);
*/
text[count++] = strdup("int ti = int(vary_texture_index+0.25);\n");
for (S32 i = 0; i < texture_index_channels; ++i)
{
std::string if_str = llformat("if (ti == %d) return texture2D(tex%d, texcoord);\n", i, i);
text[count++] = strdup(if_str.c_str());
}
text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
text[count++] = strdup("}\n");
}
{ //should never get here. Indexed texture rendering requires GLSL 1.30 or later
// (for passing integers between vertex and fragment shaders)
llerrs << "Indexed texture rendering requires GLSL 1.30 or later." << llendl;
}
}
//copy file into memory
@ -1061,6 +1076,8 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("magnification");
mReservedUniforms.push_back("max_cof");
mReservedUniforms.push_back("res_scale");
mReservedUniforms.push_back("dof_width");
mReservedUniforms.push_back("dof_height");
mReservedUniforms.push_back("depthMap");
mReservedUniforms.push_back("shadowMap0");

View File

@ -142,6 +142,8 @@ public:
DOF_MAGNIFICATION,
DOF_MAX_COF,
DOF_RES_SCALE,
DOF_WIDTH,
DOF_HEIGHT,
DEFERRED_DEPTH,
DEFERRED_SHADOW0,

File diff suppressed because it is too large Load Diff

View File

@ -55,15 +55,20 @@ class LLVBOPool
{
public:
static U32 sBytesPooled;
LLVBOPool(U32 vboUsage, U32 vboType)
: mUsage(vboUsage)
, mType(vboType)
{}
U32 mUsage;
U32 mType;
const U32 mUsage;
const U32 mType;
//size MUST be a power of 2
U8* allocate(U32& name, U32 size);
volatile 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);
void release(U32 name, volatile U8* buffer, U32 size);
//destroy all records in mFreeList
void cleanup();
@ -72,7 +77,7 @@ public:
{
public:
U32 mGLName;
U8* mClientData;
volatile U8* mClientData;
};
typedef std::list<Record> record_list_t;
@ -88,7 +93,7 @@ public:
//============================================================================
// base class
class LLPrivateMemoryPool ;
class LLPrivateMemoryPool;
class LLVertexBuffer : public LLRefCount
{
public:
@ -103,6 +108,7 @@ public:
};
LLVertexBuffer(const LLVertexBuffer& rhs)
: mUsage(rhs.mUsage)
{
*this = rhs;
}
@ -118,9 +124,9 @@ public:
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
static BOOL sUseStreamDraw;
static BOOL sUseVAO;
static BOOL sPreferStreamDraw;
static bool sUseStreamDraw;
static bool sUseVAO;
static bool sPreferStreamDraw;
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass();
@ -201,15 +207,15 @@ protected:
void destroyGLIndices();
void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices);
virtual BOOL useVBOs() const;
bool useVBOs() const;
void unmapBuffer();
public:
LLVertexBuffer(U32 typemask, S32 usage);
// map for data access
U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
volatile U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range);
volatile U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
// set for rendering
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
@ -239,21 +245,22 @@ public:
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; }
bool isEmpty() const { return mEmpty; }
bool isLocked() const { return mVertexLocked || mIndexLocked; }
S32 getNumVerts() const { return mNumVerts; }
S32 getNumIndices() const { return mNumIndices; }
U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
volatile 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 mIndicesSize; }
U8* getMappedData() const { return mMappedData; }
U8* getMappedIndices() const { return mMappedIndexData; }
volatile U8* getMappedData() const { return mMappedData; }
volatile U8* getMappedIndices() const { return mMappedIndexData; }
S32 getOffset(S32 type) const { return mOffsets[type]; }
S32 getUsage() const { return mUsage; }
bool isWriteable() const { return (mMappable || mUsage == GL_STREAM_DRAW_ARB) ? true : false; }
void draw(U32 mode, U32 count, U32 indices_offset) const;
void drawArrays(U32 mode, U32 offset, U32 count) const;
@ -273,17 +280,25 @@ protected:
S32 mSize;
S32 mIndicesSize;
U32 mTypeMask;
S32 mUsage; // GL usage
const 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 mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
U32 mMappedDataUsingVBOs : 1;
U32 mMappedIndexDataUsingVBOs : 1;
U32 mVertexLocked : 1; // if true, vertex buffer is being or has been written to in client memory
U32 mIndexLocked : 1; // if true, index buffer is being or has been written to in client memory
U32 mFinal : 1; // if true, buffer can not be mapped again
U32 mEmpty : 1; // if true, client buffer is empty (or NULL). Old values have been discarded.
mutable bool mMappable; // if true, use memory mapping to upload data (otherwise doublebuffer and use glBufferSubData)
S32 mOffsets[TYPE_MAX];
std::vector<MappedRegion> mMappedVertexRegions;
@ -294,26 +309,27 @@ protected:
void placeFence() const;
void waitFence() const;
static S32 determineUsage(S32 usage);
private:
static LLPrivateMemoryPool* sPrivatePoolp ;
static LLPrivateMemoryPool* sPrivatePoolp;
public:
static S32 sCount;
static S32 sGLCount;
static S32 sMappedCount;
static BOOL sMapped;
static bool sMapped;
typedef std::list<LLVertexBuffer*> buffer_list_t;
static BOOL sDisableVBOMapping; //disable glMapBufferARB
static BOOL sEnableVBOs;
static bool sDisableVBOMapping; //disable glMapBufferARB
static bool sEnableVBOs;
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;
static bool sVBOActive;
static bool sIBOActive;
static U32 sLastMask;
static U32 sAllocatedBytes;
static U32 sBindCount;

View File

@ -976,7 +976,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
gGL.matrixMode(LLRender::MM_MODELVIEW);
LLUI::pushMatrix();
{
LLUI::translate((F32)child->getRect().mLeft, (F32)child->getRect().mBottom, 0.f);
LLUI::translate((F32)child->getRect().mLeft, (F32)child->getRect().mBottom);
child->draw();
}

View File

@ -908,9 +908,9 @@ void LLButton::draw()
// Not sure if it is really needed. Probably S32_MAX should be always passed as max_chars.
mLastDrawCharsCount = mGLFont->render(label, 0,
(F32)x,
(F32)(mBottomVPad + y_offset),
(F32)(getRect().getHeight() / 2 + mBottomVPad),
label_color % alpha,
mHAlign, LLFontGL::BOTTOM,
mHAlign, LLFontGL::VCENTER,
LLFontGL::NORMAL,
mDropShadowedText ? LLFontGL::DROP_SHADOW_SOFT : LLFontGL::NO_SHADOW,
S32_MAX, text_width,

View File

@ -34,109 +34,113 @@
#include "llview.h"
#include "llwindow.h"
// Global singleton
LLClipboard gClipboard;
LLClipboard::LLClipboard()
LLClipboard::LLClipboard() :
mGeneration(0)
{
mSourceItem = NULL;
reset();
}
LLClipboard::~LLClipboard()
{
reset();
}
void LLClipboard::copyFromSubstring(const LLWString &src, S32 pos, S32 len, const LLUUID& source_id )
void LLClipboard::reset()
{
mSourceID = source_id;
mString = src.substr(pos, len);
LLView::getWindow()->copyTextToClipboard( mString );
// Increment the clipboard count
mGeneration++;
// Clear the clipboard
mObjects.clear();
mCutMode = false;
mString = LLWString();
}
void LLClipboard::copyFromString(const LLWString &src, const LLUUID& source_id )
// Copy the input uuid to the LL clipboard
bool LLClipboard::copyToClipboard(const LLUUID& src, const LLAssetType::EType type)
{
mSourceID = source_id;
mString = src;
LLView::getWindow()->copyTextToClipboard( mString );
reset();
return addToClipboard(src, type);
}
const LLWString& LLClipboard::getPasteWString( LLUUID* source_id )
// Add the input uuid to the LL clipboard
// Convert the uuid to string and concatenate that string to the system clipboard if legit
bool LLClipboard::addToClipboard(const LLUUID& src, const LLAssetType::EType type)
{
if( mSourceID.notNull() )
bool res = false;
if (src.notNull())
{
LLWString temp_string;
LLView::getWindow()->pasteTextFromClipboard(temp_string);
if( temp_string != mString )
res = true;
if (LLAssetType::lookupIsAssetIDKnowable(type))
{
mSourceID.setNull();
mString = temp_string;
LLWString source = utf8str_to_wstring(src.asString());
res = addToClipboard(source, 0, source.size());
}
if (res)
{
mObjects.push_back(src);
mGeneration++;
}
}
else
{
LLView::getWindow()->pasteTextFromClipboard(mString);
}
if( source_id )
{
*source_id = mSourceID;
}
return mString;
return res;
}
BOOL LLClipboard::canPasteString() const
bool LLClipboard::pasteFromClipboard(std::vector<LLUUID>& inv_objects) const
{
return LLView::getWindow()->isClipboardTextAvailable();
}
void LLClipboard::copyFromPrimarySubstring(const LLWString &src, S32 pos, S32 len, const LLUUID& source_id )
{
mSourceID = source_id;
mString = src.substr(pos, len);
LLView::getWindow()->copyTextToPrimary( mString );
}
const LLWString& LLClipboard::getPastePrimaryWString( LLUUID* source_id )
{
if( mSourceID.notNull() )
bool res = false;
S32 count = mObjects.size();
if (count > 0)
{
LLWString temp_string;
LLView::getWindow()->pasteTextFromPrimary(temp_string);
if( temp_string != mString )
res = true;
inv_objects.clear();
for (S32 i = 0; i < count; i++)
{
mSourceID.setNull();
mString = temp_string;
inv_objects.push_back(mObjects[i]);
}
}
else
{
LLView::getWindow()->pasteTextFromPrimary(mString);
}
if( source_id )
{
*source_id = mSourceID;
}
return mString;
return res;
}
BOOL LLClipboard::canPastePrimaryString() const
// Returns true if the LL Clipboard has pasteable items in it
bool LLClipboard::hasContents() const
{
return LLView::getWindow()->isPrimaryTextAvailable();
return (mObjects.size() > 0);
}
void LLClipboard::setSourceObject(const LLUUID& source_id, LLAssetType::EType type)
// Returns true if the input uuid is in the list of clipboard objects
bool LLClipboard::isOnClipboard(const LLUUID& object) const
{
mSourceItem = new LLInventoryObject (source_id, LLUUID::null, type, "");
std::vector<LLUUID>::const_iterator iter = std::find(mObjects.begin(), mObjects.end(), object);
return (iter != mObjects.end());
}
// Copy the input string to the LL and the system clipboard
bool LLClipboard::copyToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
{
return addToClipboard(src, pos, len, use_primary);
}
// Concatenate the input string to the LL and the system clipboard
bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
{
mString = src.substr(pos, len);
return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString));
}
// Copy the System clipboard to the output string.
// Manage the LL Clipboard / System clipboard consistency
bool LLClipboard::pasteFromClipboard(LLWString &dst, bool use_primary)
{
bool res = (use_primary ? LLView::getWindow()->pasteTextFromPrimary(dst) : LLView::getWindow()->pasteTextFromClipboard(dst));
if (res)
{
mString = dst;
}
return res;
}
// Return true if there's something on the System clipboard
bool LLClipboard::isTextAvailable(bool use_primary) const
{
return (use_primary ? LLView::getWindow()->isPrimaryTextAvailable() : LLView::getWindow()->isClipboardTextAvailable());
}

View File

@ -27,46 +27,68 @@
#ifndef LL_LLCLIPBOARD_H
#define LL_LLCLIPBOARD_H
#include <boost/function.hpp>
#include "llstring.h"
#include "lluuid.h"
#include "stdenums.h"
#include "llsingleton.h"
#include "llassettype.h"
#include "llinventory.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLClipboard
//
// This class is used to cut/copy/paste text strings and inventory items around
// the world. Use LLClipboard::instance().method() to use its methods.
// Note that the text and UUIDs are loosely coupled only. There are few cases
// where the viewer does offer a serialized version of the UUID on the clipboard.
// In those case, the text is overridden when copying/cutting the item.
// In all other cases, the text and the UUIDs are very much independent.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLClipboard
class LLClipboard : public LLSingleton<LLClipboard>
{
public:
LLClipboard();
~LLClipboard();
/* We support two flavors of clipboard. The default is the explicitly
copy-and-pasted clipboard. The second is the so-called 'primary' clipboard
which is implicitly copied upon selection on platforms which expect this
(i.e. X11/Linux). */
void copyFromSubstring(const LLWString &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
void copyFromString(const LLWString &copy_from, const LLUUID& source_id = LLUUID::null );
BOOL canPasteString() const;
const LLWString& getPasteWString(LLUUID* source_id = NULL);
void copyFromPrimarySubstring(const LLWString &copy_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
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; }
// Clears the clipboard
void reset();
// Returns the state of the clipboard so client can know if it has been modified (comparing with tracked state)
int getGeneration() const { return mGeneration; }
// Text strings management:
// ------------------------
// We support two flavors of text clipboards. The default is the explicitly
// copy-and-pasted clipboard. The second is the so-called 'primary' clipboard
// which is implicitly copied upon selection on platforms which expect this
// (i.e. X11/Linux, Mac).
bool copyToClipboard(const LLWString& src, S32 pos, S32 len, bool use_primary = false);
bool addToClipboard(const LLWString& src, S32 pos, S32 len, bool use_primary = false);
bool pasteFromClipboard(LLWString& dst, bool use_primary = false);
bool isTextAvailable(bool use_primary = false) const;
// Object list management:
// -----------------------
// Clears and adds one single object to the clipboard
bool copyToClipboard(const LLUUID& src, const LLAssetType::EType type = LLAssetType::AT_NONE);
// Adds one object to the current list of objects on the clipboard
bool addToClipboard(const LLUUID& src, const LLAssetType::EType type = LLAssetType::AT_NONE);
// Gets a copy of the objects on the clipboard
bool pasteFromClipboard(std::vector<LLUUID>& inventory_objects) const;
bool hasContents() const; // True if the clipboard has pasteable objects
bool isOnClipboard(const LLUUID& object) const; // True if the input object uuid is on the clipboard
bool isCutMode() const { return mCutMode; }
void setCutMode(bool mode) { mCutMode = mode; mGeneration++; }
private:
LLUUID mSourceID;
LLWString mString;
LLInventoryObject* mSourceItem;
std::vector<LLUUID> mObjects; // Objects on the clipboard. Can be empty while mString contains something licit (e.g. text from chat)
LLWString mString; // The text string. If mObjects is not empty, this string is reflecting them (UUIDs for the moment) if the asset type is knowable.
bool mCutMode; // This is a convenience flag for the viewer.
int mGeneration; // Incremented when the clipboard changes so that interested parties can check for changes on the clipboard.
};
// Global singleton
extern LLClipboard gClipboard;
#endif // LL_LLCLIPBOARD_H

View File

@ -613,7 +613,7 @@ void LLComboBox::showList()
}
mList->setOrigin(rect.mLeft, rect.mBottom);
mList->reshape(rect.getWidth(), rect.getHeight());
mList->translateIntoRect(root_view_local, FALSE);
mList->translateIntoRect(root_view_local);
// Make sure we didn't go off bottom of screen
S32 x, y;

View File

@ -244,7 +244,7 @@ void LLDragHandleTop::reshapeTitleBox()
const LLFontGL* font = LLFontGL::getFontSansSerif();
S32 title_width = getRect().getWidth();
title_width -= LEFT_PAD + 2 * BORDER_PAD + getButtonsRect().getWidth();
S32 title_height = llround(font->getLineHeight());
S32 title_height = font->getLineHeight();
LLRect title_rect;
title_rect.setLeftTopAndSize(
LEFT_PAD,

View File

@ -68,10 +68,10 @@ 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);
declare("relative", LLFloaterEnums::POSITIONING_RELATIVE);
declare("cascading", LLFloaterEnums::POSITIONING_CASCADING);
declare("centered", LLFloaterEnums::POSITIONING_CENTERED);
declare("specified", LLFloaterEnums::POSITIONING_SPECIFIED);
}
}
@ -177,9 +177,7 @@ LLFloater::Params::Params()
save_visibility("save_visibility", false),
can_dock("can_dock", false),
show_title("show_title", true),
open_positioning("open_positioning", LLFloaterEnums::OPEN_POSITIONING_NONE),
specified_left("specified_left"),
specified_bottom("specified_bottom"),
positioning("positioning", LLFloaterEnums::POSITIONING_RELATIVE),
header_height("header_height", 0),
legacy_header_height("legacy_header_height", 0),
close_image("close_image"),
@ -249,9 +247,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
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),
mPositioning(p.positioning),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
@ -270,6 +266,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinimizeSignal(NULL)
// mNotificationContext(NULL)
{
mPosition.setFloater(*this);
// mNotificationContext = new LLFloaterNotificationContext(getHandle());
// Clicks stop here.
@ -546,10 +543,18 @@ LLFloater::~LLFloater()
void LLFloater::storeRectControl()
{
if( mRectControl.size() > 1 )
if (!mRectControl.empty())
{
getControlGroup()->setRect( mRectControl, getRect() );
}
if (!mPosXControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE)
{
getControlGroup()->setF32( mPosXControl, mPosition.mX );
}
if (!mPosYControl.empty() && mPositioning == LLFloaterEnums::POSITIONING_RELATIVE)
{
getControlGroup()->setF32( mPosYControl, mPosition.mY );
}
}
void LLFloater::storeVisibilityControl()
@ -568,23 +573,6 @@ void LLFloater::storeDockStateControl()
}
}
LLRect LLFloater::getSavedRect() const
{
LLRect rect;
if (mRectControl.size() > 1)
{
rect = getControlGroup()->getRect(mRectControl);
}
return rect;
}
bool LLFloater::hasSavedRect() const
{
return !getSavedRect().isEmpty();
}
// static
std::string LLFloater::getControlName(const std::string& name, const LLSD& key)
{
@ -862,7 +850,7 @@ void LLFloater::applyControlsAndPosition(LLFloater* other)
{
if (!applyRectControl())
{
applyPositioning(other);
applyPositioning(other, true);
}
}
}
@ -871,29 +859,68 @@ bool LLFloater::applyRectControl()
{
bool saved_rect = false;
LLRect screen_rect = calcScreenRect();
mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
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;
mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
}
else if (mRectControl.size() > 1)
else
{
// If we have a saved rect, use it
const LLRect& rect = getControlGroup()->getRect(mRectControl);
saved_rect = rect.notEmpty();
if (saved_rect)
bool rect_specified = false;
if (!mRectControl.empty())
{
setOrigin(rect.mLeft, rect.mBottom);
if (mResizable)
// If we have a saved rect, use it
const LLRect& rect = getControlGroup()->getRect(mRectControl);
if (rect.notEmpty()) saved_rect = true;
if (saved_rect)
{
reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
setOrigin(rect.mLeft, rect.mBottom);
if (mResizable)
{
reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
}
mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
LLRect screen_rect = calcScreenRect();
mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
rect_specified = true;
}
}
LLControlVariablePtr x_control = getControlGroup()->getControl(mPosXControl);
LLControlVariablePtr y_control = getControlGroup()->getControl(mPosYControl);
if (x_control.notNull()
&& y_control.notNull()
&& !x_control->isDefault()
&& !y_control->isDefault())
{
mPosition.mX = x_control->getValue().asReal();
mPosition.mY = y_control->getValue().asReal();
mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
applyRelativePosition();
saved_rect = true;
}
// remember updated position
if (rect_specified)
{
storeRectControl();
}
}
if (saved_rect)
{
// propagate any derived positioning data back to settings file
storeRectControl();
}
return saved_rect;
}
@ -910,50 +937,56 @@ bool LLFloater::applyDockState()
return docked;
}
void LLFloater::applyPositioning(LLFloater* other)
void LLFloater::applyPositioning(LLFloater* other, bool on_open)
{
// Otherwise position according to the positioning code
switch (mOpenPositioning)
switch (mPositioning)
{
case LLFloaterEnums::OPEN_POSITIONING_CENTERED:
case LLFloaterEnums::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);
}
case LLFloaterEnums::POSITIONING_SPECIFIED:
break;
case LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP:
case LLFloaterEnums::OPEN_POSITIONING_CASCADING:
if (other != NULL && other != this)
case LLFloaterEnums::POSITIONING_CASCADING:
if (!on_open)
{
stackWith(*other);
applyRelativePosition();
}
else
// fall through
case LLFloaterEnums::POSITIONING_CASCADE_GROUP:
if (on_open)
{
static const U32 CASCADING_FLOATER_HOFFSET = 0;
static const U32 CASCADING_FLOATER_VOFFSET = 0;
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 LLRect& snap_rect = gFloaterView->getSnapRect();
const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET;
const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET;
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);
S32 rect_height = getRect().getHeight();
setOrigin(horizontal_offset, vertical_offset - rect_height);
translate(snap_rect.mLeft, snap_rect.mBottom);
translateIntoRect(snap_rect, FALSE);
translate(snap_rect.mLeft, snap_rect.mBottom);
}
setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
}
break;
case LLFloaterEnums::OPEN_POSITIONING_NONE:
case LLFloaterEnums::POSITIONING_RELATIVE:
{
applyRelativePosition();
break;
}
default:
// Do nothing
break;
@ -1071,7 +1104,9 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
if (by_user && !isMinimized())
{
storeRectControl();
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
LLRect screen_rect = calcScreenRect();
mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert();
}
// if not minimized, adjust all snapped dependents to new shape
@ -1249,6 +1284,7 @@ void LLFloater::setMinimized(BOOL minimize)
// Reshape *after* setting mMinimized
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
applyPositioning(NULL, false);
}
make_ui_sound("UISndWindowClose");
@ -1589,7 +1625,7 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
if (mDocked)
{
setMinimized(FALSE);
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
}
updateTitleButtons();
@ -1623,7 +1659,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
self->openFloater(self->getKey());
// only force position for floaters that don't have that data saved
if (self->mRectControl.size() <= 1)
if (self->mRectControl.empty())
{
new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());
self->setRect(new_rect);
@ -1681,6 +1717,8 @@ LLFloater* LLFloater::getClosableFloaterFromFocus()
{
if (it->hasFocus())
{
LLFloater& floater = *it;
focused_floater = &floater;
break;
}
}
@ -1800,7 +1838,7 @@ void LLFloater::draw()
const LLFontGL* font = LLFontGL::getFontSansSerif();
LLRect r = getRect();
gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1,
gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - font->getLineHeight() - 1,
titlebar_focus_color % alpha, 0, TRUE);
}
}
@ -2161,19 +2199,14 @@ LLFloaterView::LLFloaterView (const Params& p)
mSnapOffsetBottom(0),
mSnapOffsetRight(0)
{
mSnapView = getHandle();
}
// By default, adjust vertical.
void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
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)
@ -2186,35 +2219,39 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
continue;
}
if (!floaterp->isMinimized())
if (!floaterp->isMinimized() && floaterp->getCanDrag())
{
LLRect r = floaterp->getRect();
LLRect old_rect = floaterp->getRect();
floaterp->applyPositioning(NULL, false);
LLRect new_rect = floaterp->getRect();
// Compute absolute distance from each edge of screen
S32 left_offset = llabs(r.mLeft - 0);
S32 right_offset = llabs(old_right - r.mRight);
//LLRect r = floaterp->getRect();
S32 top_offset = llabs(old_top - r.mTop);
S32 bottom_offset = llabs(r.mBottom - 0);
//// Compute absolute distance from each edge of screen
//S32 left_offset = llabs(r.mLeft - 0);
//S32 right_offset = llabs(old_right - r.mRight);
S32 translate_x = 0;
S32 translate_y = 0;
//S32 top_offset = llabs(old_top - r.mTop);
//S32 bottom_offset = llabs(r.mBottom - 0);
if (left_offset > right_offset)
{
translate_x = new_right - old_right;
}
S32 translate_x = new_rect.mLeft - old_rect.mLeft;
S32 translate_y = new_rect.mBottom - old_rect.mBottom;
if (top_offset < bottom_offset)
{
translate_y = new_top - old_top;
}
//if (left_offset > right_offset)
//{
// translate_x = new_right - old_right;
//}
//if (top_offset < bottom_offset)
//{
// translate_y = new_top - old_top;
//}
// don't reposition immovable floaters
if (floaterp->getCanDrag())
{
floaterp->translate(translate_x, translate_y);
}
//if (floaterp->getCanDrag())
//{
// floaterp->translate(translate_x, translate_y);
//}
BOOST_FOREACH(LLHandle<LLFloater> dependent_floater, floaterp->mDependents)
{
if (dependent_floater.get())
@ -2641,6 +2678,8 @@ void LLFloaterView::refresh()
}
}
const S32 FLOATER_MIN_VISIBLE_PIXELS = 16;
void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside)
{
if (floater->getParent() != this)
@ -2694,7 +2733,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
}
// move window fully onscreen
if (floater->translateIntoRect( getSnapRect(), allow_partial_outside ))
if (floater->translateIntoRect( getSnapRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX ))
{
floater->clearSnapTarget();
}
@ -2908,9 +2947,11 @@ void LLFloater::setInstanceName(const std::string& name)
std::string ctrl_name = getControlName(mInstanceName, mKey);
// save_rect and save_visibility only apply to registered floaters
if (!mRectControl.empty())
if (mSaveRect)
{
mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
}
if (!mVisibilityControl.empty())
{
@ -2967,7 +3008,10 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
LLPanel::initFromParams(p);
// override any follows flags
setFollows(FOLLOWS_NONE);
if (mPositioning != LLFloaterEnums::POSITIONING_SPECIFIED)
{
setFollows(FOLLOWS_NONE);
}
mTitle = p.title;
mShortTitle = p.short_title;
@ -2986,14 +3030,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
mSingleInstance = p.single_instance;
mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance;
mOpenPositioning = p.open_positioning;
mSpecifiedLeft = p.specified_left;
mSpecifiedBottom = p.specified_bottom;
mPositioning = p.positioning;
if (p.save_rect && mRectControl.empty())
{
mRectControl = "t"; // flag to build mRectControl name once mInstanceName is set
}
mSaveRect = p.save_rect;
if (p.save_visibility)
{
mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set
@ -3108,7 +3147,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
params.rect.left.set(0);
}
params.from_xui = true;
applyXUILayout(params, parent);
applyXUILayout(params, parent, parent == gFloaterView ? gFloaterView->getSnapRect() : parent->getLocalRect());
initFromParams(params);
initFloater(params);
@ -3267,5 +3306,137 @@ void LLFloater::stackWith(LLFloater& other)
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
setShape(next_rect);
other.mPositioning = LLFloaterEnums::POSITIONING_CASCADE_GROUP;
other.setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
}
void LLFloater::applyRelativePosition()
{
LLRect snap_rect = gFloaterView->getSnapRect();
LLRect floater_view_screen_rect = gFloaterView->calcScreenRect();
snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom);
LLRect floater_screen_rect = calcScreenRect();
LLCoordGL new_center = mPosition.convert();
LLCoordGL cur_center(floater_screen_rect.getCenterX(), floater_screen_rect.getCenterY());
translate(new_center.mX - cur_center.mX, new_center.mY - cur_center.mY);
}
LLCoordFloater::LLCoordFloater(F32 x, F32 y, LLFloater& floater)
: coord_t((S32)x, (S32)y)
{
mFloater = floater.getHandle();
}
LLCoordFloater::LLCoordFloater(const LLCoordCommon& other, LLFloater& floater)
{
mFloater = floater.getHandle();
convertFromCommon(other);
}
LLCoordFloater& LLCoordFloater::operator=(const LLCoordFloater& other)
{
mFloater = other.mFloater;
coord_t::operator =(other);
return *this;
}
void LLCoordFloater::setFloater(LLFloater& floater)
{
mFloater = floater.getHandle();
}
bool LLCoordFloater::operator==(const LLCoordFloater& other) const
{
return mX == other.mX && mY == other.mY && mFloater == other.mFloater;
}
LLCoordCommon LL_COORD_FLOATER::convertToCommon() const
{
const LLCoordFloater& self = static_cast<const LLCoordFloater&>(LLCoordFloater::getTypedCoords(*this));
LLRect snap_rect = gFloaterView->getSnapRect();
LLRect floater_view_screen_rect = gFloaterView->calcScreenRect();
snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom);
LLFloater* floaterp = mFloater.get();
S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0;
S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0;
LLCoordCommon out;
if (self.mX < -0.5f)
{
out.mX = llround(rescale(self.mX, -1.f, -0.5f, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft));
}
else if (self.mX > 0.5f)
{
out.mX = llround(rescale(self.mX, 0.5f, 1.f, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS));
}
else
{
out.mX = llround(rescale(self.mX, -0.5f, 0.5f, snap_rect.mLeft, snap_rect.mRight - floater_width));
}
if (self.mY < -0.5f)
{
out.mY = llround(rescale(self.mY, -1.f, -0.5f, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom));
}
else if (self.mY > 0.5f)
{
out.mY = llround(rescale(self.mY, 0.5f, 1.f, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS));
}
else
{
out.mY = llround(rescale(self.mY, -0.5f, 0.5f, snap_rect.mBottom, snap_rect.mTop - floater_height));
}
// return center point instead of lower left
out.mX += floater_width / 2;
out.mY += floater_height / 2;
return out;
}
void LL_COORD_FLOATER::convertFromCommon(const LLCoordCommon& from)
{
LLCoordFloater& self = static_cast<LLCoordFloater&>(LLCoordFloater::getTypedCoords(*this));
LLRect snap_rect = gFloaterView->getSnapRect();
LLRect floater_view_screen_rect = gFloaterView->calcScreenRect();
snap_rect.translate(floater_view_screen_rect.mLeft, floater_view_screen_rect.mBottom);
LLFloater* floaterp = mFloater.get();
S32 floater_width = floaterp ? floaterp->getRect().getWidth() : 0;
S32 floater_height = floaterp ? floaterp->getRect().getHeight() : 0;
S32 from_x = from.mX - floater_width / 2;
S32 from_y = from.mY - floater_height / 2;
if (from_x < snap_rect.mLeft)
{
self.mX = rescale(from_x, snap_rect.mLeft - (floater_width - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mLeft, -1.f, -0.5f);
}
else if (from_x + floater_width > snap_rect.mRight)
{
self.mX = rescale(from_x, snap_rect.mRight - floater_width, snap_rect.mRight - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f);
}
else
{
self.mX = rescale(from_x, snap_rect.mLeft, snap_rect.mRight - floater_width, -0.5f, 0.5f);
}
if (from_y < snap_rect.mBottom)
{
self.mY = rescale(from_y, snap_rect.mBottom - (floater_height - FLOATER_MIN_VISIBLE_PIXELS), snap_rect.mBottom, -1.f, -0.5f);
}
else if (from_y + floater_height > snap_rect.mTop)
{
self.mY = rescale(from_y, snap_rect.mTop - floater_height, snap_rect.mTop - FLOATER_MIN_VISIBLE_PIXELS, 0.5f, 1.f);
}
else
{
self.mY = rescale(from_y, snap_rect.mBottom, snap_rect.mTop - floater_height, -0.5f, 0.5f);
}
}

View File

@ -64,12 +64,12 @@ namespace LLFloaterEnums
{
enum EOpenPositioning
{
OPEN_POSITIONING_NONE,
OPEN_POSITIONING_CASCADING,
OPEN_POSITIONING_CASCADE_GROUP,
OPEN_POSITIONING_CENTERED,
OPEN_POSITIONING_SPECIFIED,
OPEN_POSITIONING_COUNT
POSITIONING_RELATIVE,
POSITIONING_CASCADING,
POSITIONING_CASCADE_GROUP,
POSITIONING_CENTERED,
POSITIONING_SPECIFIED,
POSITIONING_COUNT
};
}
@ -82,6 +82,37 @@ namespace LLInitParam
};
}
struct LL_COORD_FLOATER
{
typedef F32 value_t;
LLCoordCommon convertToCommon() const;
void convertFromCommon(const LLCoordCommon& from);
protected:
LLHandle<LLFloater> mFloater;
};
struct LLCoordFloater : LLCoord<LL_COORD_FLOATER>
{
typedef LLCoord<LL_COORD_FLOATER> coord_t;
LLCoordFloater() {}
LLCoordFloater(F32 x, F32 y, LLFloater& floater);
LLCoordFloater(const LLCoordCommon& other, LLFloater& floater);
LLCoordFloater& operator=(const LLCoordCommon& other)
{
convertFromCommon(other);
return *this;
}
LLCoordFloater& operator=(const LLCoordFloater& other);
bool operator==(const LLCoordFloater& other) const;
bool operator!=(const LLCoordFloater& other) const { return !(*this == other); }
void setFloater(LLFloater& floater);
};
class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
{
@ -132,10 +163,7 @@ public:
can_dock,
show_title;
Optional<LLFloaterEnums::EOpenPositioning> open_positioning;
Optional<S32> specified_left;
Optional<S32> specified_bottom;
Optional<LLFloaterEnums::EOpenPositioning> positioning;
Optional<S32> header_height,
legacy_header_height; // HACK see initFromXML()
@ -184,7 +212,7 @@ public:
bool initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::string& filename, LLXMLNodePtr output_node = NULL);
/*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
/*virtual*/ BOOL canSnapTo(const LLView* other_view);
/*virtual*/ BOOL canSnapTo(const LLView* other_view);
/*virtual*/ void setSnappedTo(const LLView* snap_view);
/*virtual*/ void setFocus( BOOL b );
/*virtual*/ void setIsChrome(BOOL is_chrome);
@ -241,8 +269,6 @@ public:
BOOL isResizable() const { return mResizable; }
void setResizeLimits( S32 min_width, S32 min_height );
void getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; }
LLRect getSavedRect() const;
bool hasSavedRect() const;
static std::string getControlName(const std::string& name, const LLSD& key);
static LLControlGroup* getControlGroup();
@ -324,7 +350,7 @@ public:
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mOpenPositioning); }
bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mPositioning); }
protected:
void applyControlsAndPosition(LLFloater* other);
@ -332,7 +358,9 @@ protected:
virtual bool applyRectControl();
bool applyDockState();
void applyPositioning(LLFloater* other);
void applyPositioning(LLFloater* other, bool on_open);
void applyRelativePosition();
void storeRectControl();
void storeVisibilityControl();
void storeDockStateControl();
@ -396,7 +424,10 @@ public:
commit_signal_t* mMinimizeSignal;
protected:
bool mSaveRect;
std::string mRectControl;
std::string mPosXControl;
std::string mPosYControl;
std::string mVisibilityControl;
std::string mDocStateControl;
LLSD mKey; // Key used for retrieving instances; set (for now) by LLFLoaterReg
@ -422,9 +453,8 @@ private:
BOOL mDragOnLeft;
BOOL mResizable;
LLFloaterEnums::EOpenPositioning mOpenPositioning;
S32 mSpecifiedLeft;
S32 mSpecifiedBottom;
LLFloaterEnums::EOpenPositioning mPositioning;
LLCoordFloater mPosition;
S32 mMinWidth;
S32 mMinHeight;

View File

@ -96,7 +96,9 @@ LLFloater* LLFloaterReg::getLastFloaterCascading()
{
LLFloater* inst = *iter;
if (inst->getVisible() && inst->isPositioning(LLFloaterEnums::OPEN_POSITIONING_CASCADING))
if (inst->getVisible()
&& (inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADING)
|| inst->isPositioning(LLFloaterEnums::POSITIONING_CASCADE_GROUP)))
{
if (candidate_rect.mTop > inst->getRect().mTop)
{
@ -358,9 +360,7 @@ void LLFloaterReg::restoreVisibleInstances()
//static
std::string LLFloaterReg::getRectControlName(const std::string& name)
{
std::string res = std::string("floater_rect_") + name;
LLStringUtil::replaceChar( res, ' ', '_' );
return res;
return std::string("floater_rect_") + getBaseControlName(name);
}
//static
@ -368,19 +368,48 @@ std::string LLFloaterReg::declareRectControl(const std::string& name)
{
std::string controlname = getRectControlName(name);
LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
llformat("Window Position and Size for %s", name.c_str()),
llformat("Window Size for %s", name.c_str()),
TRUE);
return controlname;
}
std::string LLFloaterReg::declarePosXControl(const std::string& name)
{
std::string controlname = std::string("floater_pos_") + getBaseControlName(name) + "_x";
LLFloater::getControlGroup()->declareF32(controlname,
10.f,
llformat("Window X Position for %s", name.c_str()),
TRUE);
return controlname;
}
std::string LLFloaterReg::declarePosYControl(const std::string& name)
{
std::string controlname = std::string("floater_pos_") + getBaseControlName(name) + "_y";
LLFloater::getControlGroup()->declareF32(controlname,
10.f,
llformat("Window Y Position for %s", name.c_str()),
TRUE);
return controlname;
}
//static
std::string LLFloaterReg::getVisibilityControlName(const std::string& name)
{
std::string res = std::string("floater_vis_") + name;
return std::string("floater_vis_") + getBaseControlName(name);
}
//static
std::string LLFloaterReg::getBaseControlName(const std::string& name)
{
std::string res(name);
LLStringUtil::replaceChar( res, ' ', '_' );
return res;
}
//static
std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
{

View File

@ -115,9 +115,11 @@ public:
// Control Variables
static std::string getRectControlName(const std::string& name);
static std::string declareRectControl(const std::string& name);
static std::string declarePosXControl(const std::string& name);
static std::string declarePosYControl(const std::string& name);
static std::string getVisibilityControlName(const std::string& name);
static std::string declareVisibilityControl(const std::string& name);
static std::string getBaseControlName(const std::string& name);
static std::string declareDockStateControl(const std::string& name);
static std::string getDockStateControlName(const std::string& name);

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
* Copyright (C) 2010, Linden Reshasearch, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -60,6 +60,7 @@ public:
clip;
Optional<F32> open_time_constant,
close_time_constant;
Optional<S32> resize_bar_overlap;
Params();
};
@ -71,13 +72,12 @@ public:
/*virtual*/ void draw();
/*virtual*/ void removeChild(LLView*);
/*virtual*/ BOOL postBuild();
/*virtual*/ bool addChild(LLView* child, S32 tab_group = 0);
/*virtual*/ bool addChild(LLView* child, S32 tab_groupdatefractuiona = 0);
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL);
S32 getMinWidth() const { return mMinWidth; }
S32 getMinHeight() const { return mMinHeight; }
typedef enum e_animate
{
NO_ANIMATE,
@ -85,47 +85,24 @@ public:
} EAnimate;
void addPanel(LLLayoutPanel* panel, EAnimate animate = NO_ANIMATE);
void removePanel(LLPanel* panel);
void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE);
S32 getNumPanels() { return mPanels.size(); }
/**
* Moves panel_to_move before target_panel inside layout stack (both panels should already be there).
* If move_to_front is true target_panel is ignored and panel_to_move is moved to the beginning of mPanels
*/
void movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front = false);
void updatePanelAutoResize(const std::string& panel_name, BOOL auto_resize);
void setPanelUserResize(const std::string& panel_name, BOOL user_resize);
/**
* Gets minimal dimension along layout_stack axis of the specified by name panel.
*
* @returns true if specified by panel_name internal panel exists, false otherwise.
*/
bool getPanelMinSize(const std::string& panel_name, S32* min_dimp);
void updateLayout();
/**
* Gets maximal dimension along layout_stack axis of the specified by name panel.
*
* @returns true if specified by panel_name internal panel exists, false otherwise.
*/
bool getPanelMaxSize(const std::string& panel_name, S32* max_dim);
void updateLayout(BOOL force_resize = FALSE);
S32 getPanelSpacing() const { return mPanelSpacing; }
BOOL getAnimate () const { return mAnimate; }
void setAnimate (BOOL animate) { mAnimate = animate; }
static void updateClass();
protected:
LLLayoutStack(const Params&);
friend class LLUICtrlFactory;
friend class LLLayoutPanel;
private:
void createResizeBars();
void calcMinExtents();
void updateResizeBarLimits();
bool animatePanels();
void createResizeBar(LLLayoutPanel* panel);
const ELayoutOrientation mOrientation;
@ -134,17 +111,20 @@ private:
LLLayoutPanel* findEmbeddedPanel(LLPanel* panelp) const;
LLLayoutPanel* findEmbeddedPanelByName(const std::string& name) const;
void updateFractionalSizes();
void normalizeFractionalSizes();
void updatePanelRect( LLLayoutPanel* param1, const LLRect& new_rect );
S32 mMinWidth; // calculated by calcMinExtents
S32 mMinHeight; // calculated by calcMinExtents
S32 mPanelSpacing;
// true if we already applied animation this frame
bool mAnimatedThisFrame;
bool mAnimate;
bool mClip;
F32 mOpenTimeConstant;
F32 mCloseTimeConstant;
F32 mOpenTimeConstant;
F32 mCloseTimeConstant;
bool mNeedsLayout;
S32 mResizeBarOverlap;
}; // end class LLLayoutStack
@ -156,8 +136,7 @@ public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
Optional<S32> expanded_min_dim,
min_dim,
max_dim;
min_dim;
Optional<bool> user_resize,
auto_resize;
@ -168,16 +147,21 @@ public:
void initFromParams(const Params& p);
void handleReshape(const LLRect& new_rect, bool by_user);
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; }
void setVisible(BOOL visible);
S32 getMaxDim() const { return mMaxDim; }
void setMaxDim(S32 value) { mMaxDim = value; }
S32 getLayoutDim() const;
S32 getTargetDim() const;
void setTargetDim(S32 value);
S32 getMinDim() const { return llmax(0, mMinDim); }
void setMinDim(S32 value) { mMinDim = value; }
S32 getExpandedMinDim() const { return mExpandedMinDim; }
void setExpandedMinDim(S32 value) { mExpandedMinDim = value; mExpandedMinDimSpecified = true; }
S32 getExpandedMinDim() const { return mExpandedMinDim >= 0 ? mExpandedMinDim : getMinDim(); }
void setExpandedMinDim(S32 value) { mExpandedMinDim = value; }
S32 getRelevantMinDim() const
{
@ -185,29 +169,35 @@ public:
if (!mCollapsed)
{
min_dim = mExpandedMinDim;
min_dim = getExpandedMinDim();
}
return min_dim;
}
F32 getCollapseFactor();
void setOrientation(LLLayoutStack::ELayoutOrientation orientation) { mOrientation = orientation; }
F32 getAutoResizeFactor() const;
F32 getVisibleAmount() const;
S32 getVisibleDim() const;
void setOrientation(LLLayoutStack::ELayoutOrientation orientation);
void storeOriginalDim();
void setIgnoreReshape(bool ignore) { mIgnoreReshape = ignore; }
protected:
LLLayoutPanel(const Params& p);
bool mExpandedMinDimSpecified;
const bool mAutoResize;
const bool mUserResize;
S32 mExpandedMinDim;
S32 mMinDim;
S32 mMaxDim;
bool mAutoResize;
bool mUserResize;
bool mCollapsed;
F32 mVisibleAmt;
F32 mCollapseAmt;
F32 mFractionalSize;
S32 mTargetDim;
bool mIgnoreReshape;
LLLayoutStack::ELayoutOrientation mOrientation;
class LLResizeBar* mResizeBar;
};

View File

@ -1047,7 +1047,7 @@ void LLLineEditor::cut()
// Prepare for possible rollback
LLLineEditorRollback rollback( this );
gClipboard.copyFromSubstring( mText.getWString(), left_pos, length );
LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length );
deleteSelection();
// Validate new string and rollback the if needed.
@ -1078,13 +1078,13 @@ void LLLineEditor::copy()
{
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
gClipboard.copyFromSubstring( mText.getWString(), left_pos, length );
LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length );
}
}
BOOL LLLineEditor::canPaste() const
{
return !mReadOnly && gClipboard.canPasteString();
return !mReadOnly && LLClipboard::instance().isTextAvailable();
}
void LLLineEditor::paste()
@ -1115,14 +1115,7 @@ void LLLineEditor::pasteHelper(bool is_primary)
if (can_paste_it)
{
LLWString paste;
if (is_primary)
{
paste = gClipboard.getPastePrimaryWString();
}
else
{
paste = gClipboard.getPasteWString();
}
LLClipboard::instance().pasteFromClipboard(paste, is_primary);
if (!paste.empty())
{
@ -1209,13 +1202,13 @@ void LLLineEditor::copyPrimary()
{
S32 left_pos = llmin( mSelectionStart, mSelectionEnd );
S32 length = llabs( mSelectionStart - mSelectionEnd );
gClipboard.copyFromPrimarySubstring( mText.getWString(), left_pos, length );
LLClipboard::instance().copyToClipboard( mText.getWString(), left_pos, length, true);
}
}
BOOL LLLineEditor::canPastePrimary() const
{
return !mReadOnly && gClipboard.canPastePrimaryString();
return !mReadOnly && LLClipboard::instance().isTextAvailable(true);
}
void LLLineEditor::updatePrimary()
@ -1630,7 +1623,7 @@ void LLLineEditor::draw()
LLRect background( 0, getRect().getHeight(), getRect().getWidth(), 0 );
background.stretch( -mBorderThickness );
S32 lineeditor_v_pad = llround((background.getHeight() - mGLFont->getLineHeight())/2);
S32 lineeditor_v_pad = (background.getHeight() - mGLFont->getLineHeight()) / 2;
drawBackground();

View File

@ -317,7 +317,7 @@ void LLMenuItemGL::setJumpKey(KEY key)
// virtual
U32 LLMenuItemGL::getNominalHeight( void ) const
{
return llround(mFont->getLineHeight()) + MENU_ITEM_PADDING;
return mFont->getLineHeight() + MENU_ITEM_PADDING;
}
//virtual
@ -508,19 +508,19 @@ void LLMenuItemGL::draw( void )
{
if( !mDrawBoolLabel.empty() )
{
mFont->render( mDrawBoolLabel.getWString(), 0, (F32)LEFT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
mFont->render( mDrawBoolLabel.getWString(), 0, (F32)LEFT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color,
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
}
mFont->render( mLabel.getWString(), 0, (F32)LEFT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
mFont->render( mLabel.getWString(), 0, (F32)LEFT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color,
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
if( !mDrawAccelLabel.empty() )
{
mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
mFont->render( mDrawAccelLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PLAIN_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color,
LLFontGL::RIGHT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
}
if( !mDrawBranchLabel.empty() )
{
mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f) + 1.f, color,
mFont->render( mDrawBranchLabel.getWString(), 0, (F32)getRect().mRight - (F32)RIGHT_PAD_PIXELS, ((F32)MENU_ITEM_PADDING / 2.f), color,
LLFontGL::RIGHT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
}
}
@ -1966,7 +1966,7 @@ void LLMenuGL::arrange( void )
// *FIX: create the item first and then ask for its dimensions?
S32 spillover_item_width = PLAIN_PAD_PIXELS + LLFontGL::getFontSansSerif()->getWidth( std::string("More") ); // *TODO: Translate
S32 spillover_item_height = llround(LLFontGL::getFontSansSerif()->getLineHeight()) + MENU_ITEM_PADDING;
S32 spillover_item_height = LLFontGL::getFontSansSerif()->getLineHeight() + MENU_ITEM_PADDING;
// Scrolling support
item_list_t::iterator first_visible_item_iter;
@ -3082,7 +3082,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
mouse_y + MOUSE_CURSOR_PADDING,
CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2,
CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect, FALSE );
menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect );
menu->getParent()->sendChildToFront(menu);
}
@ -3425,7 +3425,7 @@ void LLMenuHolderGL::draw()
LLUI::pushMatrix();
{
LLUI::translate((F32)item_rect.mLeft, (F32)item_rect.mBottom, 0.f);
LLUI::translate((F32)item_rect.mLeft, (F32)item_rect.mBottom);
selecteditem->getMenu()->drawBackground(selecteditem, interpolant);
selecteditem->draw();
}

View File

@ -1412,6 +1412,7 @@ void addPathIfExists(const std::string& new_path, std::vector<std::string>& path
bool LLNotifications::loadTemplates()
{
llinfos << "Reading notifications template" << llendl;
std::vector<std::string> search_paths;
std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml";
@ -1484,6 +1485,8 @@ bool LLNotifications::loadTemplates()
mTemplates[notification.name] = LLNotificationTemplatePtr(new LLNotificationTemplate(notification));
}
llinfos << "...done" << llendl;
return true;
}

View File

@ -79,6 +79,8 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (!canResize()) return FALSE;
// Route future Mouse messages here preemptively. (Release on mouse up.)
// No handler needed for focus lost since this clas has no state that depends on it.
gFocusMgr.setMouseCapture( this );
@ -243,7 +245,7 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
handled = TRUE;
}
if( handled )
if( handled && canResize() )
{
switch( mSide )
{

View File

@ -70,6 +70,7 @@ public:
void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; }
void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
bool canResize() { return getEnabled() && mMaxSize > mMinSize; }
private:
S32 mDragLastScreenX;

View File

@ -378,19 +378,24 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
if (!mHideScrollbar)
{
if( *visible_height < doc_height )
// Note: 1 pixel change can happen on final animation and should not trigger
// the display of sliders.
if ((doc_height - *visible_height) > 1)
{
*show_v_scrollbar = TRUE;
*visible_width -= scrollbar_size;
}
if( *visible_width < doc_width )
if ((doc_width - *visible_width) > 1)
{
*show_h_scrollbar = TRUE;
*visible_height -= scrollbar_size;
// The view inside the scroll container should not be extended
// to container's full height to ensure the correct computation
// of *show_v_scrollbar after subtracting horizontal scrollbar_size.
// Must retest now that visible_height has changed
if( !*show_v_scrollbar && (*visible_height < doc_height) )
if( !*show_v_scrollbar && ((doc_height - *visible_height) > 1) )
{
*show_v_scrollbar = TRUE;
*visible_width -= scrollbar_size;
@ -424,63 +429,66 @@ void LLScrollContainer::draw()
focusFirstItem();
}
// Draw background
if( mIsOpaque )
if (getRect().isValid())
{
F32 alpha = getCurrentTransparency();
// Draw background
if( mIsOpaque )
{
F32 alpha = getCurrentTransparency();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gl_rect_2d(mInnerRect, mBackgroundColor.get() % alpha);
}
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gl_rect_2d(mInnerRect, mBackgroundColor.get() % alpha);
}
// Draw mScrolledViews and update scroll bars.
// get a scissor region ready, and draw the scrolling view. The
// scissor region ensures that we don't draw outside of the bounds
// of the rectangle.
if( mScrolledView )
{
updateScroll();
// Draw the scrolled area.
// Draw mScrolledViews and update scroll bars.
// get a scissor region ready, and draw the scrolling view. The
// scissor region ensures that we don't draw outside of the bounds
// of the rectangle.
if( mScrolledView )
{
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
updateScroll();
LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height,
mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0),
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0)
));
drawChild(mScrolledView);
// Draw the scrolled area.
{
S32 visible_width = 0;
S32 visible_height = 0;
BOOL show_v_scrollbar = FALSE;
BOOL show_h_scrollbar = FALSE;
calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
LLLocalClipRect clip(LLRect(mInnerRect.mLeft,
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0) + visible_height,
mInnerRect.mRight - (show_v_scrollbar ? scrollbar_size: 0),
mInnerRect.mBottom + (show_h_scrollbar ? scrollbar_size : 0)
));
drawChild(mScrolledView);
}
}
}
// Highlight border if a child of this container has keyboard focus
if( mBorder->getVisible() )
{
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
}
// Highlight border if a child of this container has keyboard focus
if( mBorder->getVisible() )
{
mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus(this) );
}
// Draw all children except mScrolledView
// Note: scrollbars have been adjusted by above drawing code
for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
child_iter != getChildList()->rend(); ++child_iter)
{
LLView *viewp = *child_iter;
if( sDebugRects )
// Draw all children except mScrolledView
// Note: scrollbars have been adjusted by above drawing code
for (child_list_const_reverse_iter_t child_iter = getChildList()->rbegin();
child_iter != getChildList()->rend(); ++child_iter)
{
sDepth++;
}
if( (viewp != mScrolledView) && viewp->getVisible() )
{
drawChild(viewp);
}
if( sDebugRects )
{
sDepth--;
LLView *viewp = *child_iter;
if( sDebugRects )
{
sDepth++;
}
if( (viewp != mScrolledView) && viewp->getVisible() )
{
drawChild(viewp);
}
if( sDebugRects )
{
sDepth--;
}
}
}
} // end draw

View File

@ -91,7 +91,7 @@ public:
void setReserveScrollCorner( BOOL b ) { mReserveScrollCorner = b; }
LLRect getVisibleContentRect();
LLRect getContentWindowRect();
const LLRect& getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
virtual const LLRect getScrolledViewRect() const { return mScrolledView ? mScrolledView->getRect() : LLRect::null; }
void pageUp(S32 overlap = 0);
void pageDown(S32 overlap = 0);
void goToTop();
@ -116,6 +116,9 @@ public:
bool autoScroll(S32 x, S32 y);
protected:
LLView* mScrolledView;
private:
// internal scrollbar handlers
virtual void scrollHorizontal( S32 new_pos );
@ -124,7 +127,6 @@ private:
void calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const;
LLScrollbar* mScrollbar[SCROLLBAR_COUNT];
LLView* mScrolledView;
S32 mSize;
BOOL mIsOpaque;
LLUIColor mBackgroundColor;

View File

@ -232,7 +232,7 @@ BOOL LLScrollListText::getVisible() const
//virtual
S32 LLScrollListText::getHeight() const
{
return llround(mFont->getLineHeight());
return mFont->getLineHeight();
}
@ -306,7 +306,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
break;
}
LLRect highlight_rect(left - 2,
llround(mFont->getLineHeight()) + 1,
mFont->getLineHeight() + 1,
left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1,
1);
mRoundedRectImage->draw(highlight_rect, highlight_color);
@ -329,7 +329,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
break;
}
mFont->render(mText.getWString(), 0,
start_x, 2.f,
start_x, 0.f,
display_color,
mFontAlignment,
LLFontGL::BOTTOM,

Some files were not shown because too many files have changed in this diff Show More