commit
6c71e11b2f
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
d4a366ed0f30c33e7523dca6ea6d0c469961fe68
|
||||
ff62e814853d28b800181543816108d445314182
|
||||
|
|
@ -1 +1 @@
|
|||
286d73ff5c19f6c00e023dc1b60975ed6bbe2872
|
||||
f8183e357a6f5a3d6d25a8dd0c09fa2bcd45e107
|
||||
89
.hgtags
89
.hgtags
|
|
@ -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
|
||||
|
|
|
|||
48
BuildParams
48
BuildParams
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
4
build.sh
4
build.sh
|
|
@ -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/"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -70,9 +70,10 @@ elseif (LINUX)
|
|||
QtNetwork
|
||||
QtGui
|
||||
QtCore
|
||||
qgif
|
||||
qjpeg
|
||||
jpeg
|
||||
jscore
|
||||
# qgif
|
||||
# qjpeg
|
||||
# jpeg
|
||||
fontconfig
|
||||
X11
|
||||
Xrender
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ class LLSDParam<T> \
|
|||
{ \
|
||||
public: \
|
||||
LLSDParam(const LLSD& value): \
|
||||
_value(value.AS()) \
|
||||
_value((T)value.AS()) \
|
||||
{} \
|
||||
\
|
||||
operator T() const { return _value; } \
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ void LLStatTime::stop()
|
|||
{
|
||||
if ( LLStatAccum::SCALE_PER_FRAME == scale )
|
||||
{
|
||||
return mTotalTimeInFrame;
|
||||
return (F32)mTotalTimeInFrame;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2078,6 +2078,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, 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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
//
|
||||
|
|
|
|||
|
|
@ -75,6 +75,12 @@ LLIOPipe::~LLIOPipe()
|
|||
//lldebugs << "destroying LLIOPipe" << llendl;
|
||||
}
|
||||
|
||||
//virtual
|
||||
bool LLIOPipe::isValid()
|
||||
{
|
||||
return true ;
|
||||
}
|
||||
|
||||
// static
|
||||
std::string LLIOPipe::lookupStatusString(EStatus status)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@ public:
|
|||
*/
|
||||
virtual ~LLIOPipe();
|
||||
|
||||
virtual bool isValid() ;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Base Constructor.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ bool LLSDMessage::httpListener(const LLSD& request)
|
|||
request,
|
||||
url, "POST", reply, error),
|
||||
LLSD(), // headers
|
||||
timeout);
|
||||
(F32)timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -188,6 +188,8 @@ public:
|
|||
*/
|
||||
void allowCookies();
|
||||
|
||||
/*virtual*/ bool isValid() ;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Give this pipe a chance to handle a generated error
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "message.h"
|
||||
#include "lltimer.h"
|
||||
#include "llextendedstatus.h"
|
||||
|
||||
const S32 LL_XFER_LARGE_PAYLOAD = 7680;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ©_from, S32 pos, S32 len, const LLUUID& source_id = LLUUID::null );
|
||||
void copyFromString(const LLWString ©_from, const LLUUID& source_id = LLUUID::null );
|
||||
BOOL canPasteString() const;
|
||||
const LLWString& getPasteWString(LLUUID* source_id = NULL);
|
||||
|
||||
void copyFromPrimarySubstring(const LLWString ©_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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue