Merge up from 24496 / a656486925e8 (FS tip) to 25952 / 931cb0061118 (V/Dev FUI tip)

Observations and broken stuff so far:
- LLSideTray is gone.
- LLBottomTray is gone.
- LLFloaterSnapshot was changed and gave lots of merge conflicts. Flickr upload will be broken.
- LLNearbyChat is derived from LLPanel now. That broke quite some stuff rearding autohiding and docking of chatbar.
- Profile floaters are gone and all web based now.
- Russian translation gave huge mere conflicts with the new russian xml files from LL. Unmergeable. I took the LL files.
- XUI files in general will need some love and testing.
master
Nicky 2012-01-17 17:57:52 +01:00
commit 161c1b019f
3007 changed files with 73111 additions and 133364 deletions

View File

@ -77,4 +77,5 @@ glob:indra/newview/search_history.txt
glob:indra/newview/filters.xml
glob:indra/newview/avatar_icons_cache.txt
glob:indra/newview/avatar_lad.log
glob:*.diff
glob:fmod*

40
.hgtags
View File

@ -1,3 +1,4 @@
bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2.1.1-release
003dd9461bfa479049afcc34545ab3431b147c7c v2start
08398e650c222336bb2b6de0cd3bba944aef11b4 2-1rn1
0962101bfa7df0643a6e625786025fe7f8a6dc97 2-1-beta-2
@ -199,6 +200,45 @@ dbaaef19266478a20654c46395300640163e98e3 3.1.0-beta2
bc01ee26fd0f1866e266429e85f76340523e91f1 3.1.0-beta2
ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 DRTVWR-92_3.1.0-release
ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 3.1.0-release
a8230590e28e4f30f5105549e0e43211d9d55711 3.2.0-start
e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
e440cd1dfbd128d7d5467019e497f7f803640ad6 3.2.0-beta1
9bcc2b7176634254e501e3fb4c5b56c1f637852e DRTVWR-97_3.2.0-beta2
9bcc2b7176634254e501e3fb4c5b56c1f637852e 3.2.0-beta2
2a13d30ee50ccfed50268238e36bb90d738ccc9e DRTVWR-98_3.2.0-beta3
2a13d30ee50ccfed50268238e36bb90d738ccc9e 3.2.0-beta3
3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
3fe994349fae64fc40874bb59db387131eb35a41 DRTVWR-104_3.2.4-beta1
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
8a44ff3d2104269ce76145c2772cf1bdff2a2abe 3.2.5-start
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
bd6bcde2584491fd9228f1fa51c4575f4e764e19 DRTVWR-103_3.2.4-release
bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
3d2d5d244c6398a4214c666d5dd3965b0918709a DRTVWR-106_3.2.5-beta1
3d2d5d244c6398a4214c666d5dd3965b0918709a 3.2.5-beta1
65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d DRTVWR-107_3.2.5-beta2
65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d 3.2.5-beta2
2174ed1c7129562428a5cfe8651ed77b8d26ae18 3.2.6-start
425f96b1e81e01644bf5e951961e7d1023bffb89 RLVa-1.2.0
fc0cbb86f5bd6e7737159e35aea2c4cf9f619b62 RLVa-1.2.1
43cb7dc1804de1a25c0b2b3f0715584af1f8b470 RLVa-1.2.2

View File

@ -136,14 +136,6 @@ viewer-mesh.login_channel = "Project Viewer - Mesh"
viewer-mesh.viewer_grid = aditi
viewer-mesh.email = shining@lists.lindenlab.com
# ========================================
# CG
# ========================================
cg_viewer-development_lenny.show_changes_since = 4b140ce7839d
cg_viewer-development_lenny.email = cg@lindenlab.com
# ================
# oz
# ================
@ -151,20 +143,31 @@ cg_viewer-development_lenny.email = cg@lindenlab.com
oz_viewer-devreview.build_debug_release_separately = true
oz_viewer-devreview.codeticket_add_context = false
oz_viewer-devreview.build_enforce_coding_policy = true
oz_viewer-devreview.email = oz@lindenlab.com
oz_project-1.build_debug_release_separately = true
oz_project-1.codeticket_add_context = false
oz_project-2.build_debug_release_separately = true
oz_project-2.codeticket_add_context = false
oz_project-3.build_debug_release_separately = true
oz_project-3.codeticket_add_context = false
oz_project-4.build_debug_release_separately = true
oz_project-4.codeticket_add_context = false
oz_viewer-trial.build_debug_release_separately = true
oz_viewer-trial.codeticket_add_context = false
oz_viewer-trial.build_enforce_coding_policy = true
oz_viewer-trial.email = oz@lindenlab.com
oz_viewer-beta-review.build_debug_release_separately = true
oz_viewer-beta-review.codeticket_add_context = false
oz_viewer-beta-review.viewer_channel = "Second Life Beta Viewer"
oz_viewer-beta-review.login_channel = "Second Life Beta Viewer"
oz_viewer-beta-review.email = oz@lindenlab.com
oz_project-1.build_debug_release_separately = true
oz_project-1.codeticket_add_context = false
oz_project-1.email = oz@lindenlab.com
oz_project-2.build_debug_release_separately = true
oz_project-2.codeticket_add_context = false
oz_project-2.email = oz@lindenlab.com
oz_project-3.build_debug_release_separately = true
oz_project-3.codeticket_add_context = false
oz_project-3.email = oz@lindenlab.com
oz_project-4.build_debug_release_separately = true
oz_project-4.codeticket_add_context = false
oz_project-4.email = oz@lindenlab.com
# =================================================================
# asset delivery 2010 projects
@ -190,4 +193,10 @@ simon_viewer-dev-private.public_build = false
simon_viewer-dev-private.email_status_this_is_os = false
# ========================================
# Vir
# ========================================
vir-project-1.viewer_channel = "Second Life Release"
vir-project-1.login_channel = "Second Life Release"
# eof

View File

@ -1206,9 +1206,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>1b92a69f5eba7cd8b017180659076db5</string>
<string>26aa7c367ffadd573f61a6a96f820f80</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/roxie_3p-llqtwebkit/rev/242182/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20111003.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/245988/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20111201.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@ -1230,9 +1230,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>1e7f24b69b0fc751c7e86efe7c621882</string>
<string>270db8568a0c4bab266d98e1a820aec4</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/roxie_3p-llqtwebkit/rev/242182/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20111003.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/245988/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20111201.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>

View File

@ -171,6 +171,8 @@ Ansariel Hiller
STORM-1101
VWR-25480
VWR-26150
STORM-1685
STORM-1713
Aralara Rajal
Ardy Lay
STORM-859
@ -483,6 +485,7 @@ Ima Mechanique
OPEN-76
STORM-959
STORM-1175
STORM-1708
Imnotgoing Sideways
Inma Rau
Innula Zenovka
@ -578,9 +581,34 @@ Jonathan Yap
STORM-1572
STORM-1574
STORM-1579
STORM-1638
STORM-976
STORM-1639
STORM-910
STORM-1653
STORM-1642
STORM-591
STORM-1105
STORM-1679
STORM-1222
STORM-1659
STORM-1674
STORM-1685
STORM-1721
STORM-1727
STORM-1725
STORM-1719
STORM-1712
STORM-1728
STORM-1736
STORM-1734
STORM-1731
STORM-653
STORM-1737
STORM-1733
STORM-1790
Kadah Coba
STORM-1060
STORM-1060
Jondan Lundquist
Josef Munster
Josette Windlow
@ -913,6 +941,7 @@ Robin Cornelius
SNOW-599
SNOW-747
STORM-422
STORM-591
STORM-960
STORM-1019
STORM-1095
@ -1107,6 +1136,9 @@ Tofu Buzzard
CTS-411
STORM-546
VWR-24509
STORM-1684
SH-2477
STORM-1684
Tony Kembia
Torben Trautman
TouchaHoney Perhaps
@ -1140,6 +1172,7 @@ Vector Hastings
VWR-8726
Veritas Raymaker
Vex Streeter
STORM-1642
Viaticus Speculaas
Vick Forcella
Villain Baroque
@ -1225,6 +1258,7 @@ Zi Ree
VWR-1140
VWR-24017
VWR-25588
STORM-1790
Zipherius Turas
VWR-76
VWR-77

View File

@ -1,4 +1,3 @@
# -*- cmake -*-
# cmake_minimum_required should appear before any
@ -70,6 +69,9 @@ if (VIEWER)
add_subdirectory(${LIBS_OPEN_PREFIX}llxuixml)
add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
# Legacy C++ tests. Build always, run if LL_TESTS is true.
add_subdirectory(${VIEWER_PREFIX}test)
# viewer media plugins
add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)

View File

@ -46,7 +46,7 @@ if (WINDOWS)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP -D_SCL_SECURE_NO_WARNINGS=1"
CACHE STRING "C++ compiler debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /Ob2 /Gm -D_SECURE_STL=0"
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /Ob0 -D_SECURE_STL=0"
CACHE STRING "C++ compiler release-with-debug options" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2 /Oi /Ot /GF /Gy /arch:SSE2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
@ -64,7 +64,7 @@ if (WINDOWS)
/D_UNICODE
/GS
/TP
/W2
/W3
/c
/Zc:forScope
/nologo

View File

@ -71,6 +71,7 @@ endif (DARWIN)
# Sort by high-level to low-level
target_link_libraries(llui_libtest
llui
llinventory
llmessage
${LLRENDER_LIBRARIES}
${LLIMAGE_LIBRARIES}

View File

@ -133,6 +133,12 @@ bool LLCrashLoggerLinux::mainLoop()
return true;
}
bool LLCrashLoggerLinux::cleanup()
{
commonCleanup();
return true;
}
void LLCrashLoggerLinux::updateApplication(const std::string& message)
{
LLCrashLogger::updateApplication(message);

View File

@ -39,6 +39,7 @@ public:
virtual bool mainLoop();
virtual void updateApplication(const std::string& = LLStringUtil::null);
virtual void gatherPlatformSpecificFiles();
virtual bool cleanup();
};
#endif

View File

@ -1269,6 +1269,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
mSyncSlave(false),
mQueueSounds(false),
mPlayedOnce(false),
mCorrupted(false),
mType(type),
mChannelp(NULL),
mCurrentDatap(NULL),
@ -1301,16 +1302,25 @@ void LLAudioSource::setChannel(LLAudioChannel *channelp)
void LLAudioSource::update()
{
if(mCorrupted)
{
return ; //no need to update
}
if (!getCurrentBuffer())
{
if (getCurrentData())
{
// Hack - try and load the sound. Will do this as a callback
// on decode later.
if (getCurrentData()->load())
if (getCurrentData()->load() && getCurrentData()->getBuffer())
{
play(getCurrentData()->getID());
}
}
else
{
mCorrupted = true ;
}
}
}
}
@ -1426,6 +1436,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
bool LLAudioSource::isDone() const
{
if(mCorrupted)
{
return true ;
}
const F32 MAX_AGE = 60.f;
const F32 MAX_UNPLAYED_AGE = 15.f;
const F32 MAX_MUTED_AGE = 11.f;
@ -1741,7 +1756,7 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
}
}
//return false when the audio file is corrupted.
bool LLAudioData::load()
{
// For now, just assume we're going to use one buffer per audiodata.
@ -1757,7 +1772,7 @@ bool LLAudioData::load()
{
// No free buffers, abort.
llinfos << "Not able to allocate a new audio buffer, aborting." << llendl;
return false;
return true;
}
std::string uuid_str;

View File

@ -334,6 +334,7 @@ protected:
bool mSyncSlave;
bool mQueueSounds;
bool mPlayedOnce;
bool mCorrupted;
S32 mType;
LLVector3d mPositionGlobal;
LLVector3 mVelocity;

View File

@ -93,7 +93,8 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true));
addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
};

View File

@ -108,9 +108,13 @@ public:
AT_LINK_FOLDER = 25,
// Inventory folder link
AT_WIDGET = 40,
// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
AT_MESH = 49,
// Mesh data in our proprietary SLM format
// Mesh data in our proprietary SLM format
AT_COUNT = 50,
// +*********************************************************+

View File

@ -620,6 +620,12 @@ namespace LLError
s.defaultLevel = level;
}
ELevel getDefaultLevel()
{
Settings& s = Settings::get();
return s.defaultLevel;
}
void setFunctionLevel(const std::string& function_name, ELevel level)
{
Globals& g = Globals::get();

View File

@ -75,6 +75,7 @@ namespace LLError
LL_COMMON_API void setPrintLocation(bool);
LL_COMMON_API void setDefaultLevel(LLError::ELevel);
LL_COMMON_API ELevel getDefaultLevel();
LL_COMMON_API void setFunctionLevel(const std::string& function_name, LLError::ELevel);
LL_COMMON_API void setClassLevel(const std::string& class_name, LLError::ELevel);
LL_COMMON_API void setFileLevel(const std::string& file_name, LLError::ELevel);

View File

@ -151,6 +151,7 @@
#pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class
#pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class
#pragma warning (disable : 4018) // '<' : signed/unsigned mismatch
#endif // LL_MSVC
#if LL_WINDOWS

View File

@ -24,6 +24,9 @@
* $/LicenseInfo$
*/
// Must turn on conditional declarations in header file so definitions end up
// with proper linkage.
#define LLSD_DEBUG_INFO
#include "linden_common.h"
#include "llsd.h"
@ -31,6 +34,7 @@
#include "../llmath/llmath.h"
#include "llformat.h"
#include "llsdserialize.h"
#include "stringize.h"
#ifndef LL_RELEASE_FOR_DOWNLOAD
#define NAME_UNNAMED_NAMESPACE
@ -50,6 +54,18 @@ namespace
using namespace LLSDUnnamedNamespace;
#endif
namespace llsd
{
// statics
S32 sLLSDAllocationCount = 0;
S32 sLLSDNetObjects = 0;
} // namespace llsd
#define ALLOC_LLSD_OBJECT { llsd::sLLSDNetObjects++; llsd::sLLSDAllocationCount++; }
#define FREE_LLSD_OBJECT { llsd::sLLSDNetObjects--; }
class LLSD::Impl
/**< This class is the abstract base class of the implementation of LLSD
It provides the reference counting implementation, and the default
@ -58,13 +74,10 @@ class LLSD::Impl
*/
{
private:
U32 mUseCount;
protected:
Impl();
enum StaticAllocationMarker { STATIC };
enum StaticAllocationMarker { STATIC_USAGE_COUNT = 0xFFFFFFFF };
Impl(StaticAllocationMarker);
///< This constructor is used for static objects and causes the
// suppresses adjusting the debugging counters when they are
@ -72,8 +85,10 @@ protected:
virtual ~Impl();
bool shared() const { return mUseCount > 1; }
bool shared() const { return (mUseCount > 1) && (mUseCount != STATIC_USAGE_COUNT); }
U32 mUseCount;
public:
static void reset(Impl*& var, Impl* impl);
///< safely set var to refer to the new impl (possibly shared)
@ -128,6 +143,18 @@ public:
virtual LLSD::array_const_iterator beginArray() const { return endArray(); }
virtual LLSD::array_const_iterator endArray() const { static const std::vector<LLSD> empty; return empty.end(); }
virtual void dumpStats() const;
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
// Container subclasses contain LLSD objects, rather than directly
// containing Impl objects. This helper forwards through LLSD.
void calcStats(const LLSD& llsd, S32 type_counts[], S32 share_counts[]) const
{
safe(llsd.impl).calcStats(type_counts, share_counts);
}
static const Impl& getImpl(const LLSD& llsd) { return safe(llsd.impl); }
static Impl& getImpl(LLSD& llsd) { return safe(llsd.impl); }
static const LLSD& undef();
static U32 sAllocationCount;
@ -360,6 +387,9 @@ namespace
LLSD::map_iterator endMap() { return mData.end(); }
virtual LLSD::map_const_iterator beginMap() const { return mData.begin(); }
virtual LLSD::map_const_iterator endMap() const { return mData.end(); }
virtual void dumpStats() const;
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
};
ImplMap& ImplMap::makeMap(LLSD::Impl*& var)
@ -414,6 +444,34 @@ namespace
return i->second;
}
void ImplMap::dumpStats() const
{
std::cout << "Map size: " << mData.size() << std::endl;
std::cout << "LLSD Net Objects: " << llsd::sLLSDNetObjects << std::endl;
std::cout << "LLSD allocations: " << llsd::sLLSDAllocationCount << std::endl;
std::cout << "LLSD::Impl Net Objects: " << sOutstandingCount << std::endl;
std::cout << "LLSD::Impl allocations: " << sAllocationCount << std::endl;
Impl::dumpStats();
}
void ImplMap::calcStats(S32 type_counts[], S32 share_counts[]) const
{
LLSD::map_const_iterator iter = beginMap();
while (iter != endMap())
{
//std::cout << " " << (*iter).first << ": " << (*iter).second << std::endl;
Impl::calcStats((*iter).second, type_counts, share_counts);
iter++;
}
// Add in the values for this map
Impl::calcStats(type_counts, share_counts);
}
class ImplArray : public LLSD::Impl
{
private:
@ -449,6 +507,8 @@ namespace
LLSD::array_iterator endArray() { return mData.end(); }
virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); }
virtual LLSD::array_const_iterator endArray() const { return mData.end(); }
virtual void calcStats(S32 type_counts[], S32 share_counts[]) const;
};
ImplArray& ImplArray::makeArray(Impl*& var)
@ -490,12 +550,13 @@ namespace
void ImplArray::insert(LLSD::Integer i, const LLSD& v)
{
if (i < 0) {
if (i < 0)
{
return;
}
DataVector::size_type index = i;
if (index >= mData.size())
if (index >= mData.size()) // tbd - sanity check limit for index ?
{
mData.resize(index + 1);
}
@ -543,6 +604,19 @@ namespace
return mData[index];
}
void ImplArray::calcStats(S32 type_counts[], S32 share_counts[]) const
{
LLSD::array_const_iterator iter = beginArray();
while (iter != endArray())
{ // Add values for all items held in the array
Impl::calcStats((*iter), type_counts, share_counts);
iter++;
}
// Add in the values for this array
Impl::calcStats(type_counts, share_counts);
}
}
LLSD::Impl::Impl()
@ -564,8 +638,11 @@ LLSD::Impl::~Impl()
void LLSD::Impl::reset(Impl*& var, Impl* impl)
{
if (impl) ++impl->mUseCount;
if (var && --var->mUseCount == 0)
if (impl && impl->mUseCount != STATIC_USAGE_COUNT)
{
++impl->mUseCount;
}
if (var && var->mUseCount != STATIC_USAGE_COUNT && --var->mUseCount == 0)
{
delete var;
}
@ -574,13 +651,13 @@ void LLSD::Impl::reset(Impl*& var, Impl* impl)
LLSD::Impl& LLSD::Impl::safe(Impl* impl)
{
static Impl theUndefined(STATIC);
static Impl theUndefined(STATIC_USAGE_COUNT);
return impl ? *impl : theUndefined;
}
const LLSD::Impl& LLSD::Impl::safe(const Impl* impl)
{
static Impl theUndefined(STATIC);
static Impl theUndefined(STATIC_USAGE_COUNT);
return impl ? *impl : theUndefined;
}
@ -656,6 +733,43 @@ const LLSD& LLSD::Impl::undef()
return immutableUndefined;
}
void LLSD::Impl::dumpStats() const
{
S32 type_counts[LLSD::TypeLLSDNumTypes + 1];
memset(&type_counts, 0, sizeof(type_counts));
S32 share_counts[LLSD::TypeLLSDNumTypes + 1];
memset(&share_counts, 0, sizeof(share_counts));
// Add info from all the values this object has
calcStats(type_counts, share_counts);
S32 type_index = LLSD::TypeLLSDTypeBegin;
while (type_index != LLSD::TypeLLSDTypeEnd)
{
std::cout << LLSD::typeString((LLSD::Type)type_index) << " type "
<< type_counts[type_index] << " objects, "
<< share_counts[type_index] << " shared"
<< std::endl;
type_index++;
}
}
void LLSD::Impl::calcStats(S32 type_counts[], S32 share_counts[]) const
{
S32 tp = S32(type());
if (0 <= tp && tp < LLSD::TypeLLSDNumTypes)
{
type_counts[tp]++;
if (shared())
{
share_counts[tp]++;
}
}
}
U32 LLSD::Impl::sAllocationCount = 0;
U32 LLSD::Impl::sOutstandingCount = 0;
@ -681,10 +795,10 @@ namespace
}
LLSD::LLSD() : impl(0) { }
LLSD::~LLSD() { Impl::reset(impl, 0); }
LLSD::LLSD() : impl(0) { ALLOC_LLSD_OBJECT; }
LLSD::~LLSD() { FREE_LLSD_OBJECT; Impl::reset(impl, 0); }
LLSD::LLSD(const LLSD& other) : impl(0) { assign(other); }
LLSD::LLSD(const LLSD& other) : impl(0) { ALLOC_LLSD_OBJECT; assign(other); }
void LLSD::assign(const LLSD& other) { Impl::assign(impl, other.impl); }
@ -692,18 +806,18 @@ void LLSD::clear() { Impl::assignUndefined(impl); }
LLSD::Type LLSD::type() const { return safe(impl).type(); }
// Scaler Constructors
LLSD::LLSD(Boolean v) : impl(0) { assign(v); }
LLSD::LLSD(Integer v) : impl(0) { assign(v); }
LLSD::LLSD(Real v) : impl(0) { assign(v); }
LLSD::LLSD(const UUID& v) : impl(0) { assign(v); }
LLSD::LLSD(const String& v) : impl(0) { assign(v); }
LLSD::LLSD(const Date& v) : impl(0) { assign(v); }
LLSD::LLSD(const URI& v) : impl(0) { assign(v); }
LLSD::LLSD(const Binary& v) : impl(0) { assign(v); }
// Scalar Constructors
LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(Real v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const UUID& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const String& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
// Convenience Constructors
LLSD::LLSD(F32 v) : impl(0) { assign((Real)v); }
LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); }
// Scalar Assignment
void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); }
@ -726,7 +840,7 @@ LLSD::URI LLSD::asURI() const { return safe(impl).asURI(); }
LLSD::Binary LLSD::asBinary() const { return safe(impl).asBinary(); }
// const char * helpers
LLSD::LLSD(const char* v) : impl(0) { assign(v); }
LLSD::LLSD(const char* v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); }
void LLSD::assign(const char* v)
{
if(v) assign(std::string(v));
@ -784,9 +898,6 @@ LLSD& LLSD::operator[](Integer i)
const LLSD& LLSD::operator[](Integer i) const
{ return safe(impl).ref(i); }
U32 LLSD::allocationCount() { return Impl::sAllocationCount; }
U32 LLSD::outstandingCount() { return Impl::sOutstandingCount; }
static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
{
// sStorage is used to hold the string representation of the llsd last
@ -801,15 +912,9 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat)
{
std::ostringstream out;
if (useXMLFormat)
{
LLSDXMLStreamer xml_streamer(llsd);
out << xml_streamer;
}
out << LLSDXMLStreamer(llsd);
else
{
LLSDNotationStreamer notation_streamer(llsd);
out << notation_streamer;
}
out << LLSDNotationStreamer(llsd);
out_string = out.str();
}
int len = out_string.length();
@ -840,3 +945,38 @@ LLSD::array_iterator LLSD::beginArray() { return makeArray(impl).beginArray();
LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); }
LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); }
LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); }
namespace llsd
{
U32 allocationCount() { return LLSD::Impl::sAllocationCount; }
U32 outstandingCount() { return LLSD::Impl::sOutstandingCount; }
// Diagnostic dump of contents in an LLSD object
void dumpStats(const LLSD& llsd) { LLSD::Impl::getImpl(llsd).dumpStats(); }
} // namespace llsd
// static
std::string LLSD::typeString(Type type)
{
static const char * sTypeNameArray[] = {
"Undefined",
"Boolean",
"Integer",
"Real",
"String",
"UUID",
"Date",
"URI",
"Binary",
"Map",
"Array"
};
if (0 <= type && type < LL_ARRAY_SIZE(sTypeNameArray))
{
return sTypeNameArray[type];
}
return STRINGIZE("** invalid type value " << type);
}

View File

@ -40,10 +40,10 @@
/**
LLSD provides a flexible data system similar to the data facilities of
dynamic languages like Perl and Python. It is created to support exchange
of structured data between loosly coupled systems. (Here, "loosly coupled"
of structured data between loosely coupled systems. (Here, "loosely coupled"
means not compiled together into the same module.)
Data in such exchanges must be highly tollerant of changes on either side
Data in such exchanges must be highly tolerant of changes on either side
such as:
- recompilation
- implementation in a different langauge
@ -51,19 +51,19 @@
- execution of older versions (with fewer parameters)
To this aim, the C++ API of LLSD strives to be very easy to use, and to
default to "the right thing" whereever possible. It is extremely tollerant
default to "the right thing" wherever possible. It is extremely tolerant
of errors and unexpected situations.
The fundimental class is LLSD. LLSD is a value holding object. It holds
The fundamental class is LLSD. LLSD is a value holding object. It holds
one value that is either undefined, one of the scalar types, or a map or an
array. LLSD objects have value semantics (copying them copies the value,
though it can be considered efficient, due to shareing.), and mutable.
though it can be considered efficient, due to sharing), and mutable.
Undefined is the singular value given to LLSD objects that are not
initialized with any data. It is also used as the return value for
operations that return an LLSD,
operations that return an LLSD.
The sclar data types are:
The scalar data types are:
- Boolean - true or false
- Integer - a 32 bit signed integer
- Real - a 64 IEEE 754 floating point value
@ -80,9 +80,73 @@
An array is a sequence of zero or more LLSD values.
Thread Safety
In general, these LLSD classes offer *less* safety than STL container
classes. Implementations prior to this one were unsafe even when
completely unrelated LLSD trees were in two threads due to reference
sharing of special 'undefined' values that participated in the reference
counting mechanism.
The dereference-before-refcount and aggressive tree sharing also make
it impractical to share an LLSD across threads. A strategy of passing
ownership or a copy to another thread is still difficult due to a lack
of a cloning interface but it can be done with some care.
One way of transferring ownership is as follows:
void method(const LLSD input) {
...
LLSD * xfer_tree = new LLSD();
{
// Top-level values
(* xfer_tree)['label'] = "Some text";
(* xfer_tree)['mode'] = APP_MODE_CONSTANT;
// There will be a second-level
LLSD subtree(LLSD::emptyMap());
(* xfer_tree)['subtree'] = subtree;
// Do *not* copy from LLSD objects via LLSD
// intermediaries. Only use plain-old-data
// types as intermediaries to prevent reference
// sharing.
subtree['value1'] = input['value1'].asInteger();
subtree['value2'] = input['value2'].asString();
// Close scope and drop 'subtree's reference.
// Only xfer_tree has a reference to the second
// level data.
}
...
// Transfer the LLSD pointer to another thread. Ownership
// transfers, this thread no longer has a reference to any
// part of the xfer_tree and there's nothing to free or
// release here. Receiving thread does need to delete the
// pointer when it is done with the LLSD. Transfer
// mechanism must perform correct data ordering operations
// as dictated by architecture.
other_thread.sendMessageAndPointer("Take This", xfer_tree);
xfer_tree = NULL;
Avoid this pattern which provides half of a race condition:
void method(const LLSD input) {
...
LLSD xfer_tree(LLSD::emptyMap());
xfer_tree['label'] = "Some text";
xfer_tree['mode'] = APP_MODE_CONSTANT;
...
other_thread.sendMessageAndPointer("Take This", xfer_tree);
@nosubgrouping
*/
// Normally undefined, used for diagnostics
//#define LLSD_DEBUG_INFO 1
class LL_COMMON_API LLSD
{
public:
@ -202,7 +266,7 @@ public:
//@}
/** @name Character Pointer Helpers
These are helper routines to make working with char* the same as easy as
These are helper routines to make working with char* as easy as
working with strings.
*/
//@{
@ -266,7 +330,7 @@ public:
/** @name Type Testing */
//@{
enum Type {
TypeUndefined,
TypeUndefined = 0,
TypeBoolean,
TypeInteger,
TypeReal,
@ -276,7 +340,10 @@ public:
TypeURI,
TypeBinary,
TypeMap,
TypeArray
TypeArray,
TypeLLSDTypeEnd,
TypeLLSDTypeBegin = TypeUndefined,
TypeLLSDNumTypes = (TypeLLSDTypeEnd - TypeLLSDTypeBegin)
};
Type type() const;
@ -302,7 +369,7 @@ public:
If you get a linker error about these being missing, you have made
mistake in your code. DO NOT IMPLEMENT THESE FUNCTIONS as a fix.
All of thse problems stem from trying to support char* in LLSD or in
All of these problems stem from trying to support char* in LLSD or in
std::string. There are too many automatic casts that will lead to
using an arbitrary pointer or scalar type to std::string.
*/
@ -311,7 +378,7 @@ public:
void assign(const void*); ///< assign from arbitrary pointers
LLSD& operator=(const void*); ///< assign from arbitrary pointers
bool has(Integer) const; ///< has only works for Maps
bool has(Integer) const; ///< has() only works for Maps
//@}
/** @name Implementation */
@ -320,13 +387,7 @@ public:
class Impl;
private:
Impl* impl;
//@}
/** @name Unit Testing Interface */
//@{
public:
static U32 allocationCount(); ///< how many Impls have been made
static U32 outstandingCount(); ///< how many Impls are still alive
friend class LLSD::Impl;
//@}
private:
@ -338,6 +399,10 @@ private:
/// Returns Notation version of llsd -- only to be called from debugger
static const char *dump(const LLSD &llsd);
//@}
public:
static std::string typeString(Type type); // Return human-readable type as a string
};
struct llsd_select_bool : public std::unary_function<LLSD, LLSD::Boolean>
@ -385,9 +450,32 @@ struct llsd_select_string : public std::unary_function<LLSD, LLSD::String>
LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd);
namespace llsd
{
#ifdef LLSD_DEBUG_INFO
/** @name Unit Testing Interface */
//@{
LL_COMMON_API void dumpStats(const LLSD&); ///< Output information on object and usage
/// @warn THE FOLLOWING COUNTS WILL NOT BE ACCURATE IN A MULTI-THREADED
/// ENVIRONMENT.
///
/// These counts track LLSD::Impl (hidden) objects.
LL_COMMON_API U32 allocationCount(); ///< how many Impls have been made
LL_COMMON_API U32 outstandingCount(); ///< how many Impls are still alive
/// These counts track LLSD (public) objects.
LL_COMMON_API extern S32 sLLSDAllocationCount; ///< Number of LLSD objects ever created
LL_COMMON_API extern S32 sLLSDNetObjects; ///< Number of LLSD objects that exist
#endif
//@}
} // namespace llsd
/** QUESTIONS & TO DOS
- Would Binary be more convenient as usigned char* buffer semantics?
- Should Binary be convertable to/from String, and if so how?
- Would Binary be more convenient as unsigned char* buffer semantics?
- Should Binary be convertible to/from String, and if so how?
- as UTF8 encoded strings (making not like UUID<->String)
- as Base64 or Base96 encoded (making like UUID<->String)
- Conversions to std::string and LLUUID do not result in easy assignment

View File

@ -611,6 +611,7 @@ LLCPUInfo::LLCPUInfo()
out << " (" << mCPUMHz << " MHz)";
}
mCPUString = out.str();
LLStringUtil::trim(mCPUString);
}
bool LLCPUInfo::hasAltivec() const

View File

@ -29,7 +29,7 @@
const S32 LL_VERSION_MAJOR = 3;
const S32 LL_VERSION_MINOR = 2;
const S32 LL_VERSION_PATCH = 1;
const S32 LL_VERSION_PATCH = 7;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Firestorm-private";

View File

@ -49,8 +49,9 @@ enum EDragAndDropType
DAD_ANIMATION = 12,
DAD_GESTURE = 13,
DAD_LINK = 14,
DAD_MESH = 15,
DAD_COUNT = 16, // number of types in this enum
DAD_MESH = 15,
DAD_WIDGET = 16,
DAD_COUNT = 17, // number of types in this enum
};
// Reasons for drags to be denied.

View File

@ -42,6 +42,7 @@
#include "llpumpio.h"
#include "llhttpclient.h"
#include "llsdserialize.h"
#include "llproxy.h"
// [SL:KB] - Patch: Viewer-CrashLookup | Checked: 2011-03-24 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
#ifdef LL_WINDOWS
@ -596,3 +597,9 @@ bool LLCrashLogger::init()
return true;
}
// For cleanup code common to all platforms.
void LLCrashLogger::commonCleanup()
{
LLProxy::cleanupClass();
}

View File

@ -51,7 +51,8 @@ public:
virtual void updateApplication(const std::string& message = LLStringUtil::null);
virtual bool init();
virtual bool mainLoop() = 0;
virtual bool cleanup() { return true; }
virtual bool cleanup() = 0;
void commonCleanup();
void setUserText(const std::string& text) { mCrashInfo["UserNotes"] = text; }
S32 getCrashBehavior() { return mCrashBehavior; }
bool runCrashLogPost(std::string host, LLSD data, std::string msg, int retries, int timeout);

View File

@ -48,6 +48,31 @@ LLGlobalEconomy::LLGlobalEconomy()
LLGlobalEconomy::~LLGlobalEconomy()
{ }
void LLGlobalEconomy::addObserver(LLEconomyObserver* observer)
{
mObservers.push_back(observer);
}
void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer)
{
std::list<LLEconomyObserver*>::iterator it =
std::find(mObservers.begin(), mObservers.end(), observer);
if (it != mObservers.end())
{
mObservers.erase(it);
}
}
void LLGlobalEconomy::notifyObservers()
{
for (std::list<LLEconomyObserver*>::iterator it = mObservers.begin();
it != mObservers.end();
++it)
{
(*it)->onEconomyDataChange();
}
}
// static
void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data)
{
@ -88,6 +113,8 @@ void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy*
econ_data->setTeleportPriceExponent(f);
msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceGroupCreate, i);
econ_data->setPriceGroupCreate(i);
econ_data->notifyObservers();
}
S32 LLGlobalEconomy::calculateTeleportCost(F32 distance) const

View File

@ -31,6 +31,16 @@
class LLMessageSystem;
class LLVector3;
/**
* Register an observer to be notified of economy data updates coming from server.
*/
class LLEconomyObserver
{
public:
virtual ~LLEconomyObserver() {}
virtual void onEconomyDataChange() = 0;
};
class LLGlobalEconomy
{
public:
@ -46,6 +56,10 @@ public:
virtual void print();
void addObserver(LLEconomyObserver* observer);
void removeObserver(LLEconomyObserver* observer);
void notifyObservers();
static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data);
S32 calculateTeleportCost(F32 distance) const;
@ -89,6 +103,8 @@ private:
S32 mTeleportMinPrice;
F32 mTeleportPriceExponent;
S32 mPriceGroupCreate;
std::list<LLEconomyObserver*> mObservers;
};

View File

@ -84,6 +84,7 @@ LLInventoryDictionary::LLInventoryDictionary()
addEntry(LLInventoryType::IT_ANIMATION, new InventoryEntry("animation", "animation", 1, LLAssetType::AT_ANIMATION));
addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE));
addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH));
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
}
@ -134,7 +135,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
LLInventoryType::IT_NONE, // 37 AT_NONE
LLInventoryType::IT_NONE, // 38 AT_NONE
LLInventoryType::IT_NONE, // 39 AT_NONE
LLInventoryType::IT_NONE, // 40 AT_NONE
LLInventoryType::IT_WIDGET, // 40 AT_WIDGET
LLInventoryType::IT_NONE, // 41 AT_NONE
LLInventoryType::IT_NONE, // 42 AT_NONE
LLInventoryType::IT_NONE, // 43 AT_NONE
@ -143,7 +144,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
LLInventoryType::IT_NONE, // 46 AT_NONE
LLInventoryType::IT_NONE, // 47 AT_NONE
LLInventoryType::IT_NONE, // 48 AT_NONE
LLInventoryType::IT_MESH // 49 AT_MESH
LLInventoryType::IT_MESH, // 49 AT_MESH
};
// static

View File

@ -62,7 +62,8 @@ public:
IT_ANIMATION = 19,
IT_GESTURE = 20,
IT_MESH = 22,
IT_COUNT = 23,
IT_WIDGET = 23,
IT_COUNT = 24,
IT_NONE = -1
};

View File

@ -75,10 +75,6 @@ set(llmath_HEADER_FILES
llvector4a.h
llvector4a.inl
llvector4logical.h
llv4math.h
llv4matrix3.h
llv4matrix4.h
llv4vector3.h
llvolume.h
llvolumemgr.h
llvolumeoctree.h

View File

@ -685,7 +685,7 @@ public:
if (lt != 0x7)
{
OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl;
//OCT_ERRS << "!!! ELEMENT EXCEEDS RANGE OF SPATIAL PARTITION !!!" << llendl;
return false;
}

View File

@ -1,141 +0,0 @@
/**
* @file llv4math.h
* @brief LLV4* class header file - vector processor enabled math
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLV4MATH_H
#define LL_LLV4MATH_H
// *NOTE: We do not support SSE acceleration on Windows builds.
// Our minimum specification for the viewer includes 1 GHz Athlon processors,
// which covers the Athlon Thunderbird series that does not support SSE.
//
// Our header files include statements like this
// const F32 HAVOK_TIMESTEP = 1.f / 45.f;
// This creates "globals" that are included in each .obj file. If a single
// .cpp file has SSE code generation turned on (eg, llviewerjointmesh_sse.cpp)
// these globals will be initialized using SSE instructions. This causes SL
// to crash before main() on processors without SSE. Untangling all these
// headers/variables is too much work for the small performance gains of
// vectorization.
//
// Therefore we only support vectorization on builds where the everything is
// built with SSE or Altivec. See https://jira.secondlife.com/browse/VWR-1610
// and https://jira.lindenlab.com/browse/SL-47720 for details.
//
// Sorry the code is such a mess. JC
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4MATH - GNUC
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#if LL_GNUC && __GNUC__ >= 4 && __SSE__
#define LL_VECTORIZE 1
#if LL_DARWIN
#include <Accelerate/Accelerate.h>
#include <xmmintrin.h>
typedef vFloat V4F32;
#else
#include <xmmintrin.h>
typedef float V4F32 __attribute__((vector_size(16)));
#endif
#endif
#if LL_GNUC
#define LL_LLV4MATH_ALIGN_PREFIX
#define LL_LLV4MATH_ALIGN_POSTFIX __attribute__((aligned(16)))
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4MATH - MSVC
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Only vectorize if the entire Windows build uses SSE.
// _M_IX86_FP is set when SSE code generation is turned on, and I have
// confirmed this in VS2003, VS2003 SP1, and VS2005. JC
#if LL_MSVC && _M_IX86_FP
#define LL_VECTORIZE 1
#include <xmmintrin.h>
typedef __m128 V4F32;
#endif
#if LL_MSVC
#define LL_LLV4MATH_ALIGN_PREFIX __declspec(align(16))
#define LL_LLV4MATH_ALIGN_POSTFIX
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4MATH - default - no vectorization
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#if !LL_VECTORIZE
#define LL_VECTORIZE 0
struct V4F32 { F32 __pad__[4]; };
inline F32 llv4lerp(F32 a, F32 b, F32 w) { return ( b - a ) * w + a; }
#endif
#ifndef LL_LLV4MATH_ALIGN_PREFIX
# define LL_LLV4MATH_ALIGN_PREFIX
#endif
#ifndef LL_LLV4MATH_ALIGN_POSTFIX
# define LL_LLV4MATH_ALIGN_POSTFIX
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4MATH
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#define LLV4_NUM_AXIS 4
class LLV4Vector3;
class LLV4Matrix3;
class LLV4Matrix4;
#endif

View File

@ -1,220 +0,0 @@
/**
* @file llviewerjointmesh.cpp
* @brief LLV4* class header file - vector processor enabled math
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLV4MATRIX3_H
#define LL_LLV4MATRIX3_H
#include "llv4math.h"
#include "llv4vector3.h"
#include "m3math.h" // for operator LLMatrix3()
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Matrix3
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
LL_LLV4MATH_ALIGN_PREFIX
class LLV4Matrix3
{
public:
union {
F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
V4F32 mV[LLV4_NUM_AXIS];
};
void lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w);
void multiply(const LLVector3 &a, LLVector3& out) const;
void multiply(const LLVector4 &a, LLV4Vector3& out) const;
void multiply(const LLVector3 &a, LLV4Vector3& out) const;
const LLV4Matrix3& transpose();
const LLV4Matrix3& operator=(const LLMatrix3& a);
operator LLMatrix3() const { return (reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0])))->getMat3(); }
friend LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b);
}
LL_LLV4MATH_ALIGN_POSTFIX;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Matrix3 - SSE
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#if LL_VECTORIZE
inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
{
__m128 vw = _mm_set1_ps(w);
mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
}
inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
{
LLV4Vector3 j;
j.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
o.setVec(j.mV);
}
inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
{
o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
}
inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
{
o.v = _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX]); // ( ax * vx ) + ...
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Matrix3
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#else
inline void LLV4Matrix3::lerp(const LLV4Matrix3 &a, const LLV4Matrix3 &b, const F32 &w)
{
mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
}
inline void LLV4Matrix3::multiply(const LLVector3 &a, LLVector3& o) const
{
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
a.mV[VY] * mMatrix[VY][VX] +
a.mV[VZ] * mMatrix[VZ][VX],
a.mV[VX] * mMatrix[VX][VY] +
a.mV[VY] * mMatrix[VY][VY] +
a.mV[VZ] * mMatrix[VZ][VY],
a.mV[VX] * mMatrix[VX][VZ] +
a.mV[VY] * mMatrix[VY][VZ] +
a.mV[VZ] * mMatrix[VZ][VZ]);
}
inline void LLV4Matrix3::multiply(const LLVector4 &a, LLV4Vector3& o) const
{
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
a.mV[VY] * mMatrix[VY][VX] +
a.mV[VZ] * mMatrix[VZ][VX],
a.mV[VX] * mMatrix[VX][VY] +
a.mV[VY] * mMatrix[VY][VY] +
a.mV[VZ] * mMatrix[VZ][VY],
a.mV[VX] * mMatrix[VX][VZ] +
a.mV[VY] * mMatrix[VY][VZ] +
a.mV[VZ] * mMatrix[VZ][VZ]);
}
inline void LLV4Matrix3::multiply(const LLVector3 &a, LLV4Vector3& o) const
{
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
a.mV[VY] * mMatrix[VY][VX] +
a.mV[VZ] * mMatrix[VZ][VX],
a.mV[VX] * mMatrix[VX][VY] +
a.mV[VY] * mMatrix[VY][VY] +
a.mV[VZ] * mMatrix[VZ][VY],
a.mV[VX] * mMatrix[VX][VZ] +
a.mV[VY] * mMatrix[VY][VZ] +
a.mV[VZ] * mMatrix[VZ][VZ]);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Matrix3
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#endif
inline const LLV4Matrix3& LLV4Matrix3::transpose()
{
#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
_MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
return *this;
#else
F32 temp;
temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
#endif
return *this;
}
inline const LLV4Matrix3& LLV4Matrix3::operator=(const LLMatrix3& a)
{
memcpy(mMatrix[VX], a.mMatrix[VX], sizeof(F32) * 3 );
memcpy(mMatrix[VY], a.mMatrix[VY], sizeof(F32) * 3 );
memcpy(mMatrix[VZ], a.mMatrix[VZ], sizeof(F32) * 3 );
return *this;
}
inline LLVector3 operator*(const LLVector3& a, const LLV4Matrix3& b)
{
return LLVector3(
a.mV[VX] * b.mMatrix[VX][VX] +
a.mV[VY] * b.mMatrix[VY][VX] +
a.mV[VZ] * b.mMatrix[VZ][VX],
a.mV[VX] * b.mMatrix[VX][VY] +
a.mV[VY] * b.mMatrix[VY][VY] +
a.mV[VZ] * b.mMatrix[VZ][VY],
a.mV[VX] * b.mMatrix[VX][VZ] +
a.mV[VY] * b.mMatrix[VY][VZ] +
a.mV[VZ] * b.mMatrix[VZ][VZ] );
}
#endif

View File

@ -1,249 +0,0 @@
/**
* @file llviewerjointmesh.cpp
* @brief LLV4* class header file - vector processor enabled math
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLV4MATRIX4_H
#define LL_LLV4MATRIX4_H
#include "llv4math.h"
#include "llv4matrix3.h" // just for operator LLV4Matrix3()
#include "llv4vector3.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Matrix4
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
LL_LLV4MATH_ALIGN_PREFIX
class LLV4Matrix4
{
public:
union {
F32 mMatrix[LLV4_NUM_AXIS][LLV4_NUM_AXIS];
V4F32 mV[LLV4_NUM_AXIS];
};
void lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w);
void multiply(const LLVector3 &a, LLVector3& o) const;
void multiply(const LLVector3 &a, LLV4Vector3& o) const;
const LLV4Matrix4& transpose();
const LLV4Matrix4& translate(const LLVector3 &vec);
const LLV4Matrix4& translate(const LLV4Vector3 &vec);
const LLV4Matrix4& operator=(const LLMatrix4& a);
operator LLMatrix4() const { return *(reinterpret_cast<const LLMatrix4*>(const_cast<const F32*>(&mMatrix[0][0]))); }
operator LLV4Matrix3() const { return *(reinterpret_cast<const LLV4Matrix3*>(const_cast<const F32*>(&mMatrix[0][0]))); }
friend LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b);
}
LL_LLV4MATH_ALIGN_POSTFIX;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Matrix4 - SSE
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#if LL_VECTORIZE
inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
{
__m128 vw = _mm_set1_ps(w);
mV[VX] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VX], a.mV[VX]), vw), a.mV[VX]); // ( b - a ) * w + a
mV[VY] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VY], a.mV[VY]), vw), a.mV[VY]);
mV[VZ] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VZ], a.mV[VZ]), vw), a.mV[VZ]);
mV[VW] = _mm_add_ps(_mm_mul_ps(_mm_sub_ps(b.mV[VW], a.mV[VW]), vw), a.mV[VW]);
}
inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
{
LLV4Vector3 j;
j.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
j.v = _mm_add_ps(j.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
o.setVec(j.mV);
}
inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
{
o.v = _mm_add_ps(mV[VW], _mm_mul_ps(_mm_set1_ps(a.mV[VX]), mV[VX])); // ( ax * vx ) + vw
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VY]), mV[VY]));
o.v = _mm_add_ps(o.v , _mm_mul_ps(_mm_set1_ps(a.mV[VZ]), mV[VZ]));
}
inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
{
mV[VW] = _mm_add_ps(mV[VW], vec.v);
return (*this);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Matrix4
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#else
inline void LLV4Matrix4::lerp(const LLV4Matrix4 &a, const LLV4Matrix4 &b, const F32 &w)
{
mMatrix[VX][VX] = llv4lerp(a.mMatrix[VX][VX], b.mMatrix[VX][VX], w);
mMatrix[VX][VY] = llv4lerp(a.mMatrix[VX][VY], b.mMatrix[VX][VY], w);
mMatrix[VX][VZ] = llv4lerp(a.mMatrix[VX][VZ], b.mMatrix[VX][VZ], w);
mMatrix[VY][VX] = llv4lerp(a.mMatrix[VY][VX], b.mMatrix[VY][VX], w);
mMatrix[VY][VY] = llv4lerp(a.mMatrix[VY][VY], b.mMatrix[VY][VY], w);
mMatrix[VY][VZ] = llv4lerp(a.mMatrix[VY][VZ], b.mMatrix[VY][VZ], w);
mMatrix[VZ][VX] = llv4lerp(a.mMatrix[VZ][VX], b.mMatrix[VZ][VX], w);
mMatrix[VZ][VY] = llv4lerp(a.mMatrix[VZ][VY], b.mMatrix[VZ][VY], w);
mMatrix[VZ][VZ] = llv4lerp(a.mMatrix[VZ][VZ], b.mMatrix[VZ][VZ], w);
mMatrix[VW][VX] = llv4lerp(a.mMatrix[VW][VX], b.mMatrix[VW][VX], w);
mMatrix[VW][VY] = llv4lerp(a.mMatrix[VW][VY], b.mMatrix[VW][VY], w);
mMatrix[VW][VZ] = llv4lerp(a.mMatrix[VW][VZ], b.mMatrix[VW][VZ], w);
}
inline void LLV4Matrix4::multiply(const LLVector3 &a, LLVector3& o) const
{
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
a.mV[VY] * mMatrix[VY][VX] +
a.mV[VZ] * mMatrix[VZ][VX] +
mMatrix[VW][VX],
a.mV[VX] * mMatrix[VX][VY] +
a.mV[VY] * mMatrix[VY][VY] +
a.mV[VZ] * mMatrix[VZ][VY] +
mMatrix[VW][VY],
a.mV[VX] * mMatrix[VX][VZ] +
a.mV[VY] * mMatrix[VY][VZ] +
a.mV[VZ] * mMatrix[VZ][VZ] +
mMatrix[VW][VZ]);
}
inline void LLV4Matrix4::multiply(const LLVector3 &a, LLV4Vector3& o) const
{
o.setVec( a.mV[VX] * mMatrix[VX][VX] +
a.mV[VY] * mMatrix[VY][VX] +
a.mV[VZ] * mMatrix[VZ][VX] +
mMatrix[VW][VX],
a.mV[VX] * mMatrix[VX][VY] +
a.mV[VY] * mMatrix[VY][VY] +
a.mV[VZ] * mMatrix[VZ][VY] +
mMatrix[VW][VY],
a.mV[VX] * mMatrix[VX][VZ] +
a.mV[VY] * mMatrix[VY][VZ] +
a.mV[VZ] * mMatrix[VZ][VZ] +
mMatrix[VW][VZ]);
}
inline const LLV4Matrix4& LLV4Matrix4::translate(const LLV4Vector3 &vec)
{
mMatrix[3][0] += vec.mV[0];
mMatrix[3][1] += vec.mV[1];
mMatrix[3][2] += vec.mV[2];
return (*this);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Matrix4
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#endif
inline const LLV4Matrix4& LLV4Matrix4::operator=(const LLMatrix4& a)
{
memcpy(mMatrix, a.mMatrix, sizeof(F32) * 16 );
return *this;
}
inline const LLV4Matrix4& LLV4Matrix4::transpose()
{
#if LL_VECTORIZE && defined(_MM_TRANSPOSE4_PS)
_MM_TRANSPOSE4_PS(mV[VX], mV[VY], mV[VZ], mV[VW]);
#else
LLV4Matrix4 mat;
mat.mMatrix[0][0] = mMatrix[0][0];
mat.mMatrix[1][0] = mMatrix[0][1];
mat.mMatrix[2][0] = mMatrix[0][2];
mat.mMatrix[3][0] = mMatrix[0][3];
mat.mMatrix[0][1] = mMatrix[1][0];
mat.mMatrix[1][1] = mMatrix[1][1];
mat.mMatrix[2][1] = mMatrix[1][2];
mat.mMatrix[3][1] = mMatrix[1][3];
mat.mMatrix[0][2] = mMatrix[2][0];
mat.mMatrix[1][2] = mMatrix[2][1];
mat.mMatrix[2][2] = mMatrix[2][2];
mat.mMatrix[3][2] = mMatrix[2][3];
mat.mMatrix[0][3] = mMatrix[3][0];
mat.mMatrix[1][3] = mMatrix[3][1];
mat.mMatrix[2][3] = mMatrix[3][2];
mat.mMatrix[3][3] = mMatrix[3][3];
*this = mat;
#endif
return *this;
}
inline const LLV4Matrix4& LLV4Matrix4::translate(const LLVector3 &vec)
{
mMatrix[3][0] += vec.mV[0];
mMatrix[3][1] += vec.mV[1];
mMatrix[3][2] += vec.mV[2];
return (*this);
}
inline LLVector3 operator*(const LLVector3 &a, const LLV4Matrix4 &b)
{
return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] +
a.mV[VY] * b.mMatrix[VY][VX] +
a.mV[VZ] * b.mMatrix[VZ][VX] +
b.mMatrix[VW][VX],
a.mV[VX] * b.mMatrix[VX][VY] +
a.mV[VY] * b.mMatrix[VY][VY] +
a.mV[VZ] * b.mMatrix[VZ][VY] +
b.mMatrix[VW][VY],
a.mV[VX] * b.mMatrix[VX][VZ] +
a.mV[VY] * b.mMatrix[VY][VZ] +
a.mV[VZ] * b.mMatrix[VZ][VZ] +
b.mMatrix[VW][VZ]);
}
#endif

View File

@ -1,80 +0,0 @@
/**
* @file llviewerjointmesh.cpp
* @brief LLV4* class header file - vector processor enabled math
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLV4VECTOR3_H
#define LL_LLV4VECTOR3_H
#include "llv4math.h"
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Vector3
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
LL_LLV4MATH_ALIGN_PREFIX
class LLV4Vector3
{
public:
union {
F32 mV[LLV4_NUM_AXIS];
V4F32 v;
};
enum {
ALIGNMENT = 16
};
void setVec(F32 x, F32 y, F32 z);
void setVec(F32 a);
}
LL_LLV4MATH_ALIGN_POSTFIX;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLV4Vector3
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline void LLV4Vector3::setVec(F32 x, F32 y, F32 z)
{
mV[VX] = x;
mV[VY] = y;
mV[VZ] = z;
}
inline void LLV4Vector3::setVec(F32 a)
{
#if LL_VECTORIZE
v = _mm_set1_ps(a);
#else
setVec(a, a, a);
#endif
}
#endif

View File

@ -4313,15 +4313,25 @@ S32 LLVolume::getNumTriangleIndices() const
}
S32 LLVolume::getNumTriangles() const
S32 LLVolume::getNumTriangles(S32* vcount) const
{
U32 triangle_count = 0;
U32 vertex_count = 0;
for (S32 i = 0; i < getNumVolumeFaces(); ++i)
{
triangle_count += getVolumeFace(i).mNumIndices/3;
const LLVolumeFace& face = getVolumeFace(i);
triangle_count += face.mNumIndices/3;
vertex_count += face.mNumVertices;
}
if (vcount)
{
*vcount = vertex_count;
}
return triangle_count;
}

View File

@ -993,7 +993,7 @@ public:
S32 getNumTriangleIndices() const;
static void getLoDTriangleCounts(const LLVolumeParams& params, S32* counts);
S32 getNumTriangles() const;
S32 getNumTriangles(S32* vcount = NULL) const;
void generateSilhouetteVertices(std::vector<LLVector3> &vertices,
std::vector<LLVector3> &normals,

View File

@ -592,7 +592,6 @@ void LLCurl::Multi::cleanup()
{
return ; //nothing to clean.
}
// Clean up active
for(easy_active_list_t::iterator iter = mEasyActiveList.begin();
iter != mEasyActiveList.end(); ++iter)

View File

@ -291,9 +291,10 @@ S32 getElementSize(const LLSD& llsd)
case LLSD::TypeMap:
case LLSD::TypeArray:
case LLSD::TypeUndefined:
default: // TypeLLSDTypeEnd, TypeLLSDNumTypes, etc.
return 0;
}
return 0;
//return 0;
}
//virtual

View File

@ -1239,6 +1239,14 @@ void LLPluginClassMedia::focus(bool focused)
sendMessage(message);
}
void LLPluginClassMedia::set_page_zoom_factor( double factor )
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_page_zoom_factor");
message.setValueReal("factor", factor);
sendMessage(message);
}
void LLPluginClassMedia::clear_cache()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cache");

View File

@ -41,7 +41,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
LOG_CLASS(LLPluginClassMedia);
public:
LLPluginClassMedia(LLPluginClassMediaOwner *owner);
~LLPluginClassMedia();
virtual ~LLPluginClassMedia();
// local initialization, called by the media manager when creating a source
bool init(const std::string &launcher_filename,
@ -202,6 +202,7 @@ public:
bool pluginSupportsMediaBrowser(void);
void focus(bool focused);
void set_page_zoom_factor( double factor );
void clear_cache();
void clear_cookies();
void set_cookies(const std::string &cookies);

View File

@ -39,7 +39,7 @@
class LLPluginInstanceMessageListener
{
public:
~LLPluginInstanceMessageListener();
virtual ~LLPluginInstanceMessageListener();
/** Plugin receives message from plugin loader shell. */
virtual void receivePluginMessage(const std::string &message) = 0;
};

View File

@ -94,10 +94,10 @@ void LLPluginMessagePipeOwner::killMessagePipe(void)
LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket):
mInputMutex(gAPRPoolp),
mOutputMutex(gAPRPoolp),
mOutputStartIndex(0),
mOwner(owner),
mSocket(socket)
{
mOwner->setMessagePipe(this);
}
@ -113,6 +113,14 @@ bool LLPluginMessagePipe::addMessage(const std::string &message)
{
// queue the message for later output
LLMutexLock lock(&mOutputMutex);
// If we're starting to use up too much memory, clear
if (mOutputStartIndex > 1024 * 1024)
{
mOutput = mOutput.substr(mOutputStartIndex);
mOutputStartIndex = 0;
}
mOutput += message;
mOutput += MESSAGE_DELIMITER; // message separator
@ -165,35 +173,44 @@ bool LLPluginMessagePipe::pumpOutput()
if(mSocket)
{
apr_status_t status;
apr_size_t size;
apr_size_t in_size, out_size;
LLMutexLock lock(&mOutputMutex);
if(!mOutput.empty())
const char * output_data = &(mOutput.data()[mOutputStartIndex]);
if(*output_data != '\0')
{
// write any outgoing messages
size = (apr_size_t)mOutput.size();
in_size = (apr_size_t) (mOutput.size() - mOutputStartIndex);
out_size = in_size;
setSocketTimeout(0);
// LL_INFOS("Plugin") << "before apr_socket_send, size = " << size << LL_ENDL;
status = apr_socket_send(
mSocket->getSocket(),
(const char*)mOutput.data(),
&size);
status = apr_socket_send(mSocket->getSocket(),
output_data,
&out_size);
// LL_INFOS("Plugin") << "after apr_socket_send, size = " << size << LL_ENDL;
if(status == APR_SUCCESS)
if((status == APR_SUCCESS) || APR_STATUS_IS_EAGAIN(status))
{
// success
mOutput = mOutput.substr(size);
}
else if(APR_STATUS_IS_EAGAIN(status))
{
// Socket buffer is full...
// remove the written part from the buffer and try again later.
mOutput = mOutput.substr(size);
// Success or Socket buffer is full...
// If we've pumped the entire string, clear it
if (out_size == in_size)
{
mOutputStartIndex = 0;
mOutput.clear();
}
else
{
llassert(in_size > out_size);
// Remove the written part from the buffer and try again later.
mOutputStartIndex += out_size;
}
}
else if(APR_STATUS_IS_EOF(status))
{

View File

@ -40,7 +40,7 @@ class LLPluginMessagePipeOwner
LOG_CLASS(LLPluginMessagePipeOwner);
public:
LLPluginMessagePipeOwner();
~LLPluginMessagePipeOwner();
virtual ~LLPluginMessagePipeOwner();
// called with incoming messages
virtual void receiveMessageRaw(const std::string &message) = 0;
@ -86,6 +86,7 @@ protected:
std::string mInput;
LLMutex mOutputMutex;
std::string mOutput;
std::string::size_type mOutputStartIndex;
LLPluginMessagePipeOwner *mOwner;
LLSocket::ptr_t mSocket;

View File

@ -41,7 +41,7 @@
class LLPluginProcessParentOwner
{
public:
~LLPluginProcessParentOwner();
virtual ~LLPluginProcessParentOwner();
virtual void receivePluginMessage(const LLPluginMessage &message) = 0;
virtual bool receivePluginMessageEarly(const LLPluginMessage &message) {return false;};
// This will only be called when the plugin has died unexpectedly

View File

@ -31,11 +31,18 @@
#include "llconvexdecomposition.h"
#include "llsdserialize.h"
#include "llvector4a.h"
#if LL_MSVC
#pragma warning (disable : 4263)
#pragma warning (disable : 4264)
#endif
#include "dae.h"
#include "dae/daeErrorHandler.h"
#include "dom/domConstants.h"
#include "dom/domMesh.h"
#if LL_MSVC
#pragma warning (default : 4263)
#pragma warning (default : 4264)
#endif
#ifdef LL_STANDALONE
# include <zlib.h>

View File

@ -36,6 +36,7 @@
#include "m4math.h"
#include "llrender.h"
#include "llglslshader.h"
#include "llglheaders.h"
@ -195,7 +196,7 @@ void LLCubeMap::enableTexture(S32 stage)
void LLCubeMap::enableTextureCoords(S32 stage)
{
mTextureCoordStage = stage;
if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps)
{
if (stage > 0)
{
@ -237,7 +238,7 @@ void LLCubeMap::disableTexture(void)
void LLCubeMap::disableTextureCoords(void)
{
if (gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
if (!LLGLSLShader::sNoFixedFunction && gGLManager.mHasCubeMap && mTextureCoordStage >= 0 && LLCubeMap::sUseCubeMaps)
{
if (mTextureCoordStage > 0)
{
@ -264,19 +265,19 @@ void LLCubeMap::setMatrix(S32 stage)
gGL.getTexUnit(stage)->activate();
}
LLVector3 x(LLVector3d(gGLModelView+0));
LLVector3 y(LLVector3d(gGLModelView+4));
LLVector3 z(LLVector3d(gGLModelView+8));
LLVector3 x(gGLModelView+0);
LLVector3 y(gGLModelView+4);
LLVector3 z(gGLModelView+8);
LLMatrix3 mat3;
mat3.setRows(x,y,z);
LLMatrix4 trans(mat3);
trans.transpose();
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadMatrixf((F32 *)trans.mMatrix);
glMatrixMode(GL_MODELVIEW);
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.pushMatrix();
gGL.loadMatrix((F32 *)trans.mMatrix);
gGL.matrixMode(LLRender::MM_MODELVIEW);
/*if (stage > 0)
{
@ -292,9 +293,9 @@ void LLCubeMap::restoreMatrix()
{
gGL.getTexUnit(mMatrixStage)->activate();
}
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
/*if (mMatrixStage > 0)
{

View File

@ -55,7 +55,10 @@ FT_Library gFTLibrary = NULL;
//static
void LLFontManager::initClass()
{
gFontManagerp = new LLFontManager;
if (!gFontManagerp)
{
gFontManagerp = new LLFontManager;
}
}
//static
@ -136,7 +139,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
FT_Done_Face(mFTFace);
mFTFace = NULL;
}
int error;
error = FT_New_Face( gFTLibrary,

View File

@ -67,6 +67,36 @@ static const std::string HEADLESS_VERSION_STRING("1.0");
std::ofstream gFailLog;
#if GL_ARB_debug_output
#ifndef APIENTRY
#define APIENTRY
#endif
void APIENTRY gl_debug_callback(GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
GLvoid* userParam)
{
if (severity == GL_DEBUG_SEVERITY_HIGH_ARB)
{
llwarns << "----- GL ERROR --------" << llendl;
}
else
{
llwarns << "----- GL WARNING -------" << llendl;
}
llwarns << "Type: " << std::hex << type << llendl;
llwarns << "ID: " << std::hex << id << llendl;
llwarns << "Severity: " << std::hex << severity << llendl;
llwarns << "Message: " << message << llendl;
llwarns << "-----------------------" << llendl;
}
#endif
void ll_init_fail_log(std::string filename)
{
gFailLog.open(filename.c_str());
@ -110,6 +140,11 @@ std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
// ATI prototypes
#if LL_WINDOWS
PFNGLGETSTRINGIPROC glGetStringi = NULL;
#endif
// vertex blending prototypes
PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB = NULL;
PFNGLVERTEXBLENDARBPROC glVertexBlendARB = NULL;
@ -128,6 +163,12 @@ PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB = NULL;
PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB = NULL;
PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB = NULL;
//GL_ARB_vertex_array_object
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
PFNGLISVERTEXARRAYPROC glIsVertexArray = NULL;
// GL_ARB_map_buffer_range
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = NULL;
PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange = NULL;
@ -197,10 +238,16 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample = NULL;
PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = NULL;
//GL_ARB_texture_multisample
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample;
PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
PFNGLSAMPLEMASKIPROC glSampleMaski;
PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample = NULL;
PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample = NULL;
PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv = NULL;
PFNGLSAMPLEMASKIPROC glSampleMaski = NULL;
//GL_ARB_debug_output
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB = NULL;
PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB = NULL;
// GL_EXT_blend_func_separate
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
@ -249,6 +296,10 @@ PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB = NULL;
PFNGLGETUNIFORMIVARBPROC glGetUniformivARB = NULL;
PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB = NULL;
#if LL_WINDOWS
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
#endif
// vertex shader prototypes
#if LL_LINUX || LL_SOLARIS
PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
@ -349,6 +400,7 @@ LLGLManager::LLGLManager() :
mHasBlendFuncSeparate(FALSE),
mHasSync(FALSE),
mHasVertexBufferObject(FALSE),
mHasVertexArrayObject(FALSE),
mHasMapBufferRange(FALSE),
mHasFlushBufferRange(FALSE),
mHasPBuffer(FALSE),
@ -370,6 +422,7 @@ LLGLManager::LLGLManager() :
mHasAnisotropic(FALSE),
mHasARBEnvCombine(FALSE),
mHasCubeMap(FALSE),
mHasDebugOutput(FALSE),
mIsATI(FALSE),
mIsNVIDIA(FALSE),
@ -409,6 +462,15 @@ void LLGLManager::initWGL()
LL_WARNS("RenderInit") << "No ARB pixel format extensions" << LL_ENDL;
}
if (ExtensionExists("WGL_ARB_create_context",gGLHExts.mSysExts))
{
GLH_EXT_NAME(wglCreateContextAttribsARB) = (PFNWGLCREATECONTEXTATTRIBSARBPROC)GLH_EXT_GET_PROC_ADDRESS("wglCreateContextAttribsARB");
}
else
{
LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
}
if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
{
GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
@ -438,13 +500,45 @@ bool LLGLManager::initGL()
LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
}
GLint alpha_bits;
glGetIntegerv( GL_ALPHA_BITS, &alpha_bits );
if( 8 != alpha_bits )
stop_glerror();
#if LL_WINDOWS
if (!glGetStringi)
{
LL_WARNS("RenderInit") << "Frame buffer has less than 8 bits of alpha. Avatar texture compositing will fail." << LL_ENDL;
glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi");
}
//reload extensions string (may have changed after using wglCreateContextAttrib)
if (glGetStringi)
{
std::stringstream str;
GLint count = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (GLint i = 0; i < count; ++i)
{
std::string ext((const char*) glGetStringi(GL_EXTENSIONS, i));
str << ext << " ";
LL_DEBUGS("GLExtensions") << ext << llendl;
}
{
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
if(wglGetExtensionsStringARB)
{
str << (const char*) wglGetExtensionsStringARB(wglGetCurrentDC());
}
}
free(gGLHExts.mSysExts);
std::string extensions = str.str();
gGLHExts.mSysExts = strdup(extensions.c_str());
}
#endif
stop_glerror();
// Extract video card strings and convert to upper case to
// work around driver-to-driver variation in capitalization.
mGLVendor = std::string((const char *)glGetString(GL_VENDOR));
@ -459,7 +553,7 @@ bool LLGLManager::initGL()
&mDriverVersionVendorString );
mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
// Trailing space necessary to keep "nVidia Corpor_ati_on" cards
// from being recognized as ATI.
if (mGLVendor.substr(0,4) == "ATI ")
@ -531,8 +625,12 @@ bool LLGLManager::initGL()
mGLVendorShort = "MISC";
}
stop_glerror();
// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
initExtensions();
stop_glerror();
S32 old_vram = mVRAM;
if (mHasATIMemInfo)
{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
@ -548,7 +646,27 @@ bool LLGLManager::initGL()
mVRAM = dedicated_memory/1024;
}
if (mHasMultitexture)
if (mVRAM < 256)
{ //something likely went wrong using the above extensions, fall back to old method
mVRAM = old_vram;
}
stop_glerror();
stop_glerror();
if (mHasFragmentShader)
{
GLint num_tex_image_units;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
mNumTextureImageUnits = llmin(num_tex_image_units, 32);
}
if (LLRender::sGLCoreProfile)
{
mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS);
}
else if (mHasMultitexture)
{
GLint num_tex_units;
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units);
@ -567,12 +685,7 @@ bool LLGLManager::initGL()
return false;
}
if (mHasFragmentShader)
{
GLint num_tex_image_units;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
mNumTextureImageUnits = llmin(num_tex_image_units, 32);
}
stop_glerror();
if (mHasTextureMultisample)
{
@ -582,6 +695,21 @@ bool LLGLManager::initGL()
glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords);
}
stop_glerror();
#if LL_WINDOWS
if (mHasDebugOutput && gDebugGL)
{ //setup debug output callback
//glDebugMessageControlARB(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW_ARB, 0, NULL, GL_TRUE);
glDebugMessageCallbackARB((GLDEBUGPROCARB) gl_debug_callback, NULL);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
}
#endif
stop_glerror();
//HACK always disable texture multisample, use FXAA instead
mHasTextureMultisample = FALSE;
#if LL_WINDOWS
if (mIsATI)
{ //using multisample textures on ATI results in black screen for some reason
@ -593,10 +721,17 @@ bool LLGLManager::initGL()
{
glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples);
}
stop_glerror();
setToDebugGPU();
stop_glerror();
initGLStates();
stop_glerror();
return true;
}
@ -700,14 +835,6 @@ std::string LLGLManager::getRawGLString()
return gl_string;
}
U32 LLGLManager::getNumFBOFSAASamples(U32 samples)
{
samples = llmin(samples, (U32) mMaxColorTextureSamples);
samples = llmin(samples, (U32) mMaxDepthTextureSamples);
samples = llmin(samples, (U32) 4);
return samples;
}
void LLGLManager::shutdownGL()
{
if (mInited)
@ -774,7 +901,7 @@ void LLGLManager::initExtensions()
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
mHasTextureRectangle = FALSE;
#else // LL_MESA_HEADLESS
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
@ -788,6 +915,7 @@ void LLGLManager::initExtensions()
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
mHasVertexArrayObject = ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts);
mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
@ -806,13 +934,14 @@ void LLGLManager::initExtensions()
mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
mHasTextureMultisample = ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts);
mHasDebugOutput = ExtensionExists("GL_ARB_debug_output", gGLHExts.mSysExts);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
#endif
mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
mHasShaderObjects = ExtensionExists("GL_ARB_shader_objects", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
mHasVertexShader = ExtensionExists("GL_ARB_vertex_program", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_vertex_shader", gGLHExts.mSysExts)
&& ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts);
&& (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
#endif
#if LL_LINUX || LL_SOLARIS
@ -985,6 +1114,13 @@ void LLGLManager::initExtensions()
mHasVertexBufferObject = FALSE;
}
}
if (mHasVertexArrayObject)
{
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glBindVertexArray");
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glDeleteVertexArrays");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) GLH_EXT_GET_PROC_ADDRESS("glGenVertexArrays");
glIsVertexArray = (PFNGLISVERTEXARRAYPROC) GLH_EXT_GET_PROC_ADDRESS("glIsVertexArray");
}
if (mHasSync)
{
glFenceSync = (PFNGLFENCESYNCPROC) GLH_EXT_GET_PROC_ADDRESS("glFenceSync");
@ -1039,6 +1175,13 @@ void LLGLManager::initExtensions()
glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) GLH_EXT_GET_PROC_ADDRESS("glGetMultisamplefv");
glSampleMaski = (PFNGLSAMPLEMASKIPROC) GLH_EXT_GET_PROC_ADDRESS("glSampleMaski");
}
if (mHasDebugOutput)
{
glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageInsertARB");
glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallbackARB");
glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLogARB");
}
#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
@ -1193,7 +1336,7 @@ void rotate_quat(LLQuaternion& rotation)
{
F32 angle_radians, x, y, z;
rotation.getAngleAxis(&angle_radians, &x, &y, &z);
glRotatef(angle_radians * RAD_TO_DEG, x, y, z);
gGL.rotatef(angle_radians * RAD_TO_DEG, x, y, z);
}
void flush_glerror()
@ -1230,10 +1373,6 @@ void log_glerror()
void do_assert_glerror()
{
if (LL_UNLIKELY(!gGLManager.mInited))
{
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
}
// Create or update texture to be used with this data
GLenum error;
error = glGetError();
@ -1326,11 +1465,6 @@ void LLGLState::initClass()
//make sure multisample defaults to disabled
sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
glDisable(GL_MULTISAMPLE_ARB);
sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
glDisable(GL_MULTISAMPLE_ARB);
glEnableClientState(GL_VERTEX_ARRAY);
}
//static
@ -1604,7 +1738,7 @@ void LLGLState::checkTextureChannels(const std::string& msg)
void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
{
if (!gDebugGL)
if (!gDebugGL || LLGLSLShader::sNoFixedFunction)
{
return;
}
@ -1625,7 +1759,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
error = TRUE;
}
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
/*glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &active_texture);
if (active_texture != GL_TEXTURE0_ARB)
{
llwarns << "Active texture corrupted: " << active_texture << llendl;
@ -1634,7 +1768,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
gFailLog << "Active texture corrupted: " << active_texture << std::endl;
}
error = TRUE;
}
}*/
static const char* label[] =
{
@ -1661,7 +1795,7 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
};
for (S32 j = 0; j < 4; j++)
for (S32 j = 1; j < 4; j++)
{
if (glIsEnabled(value[j]))
{
@ -1783,17 +1917,26 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
mState(state), mWasEnabled(FALSE), mIsEnabled(FALSE)
{
if (LLGLSLShader::sNoFixedFunction)
{ //always disable state that's deprecated post GL 3.0
{ //always ignore state that's deprecated post GL 3.0
switch (state)
{
case GL_ALPHA_TEST:
enabled = 0;
case GL_NORMALIZE:
case GL_TEXTURE_GEN_R:
case GL_TEXTURE_GEN_S:
case GL_TEXTURE_GEN_T:
case GL_TEXTURE_GEN_Q:
case GL_LIGHTING:
case GL_COLOR_MATERIAL:
case GL_FOG:
case GL_LINE_STIPPLE:
mState = 0;
break;
}
}
stop_glerror();
if (state)
if (mState)
{
mWasEnabled = sStateMap[state];
llassert(mWasEnabled == glIsEnabled(state));
@ -1875,79 +2018,6 @@ void LLGLManager::initGLStates()
////////////////////////////////////////////////////////////////////////////////
void enable_vertex_weighting(const S32 index)
{
#if GL_ARB_vertex_program
if (index > 0) glEnableVertexAttribArrayARB(index); // vertex weights
#endif
}
void disable_vertex_weighting(const S32 index)
{
#if GL_ARB_vertex_program
if (index > 0) glDisableVertexAttribArrayARB(index); // vertex weights
#endif
}
void enable_binormals(const S32 index)
{
#if GL_ARB_vertex_program
if (index > 0)
{
glEnableVertexAttribArrayARB(index); // binormals
}
#endif
}
void disable_binormals(const S32 index)
{
#if GL_ARB_vertex_program
if (index > 0)
{
glDisableVertexAttribArrayARB(index); // binormals
}
#endif
}
void enable_cloth_weights(const S32 index)
{
#if GL_ARB_vertex_program
if (index > 0) glEnableVertexAttribArrayARB(index);
#endif
}
void disable_cloth_weights(const S32 index)
{
#if GL_ARB_vertex_program
if (index > 0) glDisableVertexAttribArrayARB(index);
#endif
}
void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights)
{
#if GL_ARB_vertex_program
if (index > 0) glVertexAttribPointerARB(index, 1, GL_FLOAT, FALSE, stride, weights);
stop_glerror();
#endif
}
void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights)
{
#if GL_ARB_vertex_program
if (index > 0) glVertexAttribPointerARB(index, 4, GL_FLOAT, TRUE, stride, weights);
stop_glerror();
#endif
}
void set_binormals(const S32 index, const U32 stride,const LLVector3 *binormals)
{
#if GL_ARB_vertex_program
if (index > 0) glVertexAttribPointerARB(index, 3, GL_FLOAT, FALSE, stride, binormals);
stop_glerror();
#endif
}
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific )
{
// GL_VERSION returns a null-terminated string with the format:
@ -2060,20 +2130,20 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
glh::matrix4f suffix;
suffix.set_row(2, cplane);
glh::matrix4f newP = suffix * P;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrixf(newP.m);
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadMatrix(newP.m);
gGLObliqueProjectionInverse = LLMatrix4(newP.inverse().transpose().m);
glMatrixMode(GL_MODELVIEW);
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
LLGLUserClipPlane::~LLGLUserClipPlane()
{
if (mApply)
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}
@ -2263,16 +2333,16 @@ LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer)
P.element(2, i) = P.element(3, i) * depth;
}
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrixf(P.m);
glMatrixMode(GL_MODELVIEW);
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadMatrix(P.m);
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
LLGLSquashToFarClip::~LLGLSquashToFarClip()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}

View File

@ -88,6 +88,7 @@ public:
// ARB Extensions
BOOL mHasVertexBufferObject;
BOOL mHasVertexArrayObject;
BOOL mHasSync;
BOOL mHasMapBufferRange;
BOOL mHasFlushBufferRange;
@ -112,6 +113,7 @@ public:
BOOL mHasAnisotropic;
BOOL mHasARBEnvCombine;
BOOL mHasCubeMap;
BOOL mHasDebugOutput;
// Vendor-specific extensions
BOOL mIsATI;
@ -148,7 +150,6 @@ public:
void printGLInfoString();
void getGLInfo(LLSD& info);
U32 getNumFBOFSAASamples(U32 desired_samples = 32);
// In ALL CAPS
std::string mGLVendor;
std::string mGLVendorShort;
@ -252,7 +253,7 @@ public:
static void dumpStates();
static void checkStates(const std::string& msg = "");
static void checkTextureChannels(const std::string& msg = "");
static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0x0001);
static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0);
protected:
static boost::unordered_map<LLGLenum, LLGLboolean> sStateMap;
@ -419,15 +420,7 @@ extern LLMatrix4 gGLObliqueProjectionInverse;
#include "llglstates.h"
void init_glstates();
void enable_vertex_weighting(const S32 index);
void disable_vertex_weighting(const S32 index);
void enable_binormals(const S32 index);
void disable_binormals(const S32 index);
void enable_cloth_weights(const S32 index);
void disable_cloth_weights(const S32 index);
void set_vertex_weights(const S32 index, const U32 stride, const F32 *weights);
void set_vertex_clothing_weights(const S32 index, const U32 stride, const LLVector4 *weights);
void set_binormals(const S32 index, const U32 stride, const LLVector3 *binormals);
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific );
extern BOOL gClothRipple;

View File

@ -68,6 +68,12 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
// GL_ARB_vertex_array_object
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
// GL_ARB_sync
extern PFNGLFENCESYNCPROC glFenceSync;
extern PFNGLISSYNCPROC glIsSync;
@ -310,6 +316,12 @@ extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB;
extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements;
#endif // LL_LINUX_NV_GL_HEADERS
// GL_ARB_vertex_array_object
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
// GL_ARB_vertex_buffer_object
extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
extern PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB;
@ -531,6 +543,9 @@ extern PFNGLSAMPLEMASKIPROC glSampleMaski;
#include "GL/glext.h"
#include "GL/glh_extensions.h"
// WGL_ARB_create_context
extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
extern PFNGLGETSTRINGIPROC glGetStringi;
// GL_ARB_vertex_buffer_object
extern PFNGLBINDBUFFERARBPROC glBindBufferARB;
@ -545,6 +560,12 @@ extern PFNGLUNMAPBUFFERARBPROC glUnmapBufferARB;
extern PFNGLGETBUFFERPARAMETERIVARBPROC glGetBufferParameterivARB;
extern PFNGLGETBUFFERPOINTERVARBPROC glGetBufferPointervARB;
// GL_ARB_vertex_array_object
extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
// GL_ARB_sync
extern PFNGLFENCESYNCPROC glFenceSync;
extern PFNGLISSYNCPROC glIsSync;
@ -735,6 +756,12 @@ extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample;
extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv;
extern PFNGLSAMPLEMASKIPROC glSampleMaski;
//GL_ARB_debug_output
extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB;
extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB;
#elif LL_DARWIN
//----------------------------------------------------------------------------
// LL_DARWIN
@ -899,6 +926,31 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
#endif /* GL_GLEXT_FUNCTION_POINTERS */
#endif
#ifndef GL_ARB_texture_rg
#define GL_RG 0x8227
#define GL_RG_INTEGER 0x8228
#define GL_R8 0x8229
#define GL_R16 0x822A
#define GL_RG8 0x822B
#define GL_RG16 0x822C
#define GL_R16F 0x822D
#define GL_R32F 0x822E
#define GL_RG16F 0x822F
#define GL_RG32F 0x8230
#define GL_R8I 0x8231
#define GL_R8UI 0x8232
#define GL_R16I 0x8233
#define GL_R16UI 0x8234
#define GL_R32I 0x8235
#define GL_R32UI 0x8236
#define GL_RG8I 0x8237
#define GL_RG8UI 0x8238
#define GL_RG16I 0x8239
#define GL_RG16UI 0x823A
#define GL_RG32I 0x823B
#define GL_RG32UI 0x823C
#endif
// May be needed for DARWIN...
// #ifndef GL_ARB_compressed_tex_image
// #define GL_ARB_compressed_tex_image 1

View File

@ -31,6 +31,7 @@
#include "llshadermgr.h"
#include "llfile.h"
#include "llrender.h"
#include "llvertexbuffer.h"
#if LL_DARWIN
#include "OpenGL/OpenGL.h"
@ -50,6 +51,7 @@ using std::string;
GLhandleARB LLGLSLShader::sCurBoundShader = 0;
LLGLSLShader* LLGLSLShader::sCurBoundShaderPtr = NULL;
S32 LLGLSLShader::sIndexedTextureChannels = 0;
bool LLGLSLShader::sNoFixedFunction = false;
//UI shader -- declared here so llui_libtest will link properly
@ -75,6 +77,7 @@ hasAlphaMask(false)
LLGLSLShader::LLGLSLShader()
: mProgramObject(0), mActiveTextureChannels(0), mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE)
{
}
void LLGLSLShader::unload()
@ -110,17 +113,19 @@ void LLGLSLShader::unload()
BOOL LLGLSLShader::createShader(vector<string> * attributes,
vector<string> * uniforms)
{
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
{
mMatHash[i] = 0xFFFFFFFF;
}
mLightHash = 0xFFFFFFFF;
llassert_always(!mShaderFiles.empty());
BOOL success = TRUE;
// Create program
mProgramObject = glCreateProgramObjectARB();
if (gGLManager.mGLVersion < 3.1f)
{ //force indexed texture channels to 1 if GL version is old (performance improvement for drivers with poor branching shader model support)
mFeatures.mIndexedTextureChannels = llmin(mFeatures.mIndexedTextureChannels, 1);
}
//compile new source
vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
for ( ; fileIter != mShaderFiles.end(); fileIter++ )
@ -235,6 +240,13 @@ void LLGLSLShader::attachObjects(GLhandleARB* objects, S32 count)
BOOL LLGLSLShader::mapAttributes(const vector<string> * attributes)
{
//before linking, make sure reserved attributes always have consistent locations
for (U32 i = 0; i < LLShaderMgr::instance()->mReservedAttribs.size(); i++)
{
const char* name = LLShaderMgr::instance()->mReservedAttribs[i].c_str();
glBindAttribLocationARB(mProgramObject, i, (const GLcharARB *) name);
}
//link the program
BOOL res = link();
@ -308,7 +320,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
for (S32 i = 0; i < (S32) LLShaderMgr::instance()->mReservedUniforms.size(); i++)
{
if ( (mUniform[i] == -1)
&& (LLShaderMgr::instance()->mReservedUniforms[i].compare(0, length, name, LLShaderMgr::instance()->mReservedUniforms[i].length()) == 0))
&& (LLShaderMgr::instance()->mReservedUniforms[i] == name))
{
//found it
mUniform[i] = location;
@ -322,7 +334,7 @@ void LLGLSLShader::mapUniform(GLint index, const vector<string> * uniforms)
for (U32 i = 0; i < uniforms->size(); i++)
{
if ( (mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] == -1)
&& ((*uniforms)[i].compare(0, length, name, (*uniforms)[i].length()) == 0))
&& ((*uniforms)[i] == name))
{
//found it
mUniform[i+LLShaderMgr::instance()->mReservedUniforms.size()] = location;
@ -386,6 +398,7 @@ void LLGLSLShader::bind()
gGL.flush();
if (gGLManager.mHasShaderObjects)
{
LLVertexBuffer::unbind();
glUseProgramObjectARB(mProgramObject);
sCurBoundShader = mProgramObject;
sCurBoundShaderPtr = this;
@ -411,6 +424,7 @@ void LLGLSLShader::unbind()
stop_glerror();
}
}
LLVertexBuffer::unbind();
glUseProgramObjectARB(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
@ -420,9 +434,13 @@ void LLGLSLShader::unbind()
void LLGLSLShader::bindNoShader(void)
{
glUseProgramObjectARB(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
LLVertexBuffer::unbind();
if (gGLManager.mHasShaderObjects)
{
glUseProgramObjectARB(0);
sCurBoundShader = 0;
sCurBoundShaderPtr = NULL;
}
}
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
@ -768,13 +786,17 @@ GLint LLGLSLShader::getUniformLocation(const string& uniform)
}
}
/*if (gDebugGL)
return ret;
}
GLint LLGLSLShader::getUniformLocation(U32 index)
{
GLint ret = -1;
if (mProgramObject > 0)
{
if (ret == -1 && ret != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
{
llerrs << "Uniform map invalid." << llendl;
}
}*/
llassert(index < mUniform.size());
return mUniform[index];
}
return ret;
}
@ -930,7 +952,9 @@ void LLGLSLShader::uniform4fv(const string& uniform, U32 count, const GLfloat* v
std::map<GLint, LLVector4>::iterator iter = mValue.find(location);
if (iter == mValue.end() || shouldChange(iter->second,vec) || count != 1)
{
stop_glerror();
glUniform4fvARB(location, count, v);
stop_glerror();
mValue[location] = vec;
}
}
@ -985,8 +1009,8 @@ void LLGLSLShader::vertexAttrib4fv(U32 index, GLfloat* v)
}
}
void LLGLSLShader::setAlphaRange(F32 minimum, F32 maximum)
void LLGLSLShader::setMinimumAlpha(F32 minimum)
{
uniform1f("minimum_alpha", minimum);
uniform1f("maximum_alpha", maximum);
gGL.flush();
uniform1f(LLShaderMgr::MINIMUM_ALPHA, minimum);
}

View File

@ -70,7 +70,7 @@ public:
static GLhandleARB sCurBoundShader;
static LLGLSLShader* sCurBoundShaderPtr;
static S32 sIndexedTextureChannels;
static bool sNoFixedFunction;
void unload();
@ -109,16 +109,17 @@ public:
void uniformMatrix3fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
void uniformMatrix4fv(const std::string& uniform, U32 count, GLboolean transpose, const GLfloat *v);
void setAlphaRange(F32 minimum, F32 maximum);
void setMinimumAlpha(F32 minimum);
void vertexAttrib4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void vertexAttrib4fv(U32 index, GLfloat* v);
GLint getUniformLocation(const std::string& uniform);
GLint getUniformLocation(U32 index);
GLint getAttribLocation(U32 attrib);
GLint mapUniformTextureChannel(GLint location, GLenum type);
//enable/disable texture channel for specified uniform
//if given texture uniform is active in the shader,
//the corresponding channel will be active upon return
@ -133,6 +134,9 @@ public:
// Unbinds any previously bound shader by explicitly binding no shader.
static void bindNoShader(void);
U32 mMatHash[LLRender::NUM_MATRIX_MODES];
U32 mLightHash;
GLhandleARB mProgramObject;
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location

View File

@ -36,7 +36,9 @@
#include "llmath.h"
#include "llgl.h"
#include "llglslshader.h"
#include "llrender.h"
//----------------------------------------------------------------------------
const F32 MIN_TEXTURE_LIFETIME = 10.f;
@ -725,7 +727,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
{
if (mAutoGenMips)
{
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
if (!gGLManager.mHasFramebufferObject)
{
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_GENERATE_MIPMAP_SGIS, TRUE);
}
stop_glerror();
{
// LLFastTimer t2(FTM_TEMP4);
@ -754,6 +759,11 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
}
if (gGLManager.mHasFramebufferObject)
{
glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget));
}
}
else
{
@ -875,6 +885,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
{
//not compatible with core GL profile
llassert(!LLRender::sGLCoreProfile);
if (gGLManager.mIsDisabled)
{
llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@ -901,29 +914,29 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
{
switch (mComponents)
{
case 1:
case 1:
// Use luminance alpha (for fonts)
mFormatInternal = GL_LUMINANCE8;
mFormatPrimary = GL_LUMINANCE;
mFormatType = GL_UNSIGNED_BYTE;
break;
case 2:
case 2:
// Use luminance alpha (for fonts)
mFormatInternal = GL_LUMINANCE8_ALPHA8;
mFormatPrimary = GL_LUMINANCE_ALPHA;
mFormatType = GL_UNSIGNED_BYTE;
break;
case 3:
case 3:
mFormatInternal = GL_RGB8;
mFormatPrimary = GL_RGB;
mFormatType = GL_UNSIGNED_BYTE;
break;
case 4:
case 4:
mFormatInternal = GL_RGBA8;
mFormatPrimary = GL_RGBA;
mFormatType = GL_UNSIGNED_BYTE;
break;
default:
default:
llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
}
}
@ -1099,8 +1112,75 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
// static
void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
{
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
bool use_scratch = false;
U32* scratch = NULL;
if (LLRender::sGLCoreProfile)
{
if (pixformat == GL_ALPHA && pixtype == GL_UNSIGNED_BYTE)
{ //GL_ALPHA is deprecated, convert to RGBA
use_scratch = true;
scratch = new U32[width*height];
U32 pixel_count = (U32) (width*height);
for (U32 i = 0; i < pixel_count; i++)
{
U8* pix = (U8*) &scratch[i];
pix[0] = pix[1] = pix[2] = 0;
pix[3] = ((U8*) pixels)[i];
}
pixformat = GL_RGBA;
intformat = GL_RGBA8;
}
if (pixformat == GL_LUMINANCE_ALPHA && pixtype == GL_UNSIGNED_BYTE)
{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGBA
use_scratch = true;
scratch = new U32[width*height];
U32 pixel_count = (U32) (width*height);
for (U32 i = 0; i < pixel_count; i++)
{
U8 lum = ((U8*) pixels)[i*2+0];
U8 alpha = ((U8*) pixels)[i*2+1];
U8* pix = (U8*) &scratch[i];
pix[0] = pix[1] = pix[2] = lum;
pix[3] = alpha;
}
pixformat = GL_RGBA;
intformat = GL_RGBA8;
}
if (pixformat == GL_LUMINANCE && pixtype == GL_UNSIGNED_BYTE)
{ //GL_LUMINANCE_ALPHA is deprecated, convert to RGB
use_scratch = true;
scratch = new U32[width*height];
U32 pixel_count = (U32) (width*height);
for (U32 i = 0; i < pixel_count; i++)
{
U8 lum = ((U8*) pixels)[i];
U8* pix = (U8*) &scratch[i];
pix[0] = pix[1] = pix[2] = lum;
pix[3] = 255;
}
pixformat = GL_RGBA;
intformat = GL_RGB8;
}
}
stop_glerror();
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, use_scratch ? scratch : pixels);
stop_glerror();
if (use_scratch)
{
delete [] scratch;
}
}
//create an empty GL texture: just create a texture name
@ -1167,29 +1247,29 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
{
switch (mComponents)
{
case 1:
case 1:
// Use luminance alpha (for fonts)
mFormatInternal = GL_LUMINANCE8;
mFormatPrimary = GL_LUMINANCE;
mFormatType = GL_UNSIGNED_BYTE;
break;
case 2:
case 2:
// Use luminance alpha (for fonts)
mFormatInternal = GL_LUMINANCE8_ALPHA8;
mFormatPrimary = GL_LUMINANCE_ALPHA;
mFormatType = GL_UNSIGNED_BYTE;
break;
case 3:
case 3:
mFormatInternal = GL_RGB8;
mFormatPrimary = GL_RGB;
mFormatType = GL_UNSIGNED_BYTE;
break;
case 4:
case 4:
mFormatInternal = GL_RGBA8;
mFormatPrimary = GL_RGBA;
mFormatType = GL_UNSIGNED_BYTE;
break;
default:
default:
llerrs << "Bad number of components for texture: " << (U32)getComponents() << llendl;
}
@ -1212,6 +1292,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
{
llassert(data_in);
stop_glerror();
if (discard_level < 0)
{
@ -1240,8 +1321,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
stop_glerror();
{
llverify(gGL.getTexUnit(0)->bind(this));
stop_glerror();
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_BASE_LEVEL, 0);
stop_glerror();
glTexParameteri(LLTexUnit::getInternalType(mBindTarget), GL_TEXTURE_MAX_LEVEL, mMaxDiscardLevel-discard_level);
stop_glerror();
}
}
if (!mTexName)
@ -1754,7 +1838,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
// this to be an intentional effect and don't treat as a mask.
U32 midrangetotal = 0;
for (U32 i = 4; i < 11; i++)
for (U32 i = 2; i < 13; i++)
{
midrangetotal += sample[i];
}
@ -1769,7 +1853,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
upperhalftotal += sample[i];
}
if (midrangetotal > length/16 || // lots of midrange, or
if (midrangetotal > length/48 || // lots of midrange, or
(lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or
(upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque
{

View File

@ -466,21 +466,21 @@ void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadT
void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height)
{
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadIdentity();
gGL.ortho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f );
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
gGL.loadIdentity();
}
void LLPostProcess::viewPerspective(void)
{
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
}
void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height)

File diff suppressed because it is too large Load Diff

View File

@ -41,6 +41,8 @@
#include "llstrider.h"
#include "llpointer.h"
#include "llglheaders.h"
#include "llmatrix4a.h"
#include "glh/glh_linear.h"
class LLVertexBuffer;
class LLCubeMap;
@ -48,6 +50,8 @@ class LLImageGL;
class LLRenderTarget;
class LLTexture ;
#define LL_MATRIX_STACK_DEPTH 32
class LLTexUnit
{
friend class LLRender;
@ -235,6 +239,8 @@ public:
void setSpotDirection(const LLVector3& direction);
protected:
friend class LLRender;
S32 mIndex;
bool mEnabled;
LLColor4 mDiffuse;
@ -308,6 +314,18 @@ public:
BF_UNDEF
} eBlendFactor;
typedef enum
{
MM_MODELVIEW = 0,
MM_PROJECTION,
MM_TEXTURE0,
MM_TEXTURE1,
MM_TEXTURE2,
MM_TEXTURE3,
NUM_MATRIX_MODES,
MM_TEXTURE
} eMatrixMode;
LLRender();
~LLRender();
void init() ;
@ -319,8 +337,21 @@ public:
void translatef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
void scalef(const GLfloat& x, const GLfloat& y, const GLfloat& z);
void rotatef(const GLfloat& a, const GLfloat& x, const GLfloat& y, const GLfloat& z);
void ortho(F32 left, F32 right, F32 bottom, F32 top, F32 zNear, F32 zFar);
void pushMatrix();
void popMatrix();
void loadMatrix(const GLfloat* m);
void loadIdentity();
void multMatrix(const GLfloat* m);
void matrixMode(U32 mode);
const glh::matrix4f& getModelviewMatrix();
const glh::matrix4f& getProjectionMatrix();
void syncMatrices();
void syncLightState();
void translateUI(F32 x, F32 y, F32 z);
void scaleUI(F32 x, F32 y, F32 z);
@ -351,6 +382,12 @@ public:
void color3fv(const GLfloat* c);
void color4ubv(const GLubyte* c);
void diffuseColor3f(F32 r, F32 g, F32 b);
void diffuseColor3fv(const F32* c);
void diffuseColor4f(F32 r, F32 g, F32 b, F32 a);
void diffuseColor4fv(const F32* c);
void diffuseColor4ubv(const U8* c);
void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
@ -368,7 +405,8 @@ public:
eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
LLLightState* getLight(U32 index);
void setAmbientLightColor(const LLColor4& color);
LLTexUnit* getTexUnit(U32 index);
U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
@ -389,9 +427,21 @@ public:
public:
static U32 sUICalls;
static U32 sUIVerts;
static bool sGLCoreProfile;
private:
bool mDirty;
friend class LLLightState;
U32 mMatrixMode;
U32 mMatIdx[NUM_MATRIX_MODES];
U32 mMatHash[NUM_MATRIX_MODES];
glh::matrix4f mMatrix[NUM_MATRIX_MODES][LL_MATRIX_STACK_DEPTH];
U32 mCurMatHash[NUM_MATRIX_MODES];
U32 mLightHash;
LLColor4 mAmbientLightColor;
bool mDirty;
U32 mQuadCycle;
U32 mCount;
U32 mMode;
U32 mCurrTextureUnitIndex;
@ -419,10 +469,10 @@ private:
};
extern F64 gGLModelView[16];
extern F64 gGLLastModelView[16];
extern F64 gGLLastProjection[16];
extern F64 gGLProjection[16];
extern F32 gGLModelView[16];
extern F32 gGLLastModelView[16];
extern F32 gGLLastProjection[16];
extern F32 gGLProjection[16];
extern S32 gGLViewport[4];
extern LLRender gGL;

View File

@ -35,106 +35,12 @@
#include "llglheaders.h"
GLUquadricObj *gQuadObj2 = NULL;
LLRenderSphere gSphere;
void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks);
void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks)
{
if (!gQuadObj2)
{
gQuadObj2 = gluNewQuadric();
if (!gQuadObj2)
{
llwarns << "drawSolidSphere couldn't allocate quadric" << llendl;
return;
}
}
gluQuadricDrawStyle(gQuadObj2, GLU_FILL);
gluQuadricNormals(gQuadObj2, GLU_SMOOTH);
// If we ever changed/used the texture or orientation state
// of quadObj, we'd need to change it to the defaults here
// with gluQuadricTexture and/or gluQuadricOrientation.
gluQuadricTexture(gQuadObj2, GL_TRUE);
gluSphere(gQuadObj2, radius, slices, stacks);
}
// A couple thoughts on sphere drawing:
// 1) You need more slices than stacks, but little less than 2:1
// 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother
void LLRenderSphere::prerender()
{
// Create a series of display lists for different LODs
mDList[0] = glGenLists(1);
glNewList(mDList[0], GL_COMPILE);
drawSolidSphere(1.0, 30, 20);
glEndList();
mDList[1] = glGenLists(1);
glNewList(mDList[1], GL_COMPILE);
drawSolidSphere(1.0, 20, 15);
glEndList();
mDList[2] = glGenLists(1);
glNewList(mDList[2], GL_COMPILE);
drawSolidSphere(1.0, 12, 8);
glEndList();
mDList[3] = glGenLists(1);
glNewList(mDList[3], GL_COMPILE);
drawSolidSphere(1.0, 8, 5);
glEndList();
}
void LLRenderSphere::cleanupGL()
{
for (S32 detail = 0; detail < 4; detail++)
{
glDeleteLists(mDList[detail], 1);
mDList[detail] = 0;
}
if (gQuadObj2)
{
gluDeleteQuadric(gQuadObj2);
gQuadObj2 = NULL;
}
}
// Constants here are empirically derived from my eyeballs, JNC
//
// The toughest adjustment is the cutoff for the lowest LOD
// Maybe we should have more LODs at the low end?
void LLRenderSphere::render(F32 pixel_area)
{
S32 level_of_detail;
if (pixel_area > 10000.f)
{
level_of_detail = 0;
}
else if (pixel_area > 800.f)
{
level_of_detail = 1;
}
else if (pixel_area > 100.f)
{
level_of_detail = 2;
}
else
{
level_of_detail = 3;
}
glCallList(mDList[level_of_detail]);
}
void LLRenderSphere::render()
{
glCallList(mDList[0]);
renderGGL();
gGL.flush();
}
inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)

View File

@ -40,11 +40,6 @@ void lat2xyz(LLVector3 * result, F32 lat, F32 lon); // utility routine
class LLRenderSphere
{
public:
LLGLuint mDList[5];
void prerender();
void cleanupGL();
void render(F32 pixel_area); // of a box of size 1.0 at that position
void render(); // render at highest LOD
void renderGGL(); // render using LLRender

View File

@ -31,8 +31,7 @@
#include "llgl.h"
LLRenderTarget* LLRenderTarget::sBoundTarget = NULL;
U32 LLRenderTarget::sBytesAllocated = 0;
void check_framebuffer_status()
{
@ -51,7 +50,7 @@ void check_framebuffer_status()
}
}
BOOL LLRenderTarget::sUseFBO = false;
bool LLRenderTarget::sUseFBO = false;
LLRenderTarget::LLRenderTarget() :
mResX(0),
@ -62,8 +61,7 @@ LLRenderTarget::LLRenderTarget() :
mStencil(0),
mUseDepth(false),
mRenderDepth(false),
mUsage(LLTexUnit::TT_TEXTURE),
mSamples(0)
mUsage(LLTexUnit::TT_TEXTURE)
{
}
@ -84,20 +82,6 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
mStencil = stencil;
mUsage = usage;
mUseDepth = depth;
mSamples = samples;
mSamples = gGLManager.getNumFBOFSAASamples(mSamples);
if (mSamples > 1 && gGLManager.mHasTextureMultisample)
{
mUsage = LLTexUnit::TT_MULTISAMPLE_TEXTURE;
//no support for multisampled stencil targets yet
mStencil = false;
}
else
{
mSamples = 0;
}
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
{
@ -157,21 +141,6 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
stop_glerror();
#ifdef GL_ARB_texture_multisample
if (mSamples > 1)
{
clear_glerror();
glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, color_fmt, mResX, mResY, GL_TRUE);
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Could not allocate multisample color buffer for render target." << llendl;
return false;
}
}
else
#else
llassert_always(mSamples <= 1);
#endif
{
clear_glerror();
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
@ -182,32 +151,32 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
}
}
sBytesAllocated += mResX*mResY*4;
stop_glerror();
if (mSamples == 0)
{
if (offset == 0)
{ //use bilinear filtering on single texture render targets that aren't multisampled
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
stop_glerror();
}
else
{ //don't filter data attachments
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
stop_glerror();
}
if (offset == 0)
{ //use bilinear filtering on single texture render targets that aren't multisampled
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
stop_glerror();
}
else
{ //don't filter data attachments
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
stop_glerror();
}
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
{
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
stop_glerror();
}
else
{
// ATI doesn't support mirrored repeat for rectangular textures.
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
}
if (mUsage != LLTexUnit::TT_RECT_TEXTURE)
{
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_MIRROR);
stop_glerror();
}
else
{
// ATI doesn't support mirrored repeat for rectangular textures.
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
stop_glerror();
}
if (mFBO)
@ -250,26 +219,16 @@ bool LLRenderTarget::allocateDepth()
{
LLImageGL::generateTextures(1, &mDepth);
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
if (mSamples == 0)
{
U32 internal_type = LLTexUnit::getInternalType(mUsage);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
stop_glerror();
clear_glerror();
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT32, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
}
#ifdef GL_ARB_texture_multisample
else
{
stop_glerror();
clear_glerror();
glTexImage2DMultisample(LLTexUnit::getInternalType(mUsage), mSamples, GL_DEPTH_COMPONENT32, mResX, mResY, GL_TRUE);
}
#else
llassert_always(mSamples <= 1);
#endif
U32 internal_type = LLTexUnit::getInternalType(mUsage);
stop_glerror();
clear_glerror();
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
sBytesAllocated += mResX*mResY*4;
if (glGetError() != GL_NO_ERROR)
{
llwarns << "Unable to allocate depth buffer for render target." << llendl;
@ -339,14 +298,16 @@ void LLRenderTarget::release()
stop_glerror();
}
mDepth = 0;
sBytesAllocated -= mResX*mResY*4;
}
else if (mUseDepth && mFBO)
{ //detach shared depth buffer
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
if (mStencil)
{ //attached as a renderbuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
mStencil = false;
}
else
@ -364,6 +325,7 @@ void LLRenderTarget::release()
if (mTex.size() > 0)
{
sBytesAllocated -= mResX*mResY*4*mTex.size();
LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
mTex.clear();
}
@ -495,7 +457,8 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
gGL.flush();
if (!source.mFBO || !mFBO)
{
llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
return;
}

View File

@ -63,7 +63,8 @@ class LLRenderTarget
{
public:
//whether or not to use FBO implementation
static BOOL sUseFBO;
static bool sUseFBO;
static U32 sBytesAllocated;
LLRenderTarget();
~LLRenderTarget();
@ -143,11 +144,10 @@ protected:
std::vector<U32> mTex;
U32 mFBO;
U32 mDepth;
BOOL mStencil;
BOOL mUseDepth;
BOOL mRenderDepth;
bool mStencil;
bool mUseDepth;
bool mRenderDepth;
LLTexUnit::eTextureType mUsage;
U32 mSamples;
static LLRenderTarget* sBoundTarget;
};

View File

@ -81,7 +81,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
// NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->calculatesAtmospherics)
{
if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
if (features->hasWaterFog)
{
if (!shader->attachObject("windlight/atmosphericsVarsWaterV.glsl"))
{
return FALSE;
}
}
else if (!shader->attachObject("windlight/atmosphericsVarsV.glsl"))
{
return FALSE;
}
@ -167,7 +174,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
if(features->calculatesAtmospherics)
{
if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
if (features->hasWaterFog)
{
if (!shader->attachObject("windlight/atmosphericsVarsWaterF.glsl"))
{
return FALSE;
}
}
else if (!shader->attachObject("windlight/atmosphericsVarsF.glsl"))
{
return FALSE;
}
@ -247,7 +261,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
return FALSE;
}
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
@ -286,7 +300,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
return FALSE;
}
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
}
@ -310,7 +324,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
else if (features->hasWaterFog)
@ -342,7 +356,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
@ -361,7 +375,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
@ -401,7 +415,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
return FALSE;
}
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
}
@ -425,7 +439,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
@ -444,10 +458,26 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
{
return FALSE;
}
shader->mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits-1;
shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
}
}
}
if (features->mIndexedTextureChannels <= 1)
{
if (!shader->attachObject("objects/nonindexedTextureV.glsl"))
{
return FALSE;
}
}
else
{
if (!shader->attachObject("objects/indexedTextureV.glsl"))
{
return FALSE;
}
}
return TRUE;
}
@ -483,7 +513,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
}
else
{
LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
LL_INFOS("ShaderLoading") << log << LL_ENDL;
}
}
}
@ -544,23 +574,64 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
//we can't have any lines longer than 1024 characters
//or any shaders longer than 1024 lines... deal - DaveP
//or any shaders longer than 4096 lines... deal - DaveP
GLcharARB buff[1024];
GLcharARB* text[1024];
GLcharARB* text[4096];
GLuint count = 0;
if (gGLManager.mGLVersion < 2.1f)
F32 version = gGLManager.mGLVersion;
//hack to never use GLSL > 1.20 on OSX
#if LL_DARWIN
version = llmin(version, 2.9f);
#endif
if (version < 2.1f)
{
text[count++] = strdup("#version 110\n");
text[count++] = strdup("#define ATTRIBUTE attribute\n");
text[count++] = strdup("#define VARYING varying\n");
}
else if (gGLManager.mGLVersion < 3.f)
else if (version < 3.3f)
{
//set version to 1.20
text[count++] = strdup("#version 120\n");
text[count++] = strdup("#define FXAA_GLSL_120 1\n");
text[count++] = strdup("#define FXAA_FAST_PIXEL_OFFSET 0\n");
text[count++] = strdup("#define ATTRIBUTE attribute\n");
text[count++] = strdup("#define VARYING varying\n");
}
else
{ //set version to 1.30
text[count++] = strdup("#version 130\n");
{
if (version < 4.f)
{
//set version to 1.30
text[count++] = strdup("#version 130\n");
}
else
{ //set version to 400
text[count++] = strdup("#version 400\n");
}
text[count++] = strdup("#define DEFINE_GL_FRAGCOLOR 1\n");
text[count++] = strdup("#define FXAA_GLSL_130 1\n");
text[count++] = strdup("#define ATTRIBUTE in\n");
if (type == GL_VERTEX_SHADER_ARB)
{ //"varying" state is "out" in a vertex program, "in" in a fragment program
// ("varying" is deprecated after version 1.20)
text[count++] = strdup("#define VARYING out\n");
}
else
{
text[count++] = strdup("#define VARYING in\n");
}
//backwards compatibility with legacy texture lookup syntax
text[count++] = strdup("#define textureCube texture\n");
text[count++] = strdup("#define texture2DLod textureLod\n");
text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
}
//copy preprocessor definitions into buffer
@ -584,7 +655,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
.
uniform sampler2D texN;
varying float vary_texture_index;
VARYING float vary_texture_index;
vec4 diffuseLookup(vec2 texcoord)
{
@ -610,7 +681,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
text[count++] = strdup(decl.c_str());
}
text[count++] = strdup("varying float vary_texture_index;\n");
if (texture_index_channels > 1)
{
text[count++] = strdup("VARYING float vary_texture_index;\n");
}
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
text[count++] = strdup("{\n");
@ -633,7 +708,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
}
text[count++] = strdup("\t}\n");
text[count++] = strdup("\treturn vec4(0,0,0,0);\n");
text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
text[count++] = strdup("}\n");
}
else
@ -656,13 +731,13 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
text[count++] = strdup(if_str.c_str());
}
text[count++] = strdup("\treturn vec4(0,0,0,0);\n");
text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
text[count++] = strdup("}\n");
}
}
//copy file into memory
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(buff) )
while( fgets((char *)buff, 1024, file) != NULL && count < LL_ARRAY_SIZE(text) )
{
text[count++] = (GLcharARB *)strdup((char *)buff);
}
@ -717,14 +792,24 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL;
dumpObjectLog(ret);
#if LL_WINDOWS
std::stringstream ostr;
//dump shader source for debugging
for (GLuint i = 0; i < count; i++)
{
ostr << i << ": " << text[i];
if (i % 128 == 0)
{ //dump every 128 lines
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
ostr = std::stringstream();
}
}
LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl;
#endif // LL_WINDOWS
ret = 0;
}
@ -773,28 +858,42 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors)
LL_WARNS("ShaderLoading") << "GLSL Linker Error:" << LL_ENDL;
}
// NOTE: Removing LL_DARWIN block as it doesn't seem to actually give the correct answer,
// but want it for reference once I move it.
#if 0
// Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software
// per Apple's suggestion
glBegin(gGL.mMode);
glEnd();
#if LL_DARWIN
// Query whether the shader can or cannot run in hardware
// http://developer.apple.com/qa/qa2007/qa1502.html
long vertexGPUProcessing;
CGLContextObj ctx = CGLGetCurrentContext();
CGLGetParameter (ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing);
long fragmentGPUProcessing;
CGLGetParameter (ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
if (!fragmentGPUProcessing || !vertexGPUProcessing)
// For some reason this absolutely kills the frame rate when VBO's are enabled
if (0)
{
LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
success = GL_FALSE;
suppress_errors = FALSE;
// Force an evaluation of the gl state so the driver can tell if the shader will run in hardware or software
// per Apple's suggestion
LLGLSLShader::sNoFixedFunction = false;
glUseProgramObjectARB(obj);
gGL.begin(LLRender::TRIANGLES);
gGL.vertex3f(0.0f, 0.0f, 0.0f);
gGL.vertex3f(0.0f, 0.0f, 0.0f);
gGL.vertex3f(0.0f, 0.0f, 0.0f);
gGL.end();
gGL.flush();
glUseProgramObjectARB(0);
LLGLSLShader::sNoFixedFunction = true;
// Query whether the shader can or cannot run in hardware
// http://developer.apple.com/qa/qa2007/qa1502.html
GLint vertexGPUProcessing, fragmentGPUProcessing;
CGLContextObj ctx = CGLGetCurrentContext();
CGLGetParameter(ctx, kCGLCPGPUVertexProcessing, &vertexGPUProcessing);
CGLGetParameter(ctx, kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing);
if (!fragmentGPUProcessing || !vertexGPUProcessing)
{
LL_WARNS("ShaderLoading") << "GLSL Linker: Running in Software:" << LL_ENDL;
success = GL_FALSE;
suppress_errors = FALSE;
}
}
#else
std::string log = get_object_log(obj);
LLStringUtil::toLower(log);
@ -832,3 +931,181 @@ BOOL LLShaderMgr::validateProgramObject(GLhandleARB obj)
return success;
}
//virtual
void LLShaderMgr::initAttribsAndUniforms()
{
//MUST match order of enum in LLVertexBuffer.h
mReservedAttribs.push_back("position");
mReservedAttribs.push_back("normal");
mReservedAttribs.push_back("texcoord0");
mReservedAttribs.push_back("texcoord1");
mReservedAttribs.push_back("texcoord2");
mReservedAttribs.push_back("texcoord3");
mReservedAttribs.push_back("diffuse_color");
mReservedAttribs.push_back("emissive");
mReservedAttribs.push_back("binormal");
mReservedAttribs.push_back("weight");
mReservedAttribs.push_back("weight4");
mReservedAttribs.push_back("clothing");
mReservedAttribs.push_back("texture_index");
//matrix state
mReservedUniforms.push_back("modelview_matrix");
mReservedUniforms.push_back("projection_matrix");
mReservedUniforms.push_back("inv_proj");
mReservedUniforms.push_back("modelview_projection_matrix");
mReservedUniforms.push_back("normal_matrix");
mReservedUniforms.push_back("texture_matrix0");
mReservedUniforms.push_back("texture_matrix1");
mReservedUniforms.push_back("texture_matrix2");
mReservedUniforms.push_back("texture_matrix3");
llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_MATRIX3+1);
mReservedUniforms.push_back("viewport");
mReservedUniforms.push_back("light_position");
mReservedUniforms.push_back("light_direction");
mReservedUniforms.push_back("light_attenuation");
mReservedUniforms.push_back("light_diffuse");
mReservedUniforms.push_back("light_ambient");
mReservedUniforms.push_back("light_count");
mReservedUniforms.push_back("light");
mReservedUniforms.push_back("light_col");
mReservedUniforms.push_back("far_z");
llassert(mReservedUniforms.size() == LLShaderMgr::MULTI_LIGHT_FAR_Z+1);
mReservedUniforms.push_back("proj_mat");
mReservedUniforms.push_back("proj_near");
mReservedUniforms.push_back("proj_p");
mReservedUniforms.push_back("proj_n");
mReservedUniforms.push_back("proj_origin");
mReservedUniforms.push_back("proj_range");
mReservedUniforms.push_back("proj_ambiance");
mReservedUniforms.push_back("proj_shadow_idx");
mReservedUniforms.push_back("shadow_fade");
mReservedUniforms.push_back("proj_focus");
mReservedUniforms.push_back("proj_lod");
mReservedUniforms.push_back("proj_ambient_lod");
llassert(mReservedUniforms.size() == LLShaderMgr::PROJECTOR_AMBIENT_LOD+1);
mReservedUniforms.push_back("color");
mReservedUniforms.push_back("diffuseMap");
mReservedUniforms.push_back("specularMap");
mReservedUniforms.push_back("bumpMap");
mReservedUniforms.push_back("environmentMap");
mReservedUniforms.push_back("cloude_noise_texture");
mReservedUniforms.push_back("fullbright");
mReservedUniforms.push_back("lightnorm");
mReservedUniforms.push_back("sunlight_color_copy");
mReservedUniforms.push_back("ambient");
mReservedUniforms.push_back("blue_horizon");
mReservedUniforms.push_back("blue_density");
mReservedUniforms.push_back("haze_horizon");
mReservedUniforms.push_back("haze_density");
mReservedUniforms.push_back("cloud_shadow");
mReservedUniforms.push_back("density_multiplier");
mReservedUniforms.push_back("distance_multiplier");
mReservedUniforms.push_back("max_y");
mReservedUniforms.push_back("glow");
mReservedUniforms.push_back("cloud_color");
mReservedUniforms.push_back("cloud_pos_density1");
mReservedUniforms.push_back("cloud_pos_density2");
mReservedUniforms.push_back("cloud_scale");
mReservedUniforms.push_back("gamma");
mReservedUniforms.push_back("scene_light_strength");
llassert(mReservedUniforms.size() == LLShaderMgr::SCENE_LIGHT_STRENGTH+1);
mReservedUniforms.push_back("center");
mReservedUniforms.push_back("size");
mReservedUniforms.push_back("falloff");
mReservedUniforms.push_back("minLuminance");
mReservedUniforms.push_back("maxExtractAlpha");
mReservedUniforms.push_back("lumWeights");
mReservedUniforms.push_back("warmthWeights");
mReservedUniforms.push_back("warmthAmount");
mReservedUniforms.push_back("glowStrength");
mReservedUniforms.push_back("glowDelta");
llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_DELTA+1);
mReservedUniforms.push_back("minimum_alpha");
mReservedUniforms.push_back("shadow_matrix");
mReservedUniforms.push_back("env_mat");
mReservedUniforms.push_back("shadow_clip");
mReservedUniforms.push_back("sun_wash");
mReservedUniforms.push_back("shadow_noise");
mReservedUniforms.push_back("blur_size");
mReservedUniforms.push_back("ssao_radius");
mReservedUniforms.push_back("ssao_max_radius");
mReservedUniforms.push_back("ssao_factor");
mReservedUniforms.push_back("ssao_factor_inv");
mReservedUniforms.push_back("ssao_effect_mat");
mReservedUniforms.push_back("screen_res");
mReservedUniforms.push_back("near_clip");
mReservedUniforms.push_back("shadow_offset");
mReservedUniforms.push_back("shadow_bias");
mReservedUniforms.push_back("spot_shadow_bias");
mReservedUniforms.push_back("spot_shadow_offset");
mReservedUniforms.push_back("sun_dir");
mReservedUniforms.push_back("shadow_res");
mReservedUniforms.push_back("proj_shadow_res");
mReservedUniforms.push_back("depth_cutoff");
mReservedUniforms.push_back("norm_cutoff");
llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_NORM_CUTOFF+1);
mReservedUniforms.push_back("tc_scale");
mReservedUniforms.push_back("rcp_screen_res");
mReservedUniforms.push_back("rcp_frame_opt");
mReservedUniforms.push_back("rcp_frame_opt2");
mReservedUniforms.push_back("focal_distance");
mReservedUniforms.push_back("blur_constant");
mReservedUniforms.push_back("tan_pixel_angle");
mReservedUniforms.push_back("magnification");
mReservedUniforms.push_back("max_cof");
mReservedUniforms.push_back("res_scale");
mReservedUniforms.push_back("depthMap");
mReservedUniforms.push_back("shadowMap0");
mReservedUniforms.push_back("shadowMap1");
mReservedUniforms.push_back("shadowMap2");
mReservedUniforms.push_back("shadowMap3");
mReservedUniforms.push_back("shadowMap4");
mReservedUniforms.push_back("shadowMap5");
llassert(mReservedUniforms.size() == LLShaderMgr::DEFERRED_SHADOW5+1);
mReservedUniforms.push_back("normalMap");
mReservedUniforms.push_back("positionMap");
mReservedUniforms.push_back("diffuseRect");
mReservedUniforms.push_back("specularRect");
mReservedUniforms.push_back("noiseMap");
mReservedUniforms.push_back("lightFunc");
mReservedUniforms.push_back("lightMap");
mReservedUniforms.push_back("bloomMap");
mReservedUniforms.push_back("projectionMap");
llassert(mReservedUniforms.size() == END_RESERVED_UNIFORMS);
std::set<std::string> dupe_check;
for (U32 i = 0; i < mReservedUniforms.size(); ++i)
{
if (dupe_check.find(mReservedUniforms[i]) != dupe_check.end())
{
llerrs << "Duplicate reserved uniform name found: " << mReservedUniforms[i] << llendl;
}
dupe_check.insert(mReservedUniforms[i]);
}
}

View File

@ -36,9 +36,137 @@ public:
LLShaderMgr();
virtual ~LLShaderMgr();
typedef enum
{
MODELVIEW_MATRIX = 0,
PROJECTION_MATRIX,
INVERSE_PROJECTION_MATRIX,
MODELVIEW_PROJECTION_MATRIX,
NORMAL_MATRIX,
TEXTURE_MATRIX0,
TEXTURE_MATRIX1,
TEXTURE_MATRIX2,
TEXTURE_MATRIX3,
VIEWPORT,
LIGHT_POSITION,
LIGHT_DIRECTION,
LIGHT_ATTENUATION,
LIGHT_DIFFUSE,
LIGHT_AMBIENT,
MULTI_LIGHT_COUNT,
MULTI_LIGHT,
MULTI_LIGHT_COL,
MULTI_LIGHT_FAR_Z,
PROJECTOR_MATRIX,
PROJECTOR_NEAR,
PROJECTOR_P,
PROJECTOR_N,
PROJECTOR_ORIGIN,
PROJECTOR_RANGE,
PROJECTOR_AMBIANCE,
PROJECTOR_SHADOW_INDEX,
PROJECTOR_SHADOW_FADE,
PROJECTOR_FOCUS,
PROJECTOR_LOD,
PROJECTOR_AMBIENT_LOD,
DIFFUSE_COLOR,
DIFFUSE_MAP,
SPECULAR_MAP,
BUMP_MAP,
ENVIRONMENT_MAP,
CLOUD_NOISE_MAP,
FULLBRIGHT,
LIGHTNORM,
SUNLIGHT_COLOR,
AMBIENT,
BLUE_HORIZON,
BLUE_DENSITY,
HAZE_HORIZON,
HAZE_DENSITY,
CLOUD_SHADOW,
DENSITY_MULTIPLIER,
DISTANCE_MULTIPLIER,
MAX_Y,
GLOW,
CLOUD_COLOR,
CLOUD_POS_DENSITY1,
CLOUD_POS_DENSITY2,
CLOUD_SCALE,
GAMMA,
SCENE_LIGHT_STRENGTH,
LIGHT_CENTER,
LIGHT_SIZE,
LIGHT_FALLOFF,
GLOW_MIN_LUMINANCE,
GLOW_MAX_EXTRACT_ALPHA,
GLOW_LUM_WEIGHTS,
GLOW_WARMTH_WEIGHTS,
GLOW_WARMTH_AMOUNT,
GLOW_STRENGTH,
GLOW_DELTA,
MINIMUM_ALPHA,
DEFERRED_SHADOW_MATRIX,
DEFERRED_ENV_MAT,
DEFERRED_SHADOW_CLIP,
DEFERRED_SUN_WASH,
DEFERRED_SHADOW_NOISE,
DEFERRED_BLUR_SIZE,
DEFERRED_SSAO_RADIUS,
DEFERRED_SSAO_MAX_RADIUS,
DEFERRED_SSAO_FACTOR,
DEFERRED_SSAO_FACTOR_INV,
DEFERRED_SSAO_EFFECT_MAT,
DEFERRED_SCREEN_RES,
DEFERRED_NEAR_CLIP,
DEFERRED_SHADOW_OFFSET,
DEFERRED_SHADOW_BIAS,
DEFERRED_SPOT_SHADOW_BIAS,
DEFERRED_SPOT_SHADOW_OFFSET,
DEFERRED_SUN_DIR,
DEFERRED_SHADOW_RES,
DEFERRED_PROJ_SHADOW_RES,
DEFERRED_DEPTH_CUTOFF,
DEFERRED_NORM_CUTOFF,
FXAA_TC_SCALE,
FXAA_RCP_SCREEN_RES,
FXAA_RCP_FRAME_OPT,
FXAA_RCP_FRAME_OPT2,
DOF_FOCAL_DISTANCE,
DOF_BLUR_CONSTANT,
DOF_TAN_PIXEL_ANGLE,
DOF_MAGNIFICATION,
DOF_MAX_COF,
DOF_RES_SCALE,
DEFERRED_DEPTH,
DEFERRED_SHADOW0,
DEFERRED_SHADOW1,
DEFERRED_SHADOW2,
DEFERRED_SHADOW3,
DEFERRED_SHADOW4,
DEFERRED_SHADOW5,
DEFERRED_NORMAL,
DEFERRED_POSITION,
DEFERRED_DIFFUSE,
DEFERRED_SPECULAR,
DEFERRED_NOISE,
DEFERRED_LIGHTFUNC,
DEFERRED_LIGHT,
DEFERRED_BLOOM,
DEFERRED_PROJECTION,
END_RESERVED_UNIFORMS
} eGLSLReservedUniforms;
// singleton pattern implementation
static LLShaderMgr * instance();
virtual void initAttribsAndUniforms(void);
BOOL attachShaderFeatures(LLGLSLShader * shader);
void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE);
BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE);

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,8 @@
#include <vector>
#include <list>
#define LL_MAX_VERTEX_ATTRIB_LOCATION 64
//============================================================================
// NOTES
// Threading:
@ -49,25 +51,32 @@
//============================================================================
// gl name pools for dynamic and streaming buffers
class LLVBOPool : public LLGLNamePool
class LLVBOPool
{
protected:
virtual GLuint allocateName()
{
GLuint name;
stop_glerror();
glGenBuffersARB(1, &name);
stop_glerror();
return name;
}
public:
static U32 sBytesPooled;
virtual void releaseName(GLuint name)
U32 mUsage;
U32 mType;
//size MUST be a power of 2
U8* allocate(U32& name, U32 size);
//size MUST be the size provided to allocate that returned the given name
void release(U32 name, U8* buffer, U32 size);
//destroy all records in mFreeList
void cleanup();
class Record
{
stop_glerror();
glDeleteBuffersARB(1, &name);
stop_glerror();
}
public:
U32 mGLName;
U8* mClientData;
};
typedef std::list<Record> record_list_t;
std::vector<record_list_t> mFreeList;
};
class LLGLFence
@ -90,9 +99,7 @@ public:
S32 mIndex;
S32 mCount;
MappedRegion(S32 type, S32 index, S32 count)
: mType(type), mIndex(index), mCount(count)
{ }
MappedRegion(S32 type, S32 index, S32 count);
};
LLVertexBuffer(const LLVertexBuffer& rhs)
@ -111,18 +118,17 @@ public:
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
static S32 sWeight4Loc;
static BOOL sUseStreamDraw;
static BOOL sUseVAO;
static BOOL sPreferStreamDraw;
static void initClass(bool use_vbo, bool no_vbo_mapping);
static void cleanupClass();
static void setupClientArrays(U32 data_mask);
static void drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm);
static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp);
static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
static void unbind(); //unbind any bound vertex buffer
static void unbind(); //unbind any bound vertex buffer
//get the size of a vertex with the given typemask
static S32 calcVertexSize(const U32& typemask);
@ -133,24 +139,29 @@ public:
static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
//WARNING -- when updating these enums you MUST
// 1 - update LLVertexBuffer::sTypeSize
// 2 - add a strider accessor
// 3 - modify LLVertexBuffer::setupVertexBuffer
// 4 - modify LLVertexBuffer::setupClientArray
// 5 - modify LLViewerShaderMgr::mReservedAttribs
// 6 - update LLVertexBuffer::setupVertexArray
enum {
TYPE_VERTEX,
TYPE_VERTEX = 0,
TYPE_NORMAL,
TYPE_TEXCOORD0,
TYPE_TEXCOORD1,
TYPE_TEXCOORD2,
TYPE_TEXCOORD3,
TYPE_COLOR,
// These use VertexAttribPointer and should possibly be made generic
TYPE_EMISSIVE,
TYPE_BINORMAL,
TYPE_WEIGHT,
TYPE_WEIGHT4,
TYPE_CLOTHWEIGHT,
TYPE_MAX,
TYPE_INDEX,
//no actual additional data, but indicates position.w is texture index
TYPE_TEXTURE_INDEX,
TYPE_MAX,
TYPE_INDEX,
};
enum {
MAP_VERTEX = (1<<TYPE_VERTEX),
@ -160,6 +171,7 @@ public:
MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
MAP_TEXCOORD3 = (1<<TYPE_TEXCOORD3),
MAP_COLOR = (1<<TYPE_COLOR),
MAP_EMISSIVE = (1<<TYPE_EMISSIVE),
// These use VertexAttribPointer and should possibly be made generic
MAP_BINORMAL = (1<<TYPE_BINORMAL),
MAP_WEIGHT = (1<<TYPE_WEIGHT),
@ -173,24 +185,25 @@ protected:
virtual ~LLVertexBuffer(); // use unref()
virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
virtual void setupVertexBuffer(U32 data_mask); // pure virtual, called from mapBuffer()
void setupVertexArray();
void genBuffer();
void genIndices();
void genBuffer(U32 size);
void genIndices(U32 size);
bool bindGLBuffer(bool force_bind = false);
bool bindGLIndices(bool force_bind = false);
bool bindGLArray();
void releaseBuffer();
void releaseIndices();
void createGLBuffer();
void createGLIndices();
void createGLBuffer(U32 size);
void createGLIndices(U32 size);
void destroyGLBuffer();
void destroyGLIndices();
void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices);
virtual BOOL useVBOs() const;
void unmapBuffer(S32 type);
void freeClientBuffer() ;
void allocateClientVertexBuffer() ;
void allocateClientIndexBuffer() ;
void unmapBuffer();
public:
LLVertexBuffer(U32 typemask, S32 usage);
@ -199,7 +212,8 @@ public:
U8* mapIndexBuffer(S32 index, S32 count, bool map_range);
// set for rendering
virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0
virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
void flush(); //flush pending data to GL memory
// allocate buffer
void allocateBuffer(S32 nverts, S32 nindices, bool create);
virtual void resizeBuffer(S32 newnverts, S32 newnindices);
@ -212,29 +226,30 @@ public:
// setVertsNorms(verts, norms);
// vb->unmapBuffer();
bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getVertexStrider(LLStrider<LLVector4a>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getIndexStrider(LLStrider<U16>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeightStrider(LLStrider<F32>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getWeight4Strider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0, S32 count = -1, bool map_range = false);
BOOL isEmpty() const { return mEmpty; }
BOOL isLocked() const { return mVertexLocked || mIndexLocked; }
S32 getNumVerts() const { return mNumVerts; }
S32 getNumIndices() const { return mNumIndices; }
S32 getRequestedVerts() const { return mRequestedNumVerts; }
S32 getRequestedIndices() const { return mRequestedNumIndices; }
U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
U32 getTypeMask() const { return mTypeMask; }
bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
S32 getSize() const;
S32 getIndicesSize() const { return mNumIndices * sizeof(U16); }
S32 getIndicesSize() const { return mIndicesSize; }
U8* getMappedData() const { return mMappedData; }
U8* getMappedIndices() const { return mMappedIndexData; }
S32 getOffset(S32 type) const { return mOffsets[type]; }
@ -252,25 +267,23 @@ public:
protected:
S32 mNumVerts; // Number of vertices allocated
S32 mNumIndices; // Number of indices allocated
S32 mRequestedNumVerts; // Number of vertices requested
S32 mRequestedNumIndices; // Number of indices requested
ptrdiff_t mAlignedOffset;
ptrdiff_t mAlignedIndexOffset;
S32 mSize;
S32 mIndicesSize;
U32 mTypeMask;
S32 mUsage; // GL usage
U32 mGLBuffer; // GL VBO handle
U32 mGLIndices; // GL IBO handle
U32 mGLArray; // GL VAO handle
U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory
BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory
BOOL mFinal; // if TRUE, buffer can not be mapped again
BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not
BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
S32 mOffsets[TYPE_MAX];
std::vector<MappedRegion> mMappedVertexRegions;
@ -290,7 +303,6 @@ public:
static S32 sGLCount;
static S32 sMappedCount;
static BOOL sMapped;
static std::vector<U32> sDeleteList;
typedef std::list<LLVertexBuffer*> buffer_list_t;
static BOOL sDisableVBOMapping; //disable glMapBufferARB
@ -298,6 +310,7 @@ public:
static S32 sTypeSize[TYPE_MAX];
static U32 sGLMode[LLRender::NUM_MODES];
static U32 sGLRenderBuffer;
static U32 sGLRenderArray;
static U32 sGLRenderIndices;
static BOOL sVBOActive;
static BOOL sIBOActive;

View File

@ -5,6 +5,7 @@ project(llui)
include(00-Common)
include(LLCommon)
include(LLImage)
include(LLInventory)
include(LLMath)
include(LLMessage)
include(LLRender)
@ -16,6 +17,7 @@ include(LLXUIXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLIMAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
@ -35,6 +37,7 @@ set(llui_SOURCE_FILES
llcheckboxctrl.cpp
llclipboard.cpp
llcombobox.cpp
llcommandmanager.cpp
llconsole.cpp
llcontainerview.cpp
llctrlselectioninterface.cpp
@ -100,6 +103,7 @@ set(llui_SOURCE_FILES
lltimectrl.cpp
lltransutil.cpp
lltoggleablemenu.cpp
lltoolbar.cpp
lltooltip.cpp
llui.cpp
lluicolortable.cpp
@ -133,6 +137,7 @@ set(llui_HEADER_FILES
llcheckboxctrl.h
llclipboard.h
llcombobox.h
llcommandmanager.h
llconsole.h
llcontainerview.h
llctrlselectioninterface.h
@ -204,6 +209,7 @@ set(llui_HEADER_FILES
lltextvalidate.h
lltimectrl.h
lltoggleablemenu.h
lltoolbar.h
lltooltip.h
lltransutil.h
lluicolortable.h
@ -250,6 +256,7 @@ target_link_libraries(llui
${LLRENDER_LIBRARIES}
${LLWINDOW_LIBRARIES}
${LLIMAGE_LIBRARIES}
${LLINVENTORY_LIBRARIES}
${LLVFS_LIBRARIES} # ugh, just for LLDir
${LLXUIXML_LIBRARIES}
${LLXML_LIBRARIES}

View File

@ -973,7 +973,7 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
if ( root_rect.overlaps(screen_rect) && LLUI::sDirtyRect.overlaps(screen_rect))
{
glMatrixMode(GL_MODELVIEW);
gGL.matrixMode(LLRender::MM_MODELVIEW);
LLUI::pushMatrix();
{
LLUI::translate((F32)child->getRect().mLeft, (F32)child->getRect().mBottom, 0.f);

View File

@ -86,10 +86,11 @@ LLButton::Params::Params()
label_color_selected("label_color_selected"), // requires is_toggle true
label_color_disabled("label_color_disabled"),
label_color_disabled_selected("label_color_disabled_selected"),
highlight_color("highlight_color"),
image_color("image_color"),
image_color_disabled("image_color_disabled"),
image_overlay_color("image_overlay_color", LLColor4::white),
image_overlay_color("image_overlay_color", LLColor4::white % 0.75f),
image_overlay_disabled_color("image_overlay_disabled_color", LLColor4::white % 0.3f),
image_overlay_selected_color("image_overlay_selected_color", LLColor4::white),
flash_color("flash_color"),
pad_right("pad_right", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")),
pad_left("pad_left", LLUI::sSettingGroups["config"]->getS32("ButtonHPad")),
@ -102,10 +103,13 @@ LLButton::Params::Params()
scale_image("scale_image", true),
hover_glow_amount("hover_glow_amount"),
commit_on_return("commit_on_return", true),
display_pressed_state("display_pressed_state", true),
use_draw_context_alpha("use_draw_context_alpha", true),
badge("badge"),
handle_right_mouse("handle_right_mouse"),
held_down_delay("held_down_delay")
held_down_delay("held_down_delay"),
button_flash_count("button_flash_count"),
button_flash_rate("button_flash_rate")
{
addSynonym(is_toggle, "toggle");
changeDefault(initial_value, LLSD(false));
@ -114,7 +118,7 @@ LLButton::Params::Params()
LLButton::LLButton(const LLButton::Params& p)
: LLUICtrl(p),
LLBadgeOwner(LLView::getHandle()),
LLBadgeOwner(getHandle()),
mMouseDownFrame(0),
mMouseHeldDownCount(0),
mBorderEnabled( FALSE ),
@ -139,12 +143,13 @@ LLButton::LLButton(const LLButton::Params& p)
mSelectedLabelColor(p.label_color_selected()),
mDisabledLabelColor(p.label_color_disabled()),
mDisabledSelectedLabelColor(p.label_color_disabled_selected()),
mHighlightColor(p.highlight_color()),
mImageColor(p.image_color()),
mFlashBgColor(p.flash_color()),
mDisabledImageColor(p.image_color_disabled()),
mImageOverlay(p.image_overlay()),
mImageOverlayColor(p.image_overlay_color()),
mImageOverlayDisabledColor(p.image_overlay_disabled_color()),
mImageOverlaySelectedColor(p.image_overlay_selected_color()),
mImageOverlayAlignment(LLFontGL::hAlignFromName(p.image_overlay_alignment)),
mImageOverlayTopPad(p.image_top_pad),
mImageOverlayBottomPad(p.image_bottom_pad),
@ -162,12 +167,15 @@ LLButton::LLButton(const LLButton::Params& p)
mCommitOnReturn(p.commit_on_return),
mFadeWhenDisabled(FALSE),
mForcePressedState(false),
mDisplayPressedState(p.display_pressed_state),
mLastDrawCharsCount(0),
mMouseDownSignal(NULL),
mMouseUpSignal(NULL),
mHeldDownSignal(NULL),
mUseDrawContextAlpha(p.use_draw_context_alpha),
mHandleRightMouse(p.handle_right_mouse)
mHandleRightMouse(p.handle_right_mouse),
mButtonFlashCount(p.button_flash_count),
mButtonFlashRate(p.button_flash_rate)
{
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
@ -295,6 +303,24 @@ void LLButton::onCommit()
LLUICtrl::onCommit();
}
boost::signals2::connection LLButton::setClickedCallback(const CommitCallbackParam& cb)
{
return setClickedCallback(initCommitCallback(cb));
}
boost::signals2::connection LLButton::setMouseDownCallback(const CommitCallbackParam& cb)
{
return setMouseDownCallback(initCommitCallback(cb));
}
boost::signals2::connection LLButton::setMouseUpCallback(const CommitCallbackParam& cb)
{
return setMouseUpCallback(initCommitCallback(cb));
}
boost::signals2::connection LLButton::setHeldDownCallback(const CommitCallbackParam& cb)
{
return setHeldDownCallback(initCommitCallback(cb));
}
boost::signals2::connection LLButton::setClickedCallback( const commit_signal_t::slot_type& cb )
{
if (!mCommitSignal) mCommitSignal = new commit_signal_t();
@ -317,7 +343,7 @@ boost::signals2::connection LLButton::setHeldDownCallback( const commit_signal_t
}
// *TODO: Deprecate (for backwards compatability only)
// *TODO: Deprecate (for backwards compatibility only)
boost::signals2::connection LLButton::setClickedCallback( button_callback_t cb, void* data )
{
return setClickedCallback(boost::bind(cb, data));
@ -514,15 +540,6 @@ BOOL LLButton::handleRightMouseUp(S32 x, S32 y, MASK mask)
return TRUE;
}
void LLButton::onMouseEnter(S32 x, S32 y, MASK mask)
{
LLUICtrl::onMouseEnter(x, y, mask);
if (isInEnabledChain())
mNeedsHighlight = TRUE;
}
void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
{
LLUICtrl::onMouseLeave(x, y, mask);
@ -537,6 +554,10 @@ void LLButton::setHighlight(bool b)
BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
{
if (isInEnabledChain()
&& (!gFocusMgr.getMouseCapture() || gFocusMgr.getMouseCapture() == this))
mNeedsHighlight = TRUE;
if (!childrenHandleHover(x, y, mask))
{
if (mMouseDownTimer.getStarted())
@ -557,21 +578,37 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
return TRUE;
}
void LLButton::getOverlayImageSize(S32& overlay_width, S32& overlay_height)
{
overlay_width = mImageOverlay->getWidth();
overlay_height = mImageOverlay->getHeight();
F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
overlay_width = llround((F32)overlay_width * scale_factor);
overlay_height = llround((F32)overlay_height * scale_factor);
}
// virtual
void LLButton::draw()
{
static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
bool flash = FALSE;
static LLUICachedControl<F32> button_flash_rate("ButtonFlashRate", 0);
static LLUICachedControl<S32> button_flash_count("ButtonFlashCount", 0);
if( mFlashing )
if( mFlashing)
{
F32 elapsed = mFlashingTimer.getElapsedTimeF32();
S32 flash_count = S32(elapsed * button_flash_rate * 2.f);
// flash on or off?
flash = (flash_count % 2 == 0) || flash_count > S32((F32)button_flash_count * 2.f);
if ( sEnableButtonFlashing)
{
F32 elapsed = mFlashingTimer.getElapsedTimeF32();
S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
// flash on or off?
flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
}
else
{ // otherwise just highlight button in flash color
flash = true;
}
}
bool pressed_by_keyboard = FALSE;
@ -600,7 +637,7 @@ void LLButton::draw()
LLColor4 glow_color = LLColor4::white;
LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
LLUIImage* imagep = NULL;
if (pressed)
if (pressed && mDisplayPressedState)
{
imagep = selected ? mImagePressedSelected : mImagePressed;
}
@ -710,16 +747,7 @@ void LLButton::draw()
}
// Unselected label assignments
LLWString label;
if( getToggleState() )
{
label = mSelectedLabel;
}
else
{
label = mUnselectedLabel;
}
LLWString label = getCurrentLabel();
// overlay with keyboard focus border
if (hasFocus())
@ -784,18 +812,16 @@ void LLButton::draw()
if (mImageOverlay.notNull())
{
// get max width and height (discard level 0)
S32 overlay_width = mImageOverlay->getWidth();
S32 overlay_height = mImageOverlay->getHeight();
S32 overlay_width;
S32 overlay_height;
F32 scale_factor = llmin((F32)getRect().getWidth() / (F32)overlay_width, (F32)getRect().getHeight() / (F32)overlay_height, 1.f);
overlay_width = llround((F32)overlay_width * scale_factor);
overlay_height = llround((F32)overlay_height * scale_factor);
getOverlayImageSize(overlay_width, overlay_height);
S32 center_x = getLocalRect().getCenterX();
S32 center_y = getLocalRect().getCenterY();
//FUGLY HACK FOR "DEPRESSED" BUTTONS
if (pressed)
if (pressed && mDisplayPressedState)
{
center_y--;
center_x++;
@ -806,7 +832,11 @@ void LLButton::draw()
LLColor4 overlay_color = mImageOverlayColor.get();
if (!enabled)
{
overlay_color.mV[VALPHA] = 0.5f;
overlay_color = mImageOverlayDisabledColor.get();
}
else if (getToggleState())
{
overlay_color = mImageOverlaySelectedColor.get();
}
overlay_color.mV[VALPHA] *= alpha;
@ -814,6 +844,7 @@ void LLButton::draw()
{
case LLFontGL::LEFT:
text_left += overlay_width + mImgOverlayLabelSpace;
text_width -= overlay_width + mImgOverlayLabelSpace;
mImageOverlay->draw(
mLeftHPad,
center_y - (overlay_height / 2),
@ -831,6 +862,7 @@ void LLButton::draw()
break;
case LLFontGL::RIGHT:
text_right -= overlay_width + mImgOverlayLabelSpace;
text_width -= overlay_width + mImgOverlayLabelSpace;
mImageOverlay->draw(
getRect().getWidth() - mRightHPad - overlay_width,
center_y - (overlay_height / 2),
@ -866,7 +898,7 @@ void LLButton::draw()
S32 y_offset = 2 + (getRect().getHeight() - 20)/2;
if (pressed)
if (pressed && mDisplayPressedState)
{
y_offset--;
x++;
@ -922,7 +954,7 @@ void LLButton::setToggleState(BOOL b)
void LLButton::setFlashing( BOOL b )
{
if (b != mFlashing)
if ((bool)b != mFlashing)
{
mFlashing = b;
mFlashingTimer.reset();
@ -962,6 +994,23 @@ void LLButton::setLabelSelected( const LLStringExplicit& label )
mSelectedLabel = label;
}
bool LLButton::labelIsTruncated() const
{
return getCurrentLabel().getString().size() > mLastDrawCharsCount;
}
const LLUIString& LLButton::getCurrentLabel() const
{
if( getToggleState() )
{
return mSelectedLabel;
}
else
{
return mUnselectedLabel;
}
}
void LLButton::setImageUnselected(LLPointer<LLUIImage> image)
{
mImageUnselected = image;
@ -973,16 +1022,7 @@ void LLButton::setImageUnselected(LLPointer<LLUIImage> image)
void LLButton::autoResize()
{
LLUIString label;
if(getToggleState())
{
label = mSelectedLabel;
}
else
{
label = mUnselectedLabel;
}
resize(label);
resize(getCurrentLabel());
}
void LLButton::resize(LLUIString label)
@ -992,11 +1032,32 @@ void LLButton::resize(LLUIString label)
// get current btn length
S32 btn_width =getRect().getWidth();
// check if it need resize
if (mAutoResize == TRUE)
if (mAutoResize)
{
if (btn_width - (mRightHPad + mLeftHPad) < label_width)
S32 min_width = label_width + mLeftHPad + mRightHPad;
if (mImageOverlay)
{
setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mLeft + label_width + mLeftHPad + mRightHPad , getRect().mBottom));
S32 overlay_width = mImageOverlay->getWidth();
F32 scale_factor = (getRect().getHeight() - (mImageOverlayBottomPad + mImageOverlayTopPad)) / (F32)mImageOverlay->getHeight();
overlay_width = llround((F32)overlay_width * scale_factor);
switch(mImageOverlayAlignment)
{
case LLFontGL::LEFT:
case LLFontGL::RIGHT:
min_width += overlay_width + mImgOverlayLabelSpace;
break;
case LLFontGL::HCENTER:
min_width = llmax(min_width, overlay_width + mLeftHPad + mRightHPad);
break;
default:
// draw nothing
break;
}
}
if (btn_width < min_width)
{
reshape(min_width, getRect().getHeight());
}
}
}
@ -1143,7 +1204,7 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname)
// Set the button control value (toggle state) to the floater visibility control (Sets the value as well)
button->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
// Set the clicked callback to toggle the floater
button->setClickedCallback(boost::bind(&LLFloaterReg::toggleFloaterInstance, sdname));
button->setClickedCallback(boost::bind(&LLFloaterReg::toggleInstance, sdname, LLSD()));
}
// static
@ -1184,7 +1245,6 @@ void LLButton::resetMouseDownTimer()
mMouseDownTimer.reset();
}
BOOL LLButton::handleDoubleClick(S32 x, S32 y, MASK mask)
{
// just treat a double click as a second click

View File

@ -94,10 +94,11 @@ public:
label_color_selected,
label_color_disabled,
label_color_disabled_selected,
highlight_color,
image_color,
image_color_disabled,
image_overlay_color,
image_overlay_selected_color,
image_overlay_disabled_color,
flash_color;
// layout
@ -123,7 +124,8 @@ public:
// misc
Optional<bool> is_toggle,
scale_image,
commit_on_return;
commit_on_return,
display_pressed_state;
Optional<F32> hover_glow_amount;
Optional<TimeIntervalParam> held_down_delay;
@ -134,6 +136,9 @@ public:
Optional<bool> handle_right_mouse;
Optional<S32> button_flash_count;
Optional<F32> button_flash_rate;
Params();
};
@ -160,7 +165,6 @@ public:
virtual void draw();
/*virtual*/ BOOL postBuild();
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual void onMouseCaptureLost();
@ -171,6 +175,11 @@ public:
void setUseEllipses( BOOL use_ellipses ) { mUseEllipses = use_ellipses; }
boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb);
boost::signals2::connection setMouseDownCallback(const CommitCallbackParam& cb);
boost::signals2::connection setMouseUpCallback(const CommitCallbackParam& cb);
boost::signals2::connection setHeldDownCallback(const CommitCallbackParam& cb);
boost::signals2::connection setClickedCallback( const commit_signal_t::slot_type& cb ); // mouse down and up within button
boost::signals2::connection setMouseDownCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setMouseUpCallback( const commit_signal_t::slot_type& cb ); // mouse up, EVEN IF NOT IN BUTTON
@ -238,6 +247,8 @@ public:
S32 getLastDrawCharsCount() const { return mLastDrawCharsCount; }
bool labelIsTruncated() const;
const LLUIString& getCurrentLabel() const;
void setScaleImage(BOOL scale) { mScaleImage = scale; }
BOOL getScaleImage() const { return mScaleImage; }
@ -273,14 +284,16 @@ public:
protected:
LLPointer<LLUIImage> getImageUnselected() const { return mImageUnselected; }
LLPointer<LLUIImage> getImageSelected() const { return mImageSelected; }
void getOverlayImageSize(S32& overlay_width, S32& overlay_height);
LLFrameTimer mMouseDownTimer;
bool mNeedsHighlight;
S32 mButtonFlashCount;
F32 mButtonFlashRate;
private:
void drawBorder(LLUIImage* imagep, const LLColor4& color, S32 size);
void resetMouseDownTimer();
private:
commit_signal_t* mMouseDownSignal;
commit_signal_t* mMouseUpSignal;
commit_signal_t* mHeldDownSignal;
@ -296,6 +309,8 @@ private:
LLPointer<LLUIImage> mImageOverlay;
LLFontGL::HAlign mImageOverlayAlignment;
LLUIColor mImageOverlayColor;
LLUIColor mImageOverlaySelectedColor;
LLUIColor mImageOverlayDisabledColor;
LLPointer<LLUIImage> mImageUnselected;
LLUIString mUnselectedLabel;
@ -324,21 +339,19 @@ private:
flash icon name is set in attributes(by default it isn't). First way is used otherwise. */
LLPointer<LLUIImage> mImageFlash;
LLUIColor mHighlightColor;
LLUIColor mFlashBgColor;
LLUIColor mImageColor;
LLUIColor mDisabledImageColor;
BOOL mIsToggle;
BOOL mScaleImage;
bool mIsToggle;
bool mScaleImage;
BOOL mDropShadowedText;
BOOL mAutoResize;
BOOL mUseEllipses;
BOOL mBorderEnabled;
BOOL mFlashing;
bool mDropShadowedText;
bool mAutoResize;
bool mUseEllipses;
bool mBorderEnabled;
bool mFlashing;
LLFontGL::HAlign mHAlign;
S32 mLeftHPad;
@ -358,10 +371,10 @@ private:
F32 mHoverGlowStrength;
F32 mCurGlowStrength;
BOOL mNeedsHighlight;
BOOL mCommitOnReturn;
BOOL mFadeWhenDisabled;
bool mCommitOnReturn;
bool mFadeWhenDisabled;
bool mForcePressedState;
bool mDisplayPressedState;
LLFrameTimer mFlashingTimer;

View File

@ -40,6 +40,7 @@ LLClipboard gClipboard;
LLClipboard::LLClipboard()
{
mSourceItem = NULL;
}
@ -134,3 +135,8 @@ BOOL LLClipboard::canPastePrimaryString() const
{
return LLView::getWindow()->isPrimaryTextAvailable();
}
void LLClipboard::setSourceObject(const LLUUID& source_id, LLAssetType::EType type)
{
mSourceItem = new LLInventoryObject (source_id, LLUUID::null, type, "");
}

View File

@ -30,6 +30,8 @@
#include "llstring.h"
#include "lluuid.h"
#include "stdenums.h"
#include "llinventory.h"
class LLClipboard
@ -52,9 +54,14 @@ public:
BOOL canPastePrimaryString() const;
const LLWString& getPastePrimaryWString(LLUUID* source_id = NULL);
// Support clipboard for object known only by their uuid and asset type
void setSourceObject(const LLUUID& source_id, LLAssetType::EType type);
const LLInventoryObject* getSourceObject() { return mSourceItem; }
private:
LLUUID mSourceID;
LLUUID mSourceID;
LLWString mString;
LLInventoryObject* mSourceItem;
};

View File

@ -0,0 +1,172 @@
/**
* @file llcommandmanager.cpp
* @brief LLCommandManager class
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// A control that displays the name of the chosen item, which when
// clicked shows a scrolling box of options.
#include "linden_common.h"
#include "llcommandmanager.h"
#include "lldir.h"
#include "llerror.h"
#include "llxuiparser.h"
#include <boost/foreach.hpp>
//
// LLCommandId class
//
const LLCommandId LLCommandId::null = LLCommandId("null command");
//
// LLCommand class
//
LLCommand::Params::Params()
: available_in_toybox("available_in_toybox", false)
, icon("icon")
, label_ref("label_ref")
, name("name")
, tooltip_ref("tooltip_ref")
, execute_function("execute_function")
, execute_parameters("execute_parameters")
, execute_stop_function("execute_stop_function")
, execute_stop_parameters("execute_stop_parameters")
, is_enabled_function("is_enabled_function")
, is_enabled_parameters("is_enabled_parameters")
, is_running_function("is_running_function")
, is_running_parameters("is_running_parameters")
, is_starting_function("is_starting_function")
, is_starting_parameters("is_starting_parameters")
{
}
LLCommand::LLCommand(const LLCommand::Params& p)
: mIdentifier(p.name)
, mAvailableInToybox(p.available_in_toybox)
, mIcon(p.icon)
, mLabelRef(p.label_ref)
, mName(p.name)
, mTooltipRef(p.tooltip_ref)
, mExecuteFunction(p.execute_function)
, mExecuteParameters(p.execute_parameters)
, mExecuteStopFunction(p.execute_stop_function)
, mExecuteStopParameters(p.execute_stop_parameters)
, mIsEnabledFunction(p.is_enabled_function)
, mIsEnabledParameters(p.is_enabled_parameters)
, mIsRunningFunction(p.is_running_function)
, mIsRunningParameters(p.is_running_parameters)
, mIsStartingFunction(p.is_starting_function)
, mIsStartingParameters(p.is_starting_parameters)
{
}
//
// LLCommandManager class
//
LLCommandManager::LLCommandManager()
{
}
LLCommandManager::~LLCommandManager()
{
for (CommandVector::iterator cmdIt = mCommands.begin(); cmdIt != mCommands.end(); ++cmdIt)
{
LLCommand * command = *cmdIt;
delete command;
}
}
U32 LLCommandManager::commandCount() const
{
return mCommands.size();
}
LLCommand * LLCommandManager::getCommand(U32 commandIndex)
{
return mCommands[commandIndex];
}
LLCommand * LLCommandManager::getCommand(const LLCommandId& commandId)
{
LLCommand * command_match = NULL;
CommandIndexMap::const_iterator found = mCommandIndices.find(commandId.uuid());
if (found != mCommandIndices.end())
{
command_match = mCommands[found->second];
}
return command_match;
}
void LLCommandManager::addCommand(LLCommand * command)
{
LLCommandId command_id = command->id();
mCommandIndices[command_id.uuid()] = mCommands.size();
mCommands.push_back(command);
lldebugs << "Successfully added command: " << command->name() << llendl;
}
//static
bool LLCommandManager::load()
{
LLCommandManager& mgr = LLCommandManager::instance();
std::string commands_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "commands.xml");
LLCommandManager::Params commandsParams;
LLSimpleXUIParser parser;
if (!parser.readXUI(commands_file, commandsParams))
{
llerrs << "Unable to load xml file: " << commands_file << llendl;
return false;
}
if (!commandsParams.validateBlock())
{
llerrs << "Invalid commands file: " << commands_file << llendl;
return false;
}
BOOST_FOREACH(LLCommand::Params& commandParams, commandsParams.commands)
{
LLCommand * command = new LLCommand(commandParams);
mgr.addCommand(command);
}
return true;
}

View File

@ -0,0 +1,202 @@
/**
* @file llcommandmanager.h
* @brief LLCommandManager class to hold commands
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLCOMMANDMANAGER_H
#define LL_LLCOMMANDMANAGER_H
#include "llinitparam.h"
#include "llsingleton.h"
class LLCommand;
class LLCommandManager;
class LLCommandId
{
public:
friend class LLCommand;
friend class LLCommandManager;
struct Params : public LLInitParam::Block<Params>
{
Mandatory<std::string> name;
Params()
: name("name")
{}
};
LLCommandId(const std::string& name)
{
mUUID = LLUUID::generateNewID(name);
}
LLCommandId(const Params& p)
{
mUUID = LLUUID::generateNewID(p.name);
}
LLCommandId(const LLUUID& uuid)
: mUUID(uuid)
{}
const LLUUID& uuid() const { return mUUID; }
bool operator!=(const LLCommandId& command) const
{
return (mUUID != command.mUUID);
}
bool operator==(const LLCommandId& command) const
{
return (mUUID == command.mUUID);
}
static const LLCommandId null;
private:
LLUUID mUUID;
};
typedef std::list<LLCommandId> command_id_list_t;
class LLCommand
{
public:
struct Params : public LLInitParam::Block<Params>
{
Mandatory<bool> available_in_toybox;
Mandatory<std::string> icon;
Mandatory<std::string> label_ref;
Mandatory<std::string> name;
Mandatory<std::string> tooltip_ref;
Mandatory<std::string> execute_function;
Optional<LLSD> execute_parameters;
Optional<std::string> execute_stop_function;
Optional<LLSD> execute_stop_parameters;
Optional<std::string> is_enabled_function;
Optional<LLSD> is_enabled_parameters;
Optional<std::string> is_running_function;
Optional<LLSD> is_running_parameters;
Optional<std::string> is_starting_function;
Optional<LLSD> is_starting_parameters;
Params();
};
LLCommand(const LLCommand::Params& p);
const bool availableInToybox() const { return mAvailableInToybox; }
const std::string& icon() const { return mIcon; }
const LLCommandId& id() const { return mIdentifier; }
const std::string& labelRef() const { return mLabelRef; }
const std::string& name() const { return mName; }
const std::string& tooltipRef() const { return mTooltipRef; }
const std::string& executeFunctionName() const { return mExecuteFunction; }
const LLSD& executeParameters() const { return mExecuteParameters; }
const std::string& executeStopFunctionName() const { return mExecuteStopFunction; }
const LLSD& executeStopParameters() const { return mExecuteStopParameters; }
const std::string& isEnabledFunctionName() const { return mIsEnabledFunction; }
const LLSD& isEnabledParameters() const { return mIsEnabledParameters; }
const std::string& isRunningFunctionName() const { return mIsRunningFunction; }
const LLSD& isRunningParameters() const { return mIsRunningParameters; }
const std::string& isStartingFunctionName() const { return mIsStartingFunction; }
const LLSD& isStartingParameters() const { return mIsStartingParameters; }
private:
LLCommandId mIdentifier;
bool mAvailableInToybox;
std::string mIcon;
std::string mLabelRef;
std::string mName;
std::string mTooltipRef;
std::string mExecuteFunction;
LLSD mExecuteParameters;
std::string mExecuteStopFunction;
LLSD mExecuteStopParameters;
std::string mIsEnabledFunction;
LLSD mIsEnabledParameters;
std::string mIsRunningFunction;
LLSD mIsRunningParameters;
std::string mIsStartingFunction;
LLSD mIsStartingParameters;
};
class LLCommandManager
: public LLSingleton<LLCommandManager>
{
public:
struct Params : public LLInitParam::Block<Params>
{
Multiple< LLCommand::Params, AtLeast<1> > commands;
Params()
: commands("command")
{
}
};
LLCommandManager();
~LLCommandManager();
U32 commandCount() const;
LLCommand * getCommand(U32 commandIndex);
LLCommand * getCommand(const LLCommandId& commandId);
static bool load();
protected:
void addCommand(LLCommand * command);
private:
typedef std::map<LLUUID, U32> CommandIndexMap;
typedef std::vector<LLCommand *> CommandVector;
CommandVector mCommands;
CommandIndexMap mCommandIndices;
};
#endif // LL_LLCOMMANDMANAGER_H

View File

@ -82,7 +82,7 @@ BOOL LLDockableFloater::postBuild()
mForceDocking = true;
}
mDockTongue = LLUI::getUIImage("windows/Flyout_Pointer.png");
mDockTongue = LLUI::getUIImage("Flyout_Pointer");
LLFloater::setDocked(true);
return LLView::postBuild();
}
@ -162,10 +162,15 @@ void LLDockableFloater::setVisible(BOOL visible)
void LLDockableFloater::setMinimized(BOOL minimize)
{
if(minimize)
if(minimize && isDocked())
{
// minimizing a docked floater just hides it
setVisible(FALSE);
}
else
{
LLFloater::setMinimized(minimize);
}
}
LLView * LLDockableFloater::getDockWidget()
@ -234,8 +239,21 @@ void LLDockableFloater::setDockControl(LLDockControl* dockControl)
setDocked(isDocked());
}
const LLUIImagePtr& LLDockableFloater::getDockTongue()
const LLUIImagePtr& LLDockableFloater::getDockTongue(LLDockControl::DocAt dock_side)
{
switch(dock_side)
{
case LLDockControl::LEFT:
mDockTongue = LLUI::getUIImage("Flyout_Left");
break;
case LLDockControl::RIGHT:
mDockTongue = LLUI::getUIImage("Flyout_Right");
break;
default:
mDockTongue = LLUI::getUIImage("Flyout_Pointer");
break;
}
return mDockTongue;
}

View File

@ -113,6 +113,8 @@ public:
bool getUniqueDocking() { return mUniqueDocking; }
bool getUseTongue() { return mUseTongue; }
void setUseTongue(bool use_tongue) { mUseTongue = use_tongue;}
private:
/**
* Provides unique of dockable floater.
@ -122,7 +124,7 @@ private:
protected:
void setDockControl(LLDockControl* dockControl);
const LLUIImagePtr& getDockTongue();
const LLUIImagePtr& getDockTongue(LLDockControl::DocAt dock_side = LLDockControl::TOP);
// Checks if docking should be forced.
// It may be useful e.g. if floater created in mouselook mode (see EXT-5609)

View File

@ -92,19 +92,24 @@ void LLDockControl::setDock(LLView* dockWidget)
void LLDockControl::getAllowedRect(LLRect& rect)
{
rect = mDockableFloater->getRootView()->getRect();
rect = mDockableFloater->getRootView()->getChild<LLView>("non_toolbar_panel")->getRect();
}
void LLDockControl::repositionDockable()
{
if (!mDockWidget) return;
LLRect dockRect = mDockWidget->calcScreenRect();
LLRect rootRect;
LLRect floater_rect = mDockableFloater->calcScreenRect();
mGetAllowedRectCallback(rootRect);
// recalculate dockable position if dock position changed, dock visibility changed,
// root view rect changed or recalculation is forced
if (mPrevDockRect != dockRect || mDockWidgetVisible != isDockVisible()
|| mRootRect != rootRect || mRecalculateDocablePosition)
// recalculate dockable position if:
if (mPrevDockRect != dockRect //dock position changed
|| mDockWidgetVisible != isDockVisible() //dock visibility changed
|| mRootRect != rootRect //root view rect changed
|| mFloaterRect != floater_rect //floater rect changed
|| mRecalculateDockablePosition //recalculation is forced
)
{
// undock dockable and off() if dock not visible
if (!isDockVisible())
@ -135,7 +140,8 @@ void LLDockControl::repositionDockable()
mPrevDockRect = dockRect;
mRootRect = rootRect;
mRecalculateDocablePosition = false;
mFloaterRect = floater_rect;
mRecalculateDockablePosition = false;
mDockWidgetVisible = isDockVisible();
}
}
@ -160,7 +166,7 @@ bool LLDockControl::isDockVisible()
case TOP:
{
// check is dock inside parent rect
// assume that parent for all dockable flaoters
// assume that parent for all dockable floaters
// is the root view
LLRect dockParentRect =
mDockWidget->getRootView()->calcScreenRect();
@ -202,21 +208,33 @@ void LLDockControl::moveDockable()
switch (mDockAt)
{
case LEFT:
x = dockRect.mLeft;
y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
// check is dockable inside root view rect
if (x < rootRect.mLeft)
{
x = rootRect.mLeft;
}
if (x + dockableRect.getWidth() > rootRect.mRight)
{
x = rootRect.mRight - dockableRect.getWidth();
}
x = dockRect.mLeft - dockableRect.getWidth();
y = dockRect.getCenterY() + dockableRect.getHeight() / 2;
mDockTongueX = x + dockableRect.getWidth()/2 - mDockTongue->getWidth() / 2;
if (use_tongue)
{
x -= mDockTongue->getWidth();
}
mDockTongueX = dockableRect.mRight;
mDockTongueY = dockableRect.getCenterY() - mDockTongue->getHeight() / 2;
mDockTongueY = dockRect.mTop;
break;
case RIGHT:
x = dockRect.mRight;
y = dockRect.getCenterY() + dockableRect.getHeight() / 2;
if (use_tongue)
{
x += mDockTongue->getWidth();
}
mDockTongueX = dockRect.mRight;
mDockTongueY = dockableRect.getCenterY() - mDockTongue->getHeight() / 2;
break;
case TOP:
@ -314,13 +332,12 @@ void LLDockControl::moveDockable()
dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
dockableRect.getHeight());
}
LLRect localDocableParentRect;
mDockableFloater->getParent()->screenRectToLocal(dockableRect,
&localDocableParentRect);
mDockableFloater->setRect(localDocableParentRect);
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
&mDockTongueX, &mDockTongueY);
LLRect localDocableParentRect;
mDockableFloater->getParent()->screenRectToLocal(dockableRect, &localDocableParentRect);
mDockableFloater->setRect(localDocableParentRect);
mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY, &mDockTongueX, &mDockTongueY);
}
@ -329,7 +346,7 @@ void LLDockControl::on()
if (isDockVisible())
{
mEnabled = true;
mRecalculateDocablePosition = true;
mRecalculateDockablePosition = true;
}
}
@ -340,7 +357,7 @@ void LLDockControl::off()
void LLDockControl::forceRecalculatePosition()
{
mRecalculateDocablePosition = true;
mRecalculateDockablePosition = true;
}
void LLDockControl::drawToungue()

View File

@ -43,6 +43,7 @@ public:
{
TOP,
LEFT,
RIGHT,
BOTTOM
};
@ -79,12 +80,13 @@ private:
private:
get_allowed_rect_callback_t mGetAllowedRectCallback;
bool mEnabled;
bool mRecalculateDocablePosition;
bool mRecalculateDockablePosition;
bool mDockWidgetVisible;
DocAt mDockAt;
LLView* mDockWidget;
LLRect mPrevDockRect;
LLRect mRootRect;
LLRect mFloaterRect;
LLFloater* mDockableFloater;
LLUIImagePtr mDockTongue;
S32 mDockTongueX;

View File

@ -58,13 +58,24 @@
#include "llhelp.h"
#include "llmultifloater.h"
#include "llsdutil.h"
#include "../newview/llviewercontrol.h"
#include <boost/foreach.hpp>
#include <string.h>
#include "../newview/llviewercontrol.h" // This is a nasty hack ...
// use this to control "jumping" behavior when Ctrl-Tabbing
const S32 TABBED_FLOATER_OFFSET = 0;
namespace LLInitParam
{
void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues()
{
declare("none", LLFloaterEnums::OPEN_POSITIONING_NONE);
declare("cascading", LLFloaterEnums::OPEN_POSITIONING_CASCADING);
declare("centered", LLFloaterEnums::OPEN_POSITIONING_CENTERED);
declare("specified", LLFloaterEnums::OPEN_POSITIONING_SPECIFIED);
}
}
std::string LLFloater::sButtonNames[BUTTON_COUNT] =
{
"llfloater_close_btn", //BUTTON_CLOSE
@ -103,7 +114,6 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
LLMultiFloater* LLFloater::sHostp = NULL;
BOOL LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
LLFloater::handle_map_t LLFloater::sFloaterMap;
LLFloaterView* gFloaterView = NULL;
@ -157,7 +167,7 @@ LLFloater::Params::Params()
: title("title"),
short_title("short_title"),
single_instance("single_instance", false),
auto_tile("auto_tile", false),
reuse_instance("reuse_instance", false),
can_resize("can_resize", false),
can_minimize("can_minimize", true),
can_close("can_close", true),
@ -168,7 +178,10 @@ LLFloater::Params::Params()
save_rect("save_rect", false),
save_visibility("save_visibility", false),
can_dock("can_dock", false),
open_centered("open_centered", true),
show_title("show_title", true),
open_positioning("open_positioning", LLFloaterEnums::OPEN_POSITIONING_NONE),
specified_left("specified_left"),
specified_bottom("specified_bottom"),
header_height("header_height", 0),
legacy_header_height("legacy_header_height", 0),
close_image("close_image"),
@ -184,7 +197,8 @@ LLFloater::Params::Params()
dock_pressed_image("dock_pressed_image"),
help_pressed_image("help_pressed_image"),
open_callback("open_callback"),
close_callback("close_callback")
close_callback("close_callback"),
follows("follows")
{
changeDefault(visible, false);
}
@ -230,13 +244,16 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mTitle(p.title),
mShortTitle(p.short_title),
mSingleInstance(p.single_instance),
mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default
mKey(key),
mAutoTile(p.auto_tile),
mCanTearOff(p.can_tear_off),
mCanMinimize(p.can_minimize),
mCanClose(p.can_close),
mDragOnLeft(p.can_drag_on_left),
mResizable(p.can_resize),
mOpenPositioning(p.open_positioning),
mSpecifiedLeft(p.specified_left),
mSpecifiedBottom(p.specified_bottom),
mMinWidth(p.min_width),
mMinHeight(p.min_height),
mHeaderHeight(p.header_height),
@ -256,7 +273,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
mMinimizeSignal(NULL)
// mNotificationContext(NULL)
{
mHandle.bind(this);
// mNotificationContext = new LLFloaterNotificationContext(getHandle());
// Clicks stop here.
@ -311,9 +327,6 @@ void LLFloater::initFloater(const Params& p)
// Floaters are created in the invisible state
setVisible(FALSE);
// add self to handle->floater map
sFloaterMap[mHandle] = this;
if (!getParent())
{
gFloaterView->addChild(this);
@ -464,15 +477,24 @@ void LLFloater::layoutResizeCtrls()
mResizeHandle[3]->setRect(rect);
}
void LLFloater::enableResizeCtrls(bool enable)
void LLFloater::enableResizeCtrls(bool enable, bool width, bool height)
{
mResizeBar[LLResizeBar::LEFT]->setVisible(enable && width);
mResizeBar[LLResizeBar::LEFT]->setEnabled(enable && width);
mResizeBar[LLResizeBar::TOP]->setVisible(enable && height);
mResizeBar[LLResizeBar::TOP]->setEnabled(enable && height);
mResizeBar[LLResizeBar::RIGHT]->setVisible(enable && width);
mResizeBar[LLResizeBar::RIGHT]->setEnabled(enable && width);
mResizeBar[LLResizeBar::BOTTOM]->setVisible(enable && height);
mResizeBar[LLResizeBar::BOTTOM]->setEnabled(enable && height);
for (S32 i = 0; i < 4; ++i)
{
mResizeBar[i]->setVisible(enable);
mResizeBar[i]->setEnabled(enable);
mResizeHandle[i]->setVisible(enable);
mResizeHandle[i]->setEnabled(enable);
mResizeHandle[i]->setVisible(enable && width && height);
mResizeHandle[i]->setEnabled(enable && width && height);
}
}
@ -514,8 +536,6 @@ LLFloater::~LLFloater()
storeMinimizeStateControl();
setMinimized( FALSE );
sFloaterMap.erase(mHandle);
delete mDragHandle;
for (S32 i = 0; i < 4; i++)
{
@ -523,7 +543,6 @@ LLFloater::~LLFloater()
delete mResizeHandle[i];
}
storeRectControl();
setVisible(false); // We're not visible if we're destroyed
storeVisibilityControl();
storeDockStateControl();
@ -681,15 +700,23 @@ void LLFloater::openFloater(const LLSD& key)
}
else
{
// AO: setMinimized(FALSE);
LLFloater* floater_to_stack = LLFloaterReg::getLastFloaterInGroup(mInstanceName);
if (!floater_to_stack)
{
floater_to_stack = LLFloaterReg::getLastFloaterCascading();
}
applyControlsAndPosition(floater_to_stack);
// AO: Always unminimize notecards *HACK*
// TS: scripts too
// setMinimized(FALSE);
if ((strcmp(getName().c_str(),"preview notecard") == 0) ||
(strcmp(getName().c_str(),"preview lsl text") == 0))
{
setMinimized(FALSE);
}
setVisibleAndFrontmost(mAutoFocus);
}
@ -781,12 +808,19 @@ void LLFloater::closeFloater(bool app_quitting)
else
{
setVisible(FALSE);
if (!mReuseInstance)
{
destroy();
}
}
}
else
{
setVisible(FALSE); // hide before destroying (so handleVisibilityChange() gets called)
destroy();
if (!mReuseInstance)
{
destroy();
}
}
}
}
@ -851,45 +885,59 @@ LLMultiFloater* LLFloater::getHost()
return (LLMultiFloater*)mHostHandle.get();
}
void LLFloater::applySavedVariables()
void LLFloater::applyControlsAndPosition(LLFloater* other)
{
applyRectControl();
applyDockState();
if (!applyDockState())
{
if (!applyRectControl())
{
applyPositioning(other);
}
}
applyMinimizedState();
}
void LLFloater::applyRectControl()
bool LLFloater::applyRectControl()
{
// first, center on screen if requested
if (mOpenCentered)
{
center();
}
bool saved_rect = false;
// override center if we have saved rect control
// only if we are torn off -Zi
if (mTornOff && mRectControl.size() > 1)
LLFloater* last_in_group = LLFloaterReg::getLastFloaterInGroup(mInstanceName);
if (last_in_group && last_in_group != this)
{
// other floaters in our group, position ourselves relative to them and don't save the rect
mRectControl.clear();
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP;
}
else if (mRectControl.size() > 1)
{
// If we have a saved rect, use it
const LLRect& rect = getControlGroup()->getRect(mRectControl);
if (rect.getWidth() > 0 && rect.getHeight() > 0)
saved_rect = rect.notEmpty();
if (saved_rect)
{
translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom);
setOrigin(rect.mLeft, rect.mBottom);
if (mResizable)
{
reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
}
}
}
return saved_rect;
}
void LLFloater::applyDockState()
bool LLFloater::applyDockState()
{
bool docked = false;
if (mDocStateControl.size() > 1)
{
bool dockState = getControlGroup()->getBOOL(mDocStateControl);
setDocked(dockState);
docked = getControlGroup()->getBOOL(mDocStateControl);
setDocked(docked);
}
return docked;
}
void LLFloater::applyMinimizedState()
@ -901,6 +949,56 @@ void LLFloater::applyMinimizedState()
}
}
void LLFloater::applyPositioning(LLFloater* other)
{
// Otherwise position according to the positioning code
switch (mOpenPositioning)
{
case LLFloaterEnums::OPEN_POSITIONING_CENTERED:
center();
break;
case LLFloaterEnums::OPEN_POSITIONING_SPECIFIED:
{
// Translate relative to snap rect
setOrigin(mSpecifiedLeft, mSpecifiedBottom);
const LLRect& snap_rect = gFloaterView->getSnapRect();
translate(snap_rect.mLeft, snap_rect.mBottom);
translateIntoRect(snap_rect, FALSE);
}
break;
case LLFloaterEnums::OPEN_POSITIONING_CASCADE_GROUP:
case LLFloaterEnums::OPEN_POSITIONING_CASCADING:
if (other != NULL && other != this)
{
stackWith(*other);
}
else
{
static const U32 CASCADING_FLOATER_HOFFSET = 0;
static const U32 CASCADING_FLOATER_VOFFSET = 0;
const LLRect& snap_rect = gFloaterView->getSnapRect();
const S32 horizontal_offset = CASCADING_FLOATER_HOFFSET;
const S32 vertical_offset = snap_rect.getHeight() - CASCADING_FLOATER_VOFFSET;
S32 rect_height = getRect().getHeight();
setOrigin(horizontal_offset, vertical_offset - rect_height);
translate(snap_rect.mLeft, snap_rect.mBottom);
translateIntoRect(snap_rect, FALSE);
}
break;
case LLFloaterEnums::OPEN_POSITIONING_NONE:
default:
// Do nothing
break;
}
}
void LLFloater::applyTitle()
{
if (!mDragHandle)
@ -981,7 +1079,9 @@ BOOL LLFloater::canSnapTo(const LLView* other_view)
if (other_view != getParent())
{
const LLFloater* other_floaterp = dynamic_cast<const LLFloater*>(other_view);
if (other_floaterp && other_floaterp->getSnapTarget() == getHandle() && mDependents.find(other_floaterp->getHandle()) != mDependents.end())
if (other_floaterp
&& other_floaterp->getSnapTarget() == getHandle()
&& mDependents.find(other_floaterp->getHandle()) != mDependents.end())
{
// this is a dependent that is already snapped to us, so don't snap back to it
return FALSE;
@ -1013,9 +1113,10 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user)
const LLRect old_rect = getRect();
LLView::handleReshape(new_rect, by_user);
if (by_user)
if (by_user && !isMinimized())
{
storeRectControl();
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
}
// if not minimized, adjust all snapped dependents to new shape
@ -1075,7 +1176,7 @@ void LLFloater::setMinimized(BOOL minimize)
if (minimize == mMinimized) return;
if(mMinimizeSignal)
if (mMinimizeSignal)
{
(*mMinimizeSignal)(this, LLSD(minimize));
}
@ -1129,10 +1230,6 @@ void LLFloater::setMinimized(BOOL minimize)
mButtonsEnabled[BUTTON_RESTORE] = TRUE;
}
if (mDragHandle)
{
mDragHandle->setVisible(TRUE);
}
setBorderVisible(TRUE);
for(handle_set_iter_t dependent_it = mDependents.begin();
@ -1296,19 +1393,9 @@ void LLFloater::setIsChrome(BOOL is_chrome)
mButtons[BUTTON_CLOSE]->setToolTip(LLStringExplicit(getButtonTooltip(Params(), BUTTON_CLOSE, is_chrome)));
}
// no titles displayed on "chrome" floaters
if (mDragHandle)
mDragHandle->setTitleVisible(!is_chrome);
LLPanel::setIsChrome(is_chrome);
}
void LLFloater::setTitleVisible(bool visible)
{
if (mDragHandle)
mDragHandle->setTitleVisible(visible);
}
// Change the draw style to account for the foreground state.
void LLFloater::setForeground(BOOL front)
{
@ -1396,7 +1483,10 @@ void LLFloater::moveResizeHandlesToFront()
BOOL LLFloater::isFrontmost()
{
return gFloaterView && gFloaterView->getFrontmost() == this && getVisible();
LLFloaterView* floater_view = getParentByType<LLFloaterView>();
return getVisible()
&& (floater_view
&& floater_view->getFrontmost() == this);
}
void LLFloater::addDependentFloater(LLFloater* floaterp, BOOL reposition)
@ -1469,6 +1559,7 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
if(offerClickToButton(x, y, mask, BUTTON_CLOSE)) return TRUE;
if(offerClickToButton(x, y, mask, BUTTON_RESTORE)) return TRUE;
if(offerClickToButton(x, y, mask, BUTTON_TEAR_OFF)) return TRUE;
if(offerClickToButton(x, y, mask, BUTTON_DOCK)) return TRUE;
// Otherwise pass to drag handle for movement
return mDragHandle->handleMouseDown(x, y, mask);
@ -1574,6 +1665,13 @@ void LLFloater::setDocked(bool docked, bool pop_on_undock)
{
mDocked = docked;
mButtonsEnabled[BUTTON_DOCK] = !mDocked;
if (mDocked)
{
setMinimized(FALSE);
mOpenPositioning = LLFloaterEnums::OPEN_POSITIONING_NONE;
}
updateTitleButtons();
storeDockStateControl();
@ -1668,18 +1766,17 @@ void LLFloater::onClickHelp( LLFloater* self )
LLFloater* LLFloater::getClosableFloaterFromFocus()
{
LLFloater* focused_floater = NULL;
handle_map_iter_t iter;
for(iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter)
LLInstanceTracker<LLFloater>::instance_iter it = beginInstances();
LLInstanceTracker<LLFloater>::instance_iter end_it = endInstances();
for (; it != end_it; ++it)
{
focused_floater = iter->second;
if (focused_floater->hasFocus())
if (it->hasFocus())
{
break;
}
}
if (iter == sFloaterMap.end())
if (it == endInstances())
{
// nothing found, return
return NULL;
@ -1828,7 +1925,7 @@ void LLFloater::draw()
{
drawChild(mButtons[i]);
}
drawChild(mDragHandle);
drawChild(mDragHandle, 0, 0, TRUE);
}
else
{
@ -1945,6 +2042,12 @@ void LLFloater::setCanDrag(BOOL can_drag)
}
}
bool LLFloater::getCanDrag()
{
return mDragHandle->getEnabled();
}
void LLFloater::updateTitleButtons()
{
static LLUICachedControl<S32> floater_close_box_size ("UIFloaterCloseBoxSize", 0);
@ -2166,8 +2269,15 @@ LLFloaterView::LLFloaterView (const Params& p)
// By default, adjust vertical.
void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
S32 old_width = getRect().getWidth();
S32 old_height = getRect().getHeight();
S32 old_right = mLastSnapRect.mRight;
S32 old_top = mLastSnapRect.mTop;
LLView::reshape(width, height, called_from_parent);
S32 new_right = getSnapRect().mRight;
S32 new_top = getSnapRect().mTop;
mLastSnapRect = getSnapRect();
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
@ -2175,66 +2285,48 @@ void LLFloaterView::reshape(S32 width, S32 height, BOOL called_from_parent)
LLFloater* floaterp = (LLFloater*)viewp;
if (floaterp->isDependent())
{
// dependents use same follow flags as their "dependee"
// dependents are moved with their "dependee"
continue;
}
// Make if follow the edge it is closest to
U32 follow_flags = 0x0;
if (floaterp->isMinimized())
{
follow_flags |= (FOLLOWS_LEFT | FOLLOWS_TOP);
}
else
if (!floaterp->isMinimized())
{
LLRect r = floaterp->getRect();
// Compute absolute distance from each edge of screen
S32 left_offset = llabs(r.mLeft - 0);
S32 right_offset = llabs(old_width - r.mRight);
S32 right_offset = llabs(old_right - r.mRight);
S32 top_offset = llabs(old_height - r.mTop);
S32 top_offset = llabs(old_top - r.mTop);
S32 bottom_offset = llabs(r.mBottom - 0);
S32 translate_x = 0;
S32 translate_y = 0;
if (left_offset < right_offset)
if (left_offset > right_offset)
{
follow_flags |= FOLLOWS_LEFT;
}
else
{
follow_flags |= FOLLOWS_RIGHT;
translate_x = new_right - old_right;
}
// "No vertical adjustment" usually means that the bottom of the view
// has been pushed up or down. Hence we want the floaters to follow
// the top.
if (top_offset < bottom_offset)
{
follow_flags |= FOLLOWS_TOP;
translate_y = new_top - old_top;
}
else
// don't reposition immovable floaters
if (floaterp->getCanDrag())
{
follow_flags |= FOLLOWS_BOTTOM;
floaterp->translate(translate_x, translate_y);
}
}
floaterp->setFollows(follow_flags);
//RN: all dependent floaters copy follow behavior of "parent"
for(LLFloater::handle_set_iter_t dependent_it = floaterp->mDependents.begin();
dependent_it != floaterp->mDependents.end(); ++dependent_it)
{
LLFloater* dependent_floaterp = dependent_it->get();
if (dependent_floaterp)
BOOST_FOREACH(LLHandle<LLFloater> dependent_floater, floaterp->mDependents)
{
dependent_floaterp->setFollows(follow_flags);
if (dependent_floater.get())
{
dependent_floater.get()->translate(translate_x, translate_y);
}
}
}
}
LLView::reshape(width, height, called_from_parent);
}
@ -2575,6 +2667,52 @@ void LLFloaterView::closeAllChildren(bool app_quitting)
}
}
void LLFloaterView::hiddenFloaterClosed(LLFloater* floater)
{
for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end();
it != end_it;
++it)
{
if (it->first.get() == floater)
{
it->second.disconnect();
mHiddenFloaters.erase(it);
break;
}
}
}
void LLFloaterView::hideAllFloaters()
{
child_list_t child_list = *(getChildList());
for (child_list_iter_t it = child_list.begin(); it != child_list.end(); ++it)
{
LLFloater* floaterp = dynamic_cast<LLFloater*>(*it);
if (floaterp && floaterp->getVisible())
{
floaterp->setVisible(false);
boost::signals2::connection connection = floaterp->mCloseSignal.connect(boost::bind(&LLFloaterView::hiddenFloaterClosed, this, floaterp));
mHiddenFloaters.push_back(std::make_pair(floaterp->getHandle(), connection));
}
}
}
void LLFloaterView::showHiddenFloaters()
{
for (hidden_floaters_t::iterator it = mHiddenFloaters.begin(), end_it = mHiddenFloaters.end();
it != end_it;
++it)
{
LLFloater* floaterp = it->first.get();
if (floaterp)
{
floaterp->setVisible(true);
}
it->second.disconnect();
}
mHiddenFloaters.clear();
}
BOOL LLFloaterView::allChildrenClosed()
{
@ -2608,6 +2746,12 @@ void LLFloaterView::shiftFloaters(S32 x_offset, S32 y_offset)
void LLFloaterView::refresh()
{
LLRect snap_rect = getSnapRect();
if (snap_rect != mLastSnapRect)
{
reshape(getRect().getWidth(), getRect().getHeight(), TRUE);
}
// Constrain children to be entirely on the screen
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
{
@ -2673,7 +2817,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
}
// move window fully onscreen
if (floater->translateIntoRect( getLocalRect(), allow_partial_outside ))
if (floater->translateIntoRect( getSnapRect(), allow_partial_outside ))
{
floater->clearSnapTarget();
}
@ -2903,7 +3047,6 @@ void LLFloater::setInstanceName(const std::string& name)
{
mMinimizeStateControl = LLFloaterReg::declareMinimizeStateControl(ctrl_name);
}
}
}
@ -2950,6 +3093,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
// control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible
LLPanel::initFromParams(p);
// override any follows flags
setFollows(FOLLOWS_NONE);
mTitle = p.title;
mShortTitle = p.short_title;
applyTitle();
@ -2965,8 +3111,11 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
mHeaderHeight = p.header_height;
mLegacyHeaderHeight = p.legacy_header_height;
mSingleInstance = p.single_instance;
mAutoTile = p.auto_tile;
mOpenCentered = p.open_centered;
mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance;
mOpenPositioning = p.open_positioning;
mSpecifiedLeft = p.specified_left;
mSpecifiedBottom = p.specified_bottom;
// ## Zi: Optional Drop Shadows
// we do this here because the values in the constructor get ignored, probably due to
@ -2981,7 +3130,6 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
{
mVisibilityControl = "t"; // flag to build mVisibilityControl name once mInstanceName is set
}
if(p.save_dock_state)
{
mDocStateControl = "t"; // flag to build mDocStateControl name once mInstanceName is set
@ -2992,13 +3140,18 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
// open callback
if (p.open_callback.isProvided())
{
mOpenSignal.connect(initCommitCallback(p.open_callback));
setOpenCallback(initCommitCallback(p.open_callback));
}
// close callback
if (p.close_callback.isProvided())
{
setCloseCallback(initCommitCallback(p.close_callback));
}
if (mDragHandle)
{
mDragHandle->setTitleVisible(p.show_title);
}
}
boost::signals2::connection LLFloater::setMinimizeCallback( const commit_signal_t::slot_type& cb )
@ -3007,6 +3160,11 @@ boost::signals2::connection LLFloater::setMinimizeCallback( const commit_signal_
return mMinimizeSignal->connect(cb);
}
boost::signals2::connection LLFloater::setOpenCallback( const commit_signal_t::slot_type& cb )
{
return mOpenSignal.connect(cb);
}
boost::signals2::connection LLFloater::setCloseCallback( const commit_signal_t::slot_type& cb )
{
return mCloseSignal.connect(cb);
@ -3051,7 +3209,9 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
return FALSE;
}
parser.readXUI(referenced_xml, params, LLUICtrlFactory::getInstance()->getCurFileName());
Params referenced_params;
parser.readXUI(referenced_xml, referenced_params, LLUICtrlFactory::getInstance()->getCurFileName());
params.fillFrom(referenced_params);
// add children using dimensions from referenced xml for consistent layout
setShape(params.rect);
@ -3241,7 +3401,6 @@ void LLFloater::stackWith(LLFloater& other)
next_rect.setLeftTopAndSize(next_rect.mLeft, next_rect.mTop, getRect().getWidth(), getRect().getHeight());
mRectControl.clear(); // don't save rect of stacked floaters
setShape(next_rect);
}

View File

@ -35,6 +35,7 @@
#include "lluuid.h"
//#include "llnotificationsutil.h"
#include <set>
#include <boost/signals2.hpp>
class LLDragHandle;
class LLResizeHandle;
@ -59,11 +60,35 @@ const BOOL CLOSE_NO = FALSE;
const BOOL ADJUST_VERTICAL_YES = TRUE;
const BOOL ADJUST_VERTICAL_NO = FALSE;
class LLFloater : public LLPanel
namespace LLFloaterEnums
{
friend class LLFloaterView;
friend class LLFloaterReg;
friend class LLMultiFloater;
enum EOpenPositioning
{
OPEN_POSITIONING_NONE,
OPEN_POSITIONING_CASCADING,
OPEN_POSITIONING_CASCADE_GROUP,
OPEN_POSITIONING_CENTERED,
OPEN_POSITIONING_SPECIFIED,
OPEN_POSITIONING_COUNT
};
}
namespace LLInitParam
{
template<>
struct TypeValues<LLFloaterEnums::EOpenPositioning> : public TypeValuesHelper<LLFloaterEnums::EOpenPositioning>
{
static void declareValues();
};
}
class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
{
friend class LLFloaterView;
friend class LLFloaterReg;
friend class LLMultiFloater;
public:
struct KeyCompare
{
@ -95,7 +120,7 @@ public:
short_title;
Optional<bool> single_instance,
auto_tile,
reuse_instance,
can_resize,
can_minimize,
can_close,
@ -106,7 +131,13 @@ public:
save_visibility,
save_dock_state,
can_dock,
open_centered;
show_title;
Optional<LLFloaterEnums::EOpenPositioning> open_positioning;
Optional<S32> specified_left;
Optional<S32> specified_bottom;
Optional<S32> header_height,
legacy_header_height; // HACK see initFromXML()
@ -126,6 +157,8 @@ public:
Optional<CommitCallbackParam> open_callback,
close_callback;
Ignored follows;
Params();
};
@ -145,6 +178,7 @@ public:
bool buildFromFile(const std::string &filename, LLXMLNodePtr output_node = NULL);
boost::signals2::connection setMinimizeCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setOpenCallback( const commit_signal_t::slot_type& cb );
boost::signals2::connection setCloseCallback( const commit_signal_t::slot_type& cb );
void initFromParams(const LLFloater::Params& p);
@ -181,7 +215,6 @@ public:
void setShortTitle( const std::string& short_title );
std::string getShortTitle() const;
void setHideOnMinimize(bool hide);
void setTitleVisible(bool visible);
virtual void setMinimized(BOOL b);
void moveResizeHandlesToFront();
void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE);
@ -205,6 +238,7 @@ public:
void setCanTearOff(BOOL can_tear_off);
virtual void setCanResize(BOOL can_resize);
void setCanDrag(BOOL can_drag);
bool getCanDrag();
void setHost(LLMultiFloater* host);
BOOL isResizable() const { return mResizable; }
void setResizeLimits( S32 min_width, S32 min_height );
@ -253,7 +287,7 @@ public:
void clearSnapTarget() { mSnappedTo.markDead(); }
LLHandle<LLFloater> getSnapTarget() const { return mSnappedTo; }
LLHandle<LLFloater> getHandle() const { return mHandle; }
LLHandle<LLFloater> getHandle() const { return getDerivedHandle<LLFloater>(); }
const LLSD& getKey() { return mKey; }
virtual bool matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); }
@ -267,8 +301,6 @@ public:
virtual void setTornOff(bool torn_off) { mTornOff = torn_off; }
void stackWith(LLFloater& other);
// Return a closeable floater, if any, given the current focus.
static LLFloater* getClosableFloaterFromFocus();
@ -292,16 +324,22 @@ public:
void updateTransparency(ETypeTransparency transparency_type);
protected:
virtual void applySavedVariables();
void enableResizeCtrls(bool enable, bool width = true, bool height = true);
void applyRectControl();
void applyDockState();
void applyMinimizedState();
bool isPositioning(LLFloaterEnums::EOpenPositioning p) const { return (p == mOpenPositioning); }
protected:
void applyControlsAndPosition(LLFloater* other);
void stackWith(LLFloater& other);
virtual bool applyRectControl();
bool applyDockState();
void applyPositioning(LLFloater* other);
void storeRectControl();
void storeVisibilityControl();
void storeDockStateControl();
void storeMinimizeStateControl();
void applyMinimizedState();
void setKey(const LLSD& key);
void setInstanceName(const std::string& name);
@ -343,7 +381,6 @@ private:
BOOL offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index);
void addResizeCtrls();
void layoutResizeCtrls();
void enableResizeCtrls(bool enable);
void addDragHandle();
void layoutDragHandle(); // repair layout
@ -382,8 +419,8 @@ private:
LLUIString mShortTitle;
BOOL mSingleInstance; // TRUE if there is only ever one instance of the floater
bool mReuseInstance; // true if we want to hide the floater when we close it instead of destroying it
std::string mInstanceName; // Store the instance name so we can remove ourselves from the list
BOOL mAutoTile; // TRUE if placement of new instances tiles
BOOL mDropShadow; // ## Zi: Optional Drop Shadows
BOOL mCanTearOff;
@ -391,8 +428,11 @@ private:
BOOL mCanClose;
BOOL mDragOnLeft;
BOOL mResizable;
bool mOpenCentered;
bool mHideOnMinimize;
LLFloaterEnums::EOpenPositioning mOpenPositioning;
S32 mSpecifiedLeft;
S32 mSpecifiedBottom;
S32 mMinWidth;
S32 mMinHeight;
@ -431,18 +471,9 @@ private:
typedef void(*click_callback)(LLFloater*);
static click_callback sButtonCallbacks[BUTTON_COUNT];
typedef std::map<LLHandle<LLFloater>, LLFloater*> handle_map_t;
typedef std::map<LLHandle<LLFloater>, LLFloater*>::iterator handle_map_iter_t;
static handle_map_t sFloaterMap;
std::vector<LLHandle<LLView> > mMinimizedHiddenChildren;
BOOL mHasBeenDraggedWhileMinimized;
S32 mPreviousMinimizedBottom;
S32 mPreviousMinimizedLeft;
// LLFloaterNotificationContext* mNotificationContext;
LLRootHandle<LLFloater> mHandle;
};
@ -490,6 +521,10 @@ public:
BOOL allChildrenClosed();
void shiftFloaters(S32 x_offset, S32 y_offset);
void hideAllFloaters();
void showHiddenFloaters();
LLFloater* getFrontmost() const;
LLFloater* getBackmost() const;
LLFloater* getParentFloater(LLView* viewp) const;
@ -504,11 +539,16 @@ public:
void setFloaterSnapView(LLHandle<LLView> snap_view) {mSnapView = snap_view; }
private:
void hiddenFloaterClosed(LLFloater* floater);
LLRect mLastSnapRect;
LLHandle<LLView> mSnapView;
BOOL mFocusCycleMode;
S32 mSnapOffsetBottom;
S32 mSnapOffsetRight;
S32 mMinimizePositionVOffset;
typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
hidden_floaters_t mHiddenFloaters;
};
//

View File

@ -64,19 +64,57 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con
//static
LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
{
LLRect rect;
const std::string& groupname = sGroupMap[name];
if (!groupname.empty())
{
instance_list_t& list = sInstanceMap[groupname];
if (!list.empty())
{
return list.back();
for (instance_list_t::reverse_iterator iter = list.rbegin(); iter != list.rend(); ++iter)
{
LLFloater* inst = *iter;
if (inst->getVisible() && !inst->isMinimized())
{
return inst;
}
}
}
}
return NULL;
}
LLFloater* LLFloaterReg::getLastFloaterCascading()
{
LLRect candidate_rect;
candidate_rect.mTop = 100000;
LLFloater* candidate_floater = NULL;
std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
for( ; it != it_end; ++it)
{
const std::string& group_name = it->second;
instance_list_t& instances = sInstanceMap[group_name];
for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
{
LLFloater* inst = *iter;
if (inst->getVisible() && inst->isPositioning(LLFloaterEnums::OPEN_POSITIONING_CASCADING))
{
if (candidate_rect.mTop > inst->getRect().mTop)
{
candidate_floater = inst;
candidate_rect = inst->getRect();
}
}
}
}
return candidate_floater;
}
//static
LLFloater* LLFloaterReg::findInstance(const std::string& name, const LLSD& key)
{
@ -112,21 +150,24 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
if (!groupname.empty())
{
instance_list_t& list = sInstanceMap[groupname];
int index = list.size();
res = build_func(key);
if (!res)
{
llwarns << "Failed to build floater type: '" << name << "'." << llendl;
return NULL;
}
bool success = res->buildFromFile(xui_file, NULL);
if (!success)
{
llwarns << "Failed to build floater type: '" << name << "'." << llendl;
return NULL;
}
// Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe
if (res->mKey.isUndefined())
{
res->mKey = key;
res->mKey = key;
}
res->setInstanceName(name);
@ -142,20 +183,13 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key)
res->setHideOnMinimize(true);
}
res->applySavedVariables(); // Can't apply rect and dock state until setting instance name
if (res->mAutoTile && !res->getHost() && index > 0)
{
LLFloater* last_floater = getLastFloaterInGroup(groupname);
if (last_floater)
{
res->stackWith(*last_floater);
gFloaterView->adjustToFitScreen(res, true);
}
}
else
{
gFloaterView->adjustToFitScreen(res, false);
}
LLFloater *last_floater = (list.empty() ? NULL : list.back());
res->applyControlsAndPosition(last_floater);
gFloaterView->adjustToFitScreen(res, false);
list.push_back(res);
}
}
@ -444,70 +478,71 @@ void LLFloaterReg::registerControlVariables()
}
}
// Callbacks
// static
// Call once (i.e use for init callbacks)
void LLFloaterReg::initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname)
//static
void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key)
{
// Get the visibility control name for the floater
std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString());
// Set the control value to the floater visibility control (Sets the value as well)
ctrl->setControlVariable(LLFloater::getControlGroup()->getControl(vis_control_name));
}
//
// Floaters controlled by the toolbar behave a bit differently from others.
// Namely they have 3-4 states as defined in the design wiki page here:
// https://wiki.lindenlab.com/wiki/FUI_Button_states
//
// The basic idea is this:
// * If the target floater is minimized, this button press will un-minimize it.
// * Else if the target floater is closed open it.
// * Else if the target floater does not have focus, give it focus.
// * Also, if it is not on top, bring it forward when focus is given.
// * Else the target floater is open, close it.
//
// callback args may use "floatername.key" format
static void parse_name_key(std::string& name, LLSD& key)
{
std::string instname = name;
std::size_t dotpos = instname.find(".");
if (dotpos != std::string::npos)
std::string name = sdname.asString();
LLFloater* instance = getInstance(name, key);
if (!instance)
{
name = instname.substr(0, dotpos);
key = LLSD(instname.substr(dotpos+1, std::string::npos));
lldebugs << "Unable to get instance of floater '" << name << "'" << llendl;
}
else if (instance->isMinimized())
{
instance->setMinimized(FALSE);
instance->setVisibleAndFrontmost();
}
else if (!instance->isShown())
{
instance->openFloater(key);
instance->setVisibleAndFrontmost();
}
else if (!instance->isFrontmost())
{
instance->setVisibleAndFrontmost();
}
else
{
instance->closeFloater();
}
}
//static
void LLFloaterReg::showFloaterInstance(const LLSD& sdname)
// static
U32 LLFloaterReg::getVisibleFloaterInstanceCount()
{
LLSD key;
std::string name = sdname.asString();
parse_name_key(name, key);
showInstance(name, key, TRUE);
}
//static
void LLFloaterReg::hideFloaterInstance(const LLSD& sdname)
{
LLSD key;
std::string name = sdname.asString();
parse_name_key(name, key);
hideInstance(name, key);
}
//static
void LLFloaterReg::toggleFloaterInstance(const LLSD& sdname)
{
LLSD key;
std::string name = sdname.asString();
parse_name_key(name, key);
toggleInstance(name, key);
}
U32 count = 0;
//static
bool LLFloaterReg::floaterInstanceVisible(const LLSD& sdname)
{
LLSD key;
std::string name = sdname.asString();
parse_name_key(name, key);
return instanceVisible(name, key);
}
std::map<std::string,std::string>::const_iterator it = sGroupMap.begin(), it_end = sGroupMap.end();
for( ; it != it_end; ++it)
{
const std::string& group_name = it->second;
//static
bool LLFloaterReg::floaterInstanceMinimized(const LLSD& sdname)
{
LLSD key;
std::string name = sdname.asString();
parse_name_key(name, key);
LLFloater* instance = findInstance(name, key);
return LLFloater::isShown(instance);
instance_list_t& instances = sInstanceMap[group_name];
for (instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); ++iter)
{
LLFloater* inst = *iter;
if (inst->getVisible() && !inst->isMinimized())
{
count++;
}
}
}
return count;
}

View File

@ -99,6 +99,7 @@ public:
// Helpers
static LLFloater* getLastFloaterInGroup(const std::string& name);
static LLFloater* getLastFloaterCascading();
// Find / get (create) / remove / destroy
static LLFloater* findInstance(const std::string& name, const LLSD& key = LLSD());
@ -137,12 +138,7 @@ public:
static void registerControlVariables();
// Callback wrappers
static void initUICtrlToFloaterVisibilityControl(LLUICtrl* ctrl, const LLSD& sdname);
static void showFloaterInstance(const LLSD& sdname);
static void hideFloaterInstance(const LLSD& sdname);
static void toggleFloaterInstance(const LLSD& sdname);
static bool floaterInstanceVisible(const LLSD& sdname);
static bool floaterInstanceMinimized(const LLSD& sdname);
static void toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD& key = LLSD());
// Typed find / get / show
template <class T>
@ -165,6 +161,7 @@ public:
static void blockShowFloaters(bool value) { sBlockShowFloaters = value;}
static U32 getVisibleFloaterInstanceCount();
};
#endif

View File

@ -28,17 +28,18 @@
#define LLHANDLE_H
#include "llpointer.h"
#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>
template <typename T>
class LLTombStone : public LLRefCount
{
public:
LLTombStone(T* target = NULL) : mTarget(target) {}
LLTombStone(void* target = NULL) : mTarget(target) {}
void setTarget(T* target) { mTarget = target; }
T* getTarget() const { return mTarget; }
void setTarget(void* target) { mTarget = target; }
void* getTarget() const { return mTarget; }
private:
T* mTarget;
mutable void* mTarget;
};
// LLHandles are used to refer to objects whose lifetime you do not control or influence.
@ -53,13 +54,15 @@ private:
template <typename T>
class LLHandle
{
template <typename U> friend class LLHandle;
template <typename U> friend class LLHandleProvider;
public:
LLHandle() : mTombStone(getDefaultTombStone()) {}
const LLHandle<T>& operator =(const LLHandle<T>& other)
{
mTombStone = other.mTombStone;
return *this;
}
template<typename U>
LLHandle(const LLHandle<U>& other, typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0)
: mTombStone(other.mTombStone)
{}
bool isDead() const
{
@ -73,7 +76,7 @@ public:
T* get() const
{
return mTombStone->getTarget();
return reinterpret_cast<T*>(mTombStone->getTarget());
}
friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
@ -94,12 +97,13 @@ public:
}
protected:
LLPointer<LLTombStone<T> > mTombStone;
LLPointer<LLTombStone> mTombStone;
private:
static LLPointer<LLTombStone<T> >& getDefaultTombStone()
typedef T* pointer_t;
static LLPointer<LLTombStone>& getDefaultTombStone()
{
static LLPointer<LLTombStone<T> > sDefaultTombStone = new LLTombStone<T>;
static LLPointer<LLTombStone> sDefaultTombStone = new LLTombStone;
return sDefaultTombStone;
}
};
@ -108,23 +112,26 @@ template <typename T>
class LLRootHandle : public LLHandle<T>
{
public:
typedef LLRootHandle<T> self_t;
typedef LLHandle<T> base_t;
LLRootHandle(T* object) { bind(object); }
LLRootHandle() {};
~LLRootHandle() { unbind(); }
// this is redundant, since a LLRootHandle *is* an LLHandle
LLHandle<T> getHandle() { return LLHandle<T>(*this); }
// this is redundant, since an LLRootHandle *is* an LLHandle
//LLHandle<T> getHandle() { return LLHandle<T>(*this); }
void bind(T* object)
{
// unbind existing tombstone
if (LLHandle<T>::mTombStone.notNull())
{
if (LLHandle<T>::mTombStone->getTarget() == object) return;
if (LLHandle<T>::mTombStone->getTarget() == (void*)object) return;
LLHandle<T>::mTombStone->setTarget(NULL);
}
// tombstone reference counted, so no paired delete
LLHandle<T>::mTombStone = new LLTombStone<T>(object);
LLHandle<T>::mTombStone = new LLTombStone((void*)object);
}
void unbind()
@ -142,6 +149,15 @@ private:
template <typename T>
class LLHandleProvider
{
public:
LLHandle<T> getHandle() const
{
// perform lazy binding to avoid small tombstone allocations for handle
// providers whose handles are never referenced
mHandle.bind(static_cast<T*>(const_cast<LLHandleProvider<T>* >(this)));
return mHandle;
}
protected:
typedef LLHandle<T> handle_type_t;
LLHandleProvider()
@ -149,16 +165,17 @@ protected:
// provided here to enforce T deriving from LLHandleProvider<T>
}
LLHandle<T> getHandle()
{
// perform lazy binding to avoid small tombstone allocations for handle
// providers whose handles are never referenced
mHandle.bind(static_cast<T*>(this));
return mHandle;
template <typename U>
LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
{
LLHandle<U> downcast_handle;
downcast_handle.mTombStone = getHandle().mTombStone;
return downcast_handle;
}
private:
LLRootHandle<T> mHandle;
mutable LLRootHandle<T> mHandle;
};
#endif

View File

@ -32,6 +32,7 @@ class LLHelp
{
public:
virtual void showTopic(const std::string &topic) = 0;
virtual std::string getURL(const std::string &topic) = 0;
// return default (fallback) topic name suitable for showTopic()
virtual std::string defaultTopic() = 0;
// return topic to use before the user logs in

View File

@ -51,8 +51,7 @@ public:
* - TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with.
* - DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close.
*/
// typedef enum TOKEN_TYPE
enum TOKEN_TYPE // <ND/> That typedef makes GCC >= 4.6 really angry, rightfully so.
enum TOKEN_TYPE
{
WORD,
LINE,

View File

@ -47,6 +47,19 @@ void LLLayoutStack::OrientationNames::declareValues()
//
// LLLayoutPanel
//
LLLayoutPanel::Params::Params()
: expanded_min_dim("expanded_min_dim", 0),
min_dim("min_dim", 0),
max_dim("max_dim", S32_MAX),
user_resize("user_resize", true),
auto_resize("auto_resize", true)
{
addSynonym(min_dim, "min_width");
addSynonym(min_dim, "min_height");
addSynonym(max_dim, "max_width");
addSynonym(max_dim, "max_height");
}
LLLayoutPanel::LLLayoutPanel(const Params& p)
: LLPanel(p),
mExpandedMinDimSpecified(false),
@ -58,7 +71,9 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
mCollapsed(FALSE),
mCollapseAmt(0.f),
mVisibleAmt(1.f), // default to fully visible
mResizeBar(NULL)
mResizeBar(NULL),
mFractionalSize(0.f),
mOrientation(LLLayoutStack::HORIZONTAL)
{
// Set the expanded min dim if it is provided, otherwise it gets the p.min_dim value
if (p.expanded_min_dim.isProvided())
@ -88,9 +103,22 @@ LLLayoutPanel::~LLLayoutPanel()
mResizeBar = NULL;
}
F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)
void LLLayoutPanel::reshape(S32 width, S32 height, BOOL called_from_parent)
{
if (orientation == LLLayoutStack::HORIZONTAL)
if (mOrientation == LLLayoutStack::HORIZONTAL)
{
mFractionalSize += width - llround(mFractionalSize);
}
else
{
mFractionalSize += height - llround(mFractionalSize);
}
LLPanel::reshape(width, height, called_from_parent);
}
F32 LLLayoutPanel::getCollapseFactor()
{
if (mOrientation == LLLayoutStack::HORIZONTAL)
{
F32 collapse_amt =
clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)getRelevantMinDim() / (F32)llmax(1, getRect().getWidth()));
@ -149,11 +177,11 @@ void LLLayoutStack::draw()
// scale clipping rectangle by visible amount
if (mOrientation == HORIZONTAL)
{
clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor(mOrientation));
clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
}
else
{
clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor(mOrientation));
clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
}
LLPanel* panelp = (*panel_it);
@ -193,36 +221,15 @@ bool LLLayoutStack::addChild(LLView* child, S32 tab_group)
LLLayoutPanel* panelp = dynamic_cast<LLLayoutPanel*>(child);
if (panelp)
{
panelp->mFractionalSize = (mOrientation == HORIZONTAL)
? panelp->getRect().getWidth()
: panelp->getRect().getHeight();
panelp->setOrientation(mOrientation);
mPanels.push_back(panelp);
}
return LLView::addChild(child, tab_group);
}
S32 LLLayoutStack::getDefaultHeight(S32 cur_height)
{
// if we are spanning our children (crude upward propagation of size)
// then don't enforce our size on our children
if (mOrientation == HORIZONTAL)
{
cur_height = llmax(mMinHeight, getRect().getHeight());
}
return cur_height;
}
S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
{
// if we are spanning our children (crude upward propagation of size)
// then don't enforce our size on our children
if (mOrientation == VERTICAL)
{
cur_width = llmax(mMinWidth, getRect().getWidth());
}
return cur_width;
}
void LLLayoutStack::movePanel(LLPanel* panel_to_move, LLPanel* target_panel, bool move_to_front)
{
LLLayoutPanel* embedded_panel_to_move = findEmbeddedPanel(panel_to_move);
@ -317,9 +324,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
createResizeBars();
// calculate current extents
S32 total_width = 0;
S32 total_height = 0;
F32 total_size = 0.f;
//
// animate visibility
//
e_panel_list_t::iterator panel_it;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
@ -361,179 +370,110 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
}
}
if (panelp->mCollapsed)
{
panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
}
else
{
panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
}
F32 collapse_state = panelp->mCollapsed ? 1.f : 0.f;
panelp->mCollapseAmt = lerp(panelp->mCollapseAmt, collapse_state, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
if (mOrientation == HORIZONTAL)
total_size += panelp->mFractionalSize * panelp->getCollapseFactor();
// want n-1 panel gaps for n panels
if (panel_it != mPanels.begin())
{
// enforce minimize size constraint by default
if (panelp->getRect().getWidth() < panelp->getRelevantMinDim())
{
panelp->reshape(panelp->getRelevantMinDim(), panelp->getRect().getHeight());
}
total_width += llround(panelp->getRect().getWidth() * panelp->getCollapseFactor(mOrientation));
// want n-1 panel gaps for n panels
if (panel_it != mPanels.begin())
{
total_width += mPanelSpacing;
}
}
else //VERTICAL
{
// enforce minimize size constraint by default
if (panelp->getRect().getHeight() < panelp->getRelevantMinDim())
{
panelp->reshape(panelp->getRect().getWidth(), panelp->getRelevantMinDim());
}
total_height += llround(panelp->getRect().getHeight() * panelp->getCollapseFactor(mOrientation));
if (panel_it != mPanels.begin())
{
total_height += mPanelSpacing;
}
total_size += mPanelSpacing;
}
}
S32 num_resizable_panels = 0;
S32 shrink_headroom_available = 0;
S32 shrink_headroom_total = 0;
F32 shrink_headroom_available = 0.f;
F32 shrink_headroom_total = 0.f;
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLLayoutPanel* panelp = (*panel_it);
// panels that are not fully visible do not count towards shrink headroom
if ((*panel_it)->getCollapseFactor(mOrientation) < 1.f)
if (panelp->getCollapseFactor() < 1.f)
{
continue;
}
S32 relevant_dimension = (mOrientation == HORIZONTAL) ? (*panel_it)->getRect().getWidth() : (*panel_it)->getRect().getHeight();
S32 relevant_min = (*panel_it)->getRelevantMinDim();
F32 cur_size = panelp->mFractionalSize;
F32 min_size = (F32)panelp->getRelevantMinDim();
// if currently resizing a panel or the panel is flagged as not automatically resizing
// only track total available headroom, but don't use it for automatic resize logic
if ((*panel_it)->mResizeBar->hasMouseCapture()
|| (!(*panel_it)->mAutoResize
if (panelp->mResizeBar->hasMouseCapture()
|| (!panelp->mAutoResize
&& !force_resize))
{
shrink_headroom_total += relevant_dimension - relevant_min;
shrink_headroom_total += cur_size - min_size;
}
else
{
num_resizable_panels++;
shrink_headroom_available += relevant_dimension - relevant_min;
shrink_headroom_total += relevant_dimension - relevant_min;
shrink_headroom_available += cur_size - min_size;
shrink_headroom_total += cur_size - min_size;
}
}
// calculate how many pixels need to be distributed among layout panels
// positive means panels need to grow, negative means shrink
S32 pixels_to_distribute;
if (mOrientation == HORIZONTAL)
{
pixels_to_distribute = getRect().getWidth() - total_width;
}
else //VERTICAL
{
pixels_to_distribute = getRect().getHeight() - total_height;
}
F32 pixels_to_distribute = (mOrientation == HORIZONTAL)
? getRect().getWidth() - total_size
: getRect().getHeight() - total_size;
// now we distribute the pixels...
S32 cur_x = 0;
S32 cur_y = getRect().getHeight();
F32 cur_x = 0.f;
F32 cur_y = (F32)getRect().getHeight();
for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
{
LLLayoutPanel* panelp = (*panel_it);
S32 cur_width = panelp->getRect().getWidth();
S32 cur_height = panelp->getRect().getHeight();
S32 new_width = cur_width;
S32 new_height = cur_height;
S32 relevant_min = panelp->getRelevantMinDim();
if (mOrientation == HORIZONTAL)
{
new_width = llmax(relevant_min, new_width);
}
else
{
new_height = llmax(relevant_min, new_height);
}
S32 delta_size = 0;
F32 min_size = panelp->getRelevantMinDim();
F32 delta_size = 0.f;
// if panel can automatically resize (not animating, and resize flag set)...
if (panelp->getCollapseFactor(mOrientation) == 1.f
if (panelp->getCollapseFactor() == 1.f
&& (force_resize || panelp->mAutoResize)
&& !panelp->mResizeBar->hasMouseCapture())
{
if (mOrientation == HORIZONTAL)
if (pixels_to_distribute < 0.f)
{
// if we're shrinking
if (pixels_to_distribute < 0)
{
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - relevant_min) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_width - relevant_min);
}
else
{
// grow all elements equally
delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
num_resizable_panels--;
}
pixels_to_distribute -= delta_size;
new_width = llmax(relevant_min, cur_width + delta_size);
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0.f)
? pixels_to_distribute * ((F32)(panelp->mFractionalSize - min_size) / shrink_headroom_available)
: 0.f;
shrink_headroom_available -= (panelp->mFractionalSize - min_size);
}
else
{
new_width = getDefaultWidth(new_width);
}
if (mOrientation == VERTICAL)
{
if (pixels_to_distribute < 0)
{
// shrink proportionally to amount over minimum
// so we can do this in one pass
delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - relevant_min) / (F32)shrink_headroom_available)) : 0;
shrink_headroom_available -= (cur_height - relevant_min);
}
else
{
delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels);
num_resizable_panels--;
}
pixels_to_distribute -= delta_size;
new_height = llmax(relevant_min, cur_height + delta_size);
}
else
{
new_height = getDefaultHeight(new_height);
}
}
else
{
if (mOrientation == HORIZONTAL)
{
new_height = getDefaultHeight(new_height);
}
else // VERTICAL
{
new_width = getDefaultWidth(new_width);
// grow all elements equally
delta_size = pixels_to_distribute / (F32)num_resizable_panels;
num_resizable_panels--;
}
panelp->mFractionalSize = llmax(min_size, panelp->mFractionalSize + delta_size);
pixels_to_distribute -= delta_size;
}
// adjust running headroom count based on new sizes
shrink_headroom_total += delta_size;
LLRect panel_rect;
panel_rect.setLeftTopAndSize(cur_x, cur_y, new_width, new_height);
if (mOrientation == HORIZONTAL)
{
panel_rect.setLeftTopAndSize(llround(cur_x),
llround(cur_y),
llround(panelp->mFractionalSize),
getRect().getHeight());
}
else
{
panel_rect.setLeftTopAndSize(llround(cur_x),
llround(cur_y),
getRect().getWidth(),
llround(panelp->mFractionalSize));
}
panelp->setShape(panel_rect);
LLRect resize_bar_rect = panel_rect;
@ -549,13 +489,14 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
}
(*panel_it)->mResizeBar->setRect(resize_bar_rect);
F32 size = ((*panel_it)->mFractionalSize * (*panel_it)->getCollapseFactor()) + (F32)mPanelSpacing;
if (mOrientation == HORIZONTAL)
{
cur_x += llround(new_width * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing;
cur_x += size;
}
else //VERTICAL
{
cur_y -= llround(new_height * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing;
cur_y -= size;
}
}
@ -570,13 +511,13 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
{
(*panel_it)->mResizeBar->setResizeLimits(
relevant_min,
relevant_min + shrink_headroom_total);
relevant_min + llround(shrink_headroom_total));
}
else //VERTICAL
{
(*panel_it)->mResizeBar->setResizeLimits(
relevant_min,
relevant_min + shrink_headroom_total);
relevant_min + llround(shrink_headroom_total));
}
// toggle resize bars based on panel visibility, resizability, etc
@ -599,8 +540,8 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
// not enough room to fit existing contents
if (force_resize == FALSE
// layout did not complete by reaching target position
&& ((mOrientation == VERTICAL && cur_y != -mPanelSpacing)
|| (mOrientation == HORIZONTAL && cur_x != getRect().getWidth() + mPanelSpacing)))
&& ((mOrientation == VERTICAL && llround(cur_y) != -mPanelSpacing)
|| (mOrientation == HORIZONTAL && llround(cur_x) != getRect().getWidth() + mPanelSpacing)))
{
// do another layout pass with all stacked elements contributing
// even those that don't usually resize

View File

@ -126,8 +126,6 @@ protected:
private:
void createResizeBars();
void calcMinExtents();
S32 getDefaultHeight(S32 cur_height);
S32 getDefaultWidth(S32 cur_width);
const ELayoutOrientation mOrientation;
@ -163,24 +161,15 @@ public:
Optional<bool> user_resize,
auto_resize;
Params()
: expanded_min_dim("expanded_min_dim", 0),
min_dim("min_dim", 0),
max_dim("max_dim", 0),
user_resize("user_resize", true),
auto_resize("auto_resize", true)
{
addSynonym(min_dim, "min_width");
addSynonym(min_dim, "min_height");
addSynonym(max_dim, "max_width");
addSynonym(max_dim, "max_height");
}
Params();
};
~LLLayoutPanel();
void initFromParams(const Params& p);
void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
S32 getMinDim() const { return mMinDim; }
void setMinDim(S32 value) { mMinDim = value; if (!mExpandedMinDimSpecified) mExpandedMinDim = value; }
@ -202,22 +191,25 @@ public:
return min_dim;
}
F32 getCollapseFactor();
void setOrientation(LLLayoutStack::ELayoutOrientation orientation) { mOrientation = orientation; }
protected:
LLLayoutPanel(const Params& p);
F32 getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation);
bool mExpandedMinDimSpecified;
S32 mExpandedMinDim;
bool mExpandedMinDimSpecified;
S32 mExpandedMinDim;
S32 mMinDim;
S32 mMaxDim;
BOOL mAutoResize;
BOOL mUserResize;
BOOL mCollapsed;
S32 mMinDim;
S32 mMaxDim;
bool mAutoResize;
bool mUserResize;
bool mCollapsed;
F32 mVisibleAmt;
F32 mCollapseAmt;
F32 mFractionalSize;
LLLayoutStack::ELayoutOrientation mOrientation;
class LLResizeBar* mResizeBar;
F32 mVisibleAmt;
F32 mCollapseAmt;
};

View File

@ -66,7 +66,7 @@ public:
typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t;
struct MaxLength : public LLInitParam::Choice<MaxLength>
struct MaxLength : public LLInitParam::ChoiceBlock<MaxLength>
{
Alternative<S32> bytes, chars;

View File

@ -34,6 +34,7 @@
// Project includes
#include "lluictrlfactory.h"
#include "lluiimage.h"
#include "boost/foreach.hpp"
// registered in llui.cpp to avoid being left out by MS linker
//static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");
@ -51,11 +52,9 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
void LLLoadingIndicator::initFromParams(const Params& p)
{
for (LLInitParam::ParamIterator<LLUIImage*>::const_iterator it = p.images().image.begin(), end_it = p.images().image.end();
it != end_it;
++it)
BOOST_FOREACH(LLUIImage* image, p.images.image)
{
mImages.push_back(it->getValue());
mImages.push_back(image);
}
// Start timer for switching images.

View File

@ -51,7 +51,7 @@ class LLLoadingIndicator
LOG_CLASS(LLLoadingIndicator);
public:
struct Images : public LLInitParam::Block<Images>
struct Images : public LLInitParam::BatchBlock<Images>
{
Multiple<LLUIImage*> image;
@ -63,7 +63,7 @@ public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
Optional<F32> images_per_sec;
Batch<Images> images;
Optional<Images> images;
Params()
: images_per_sec("images_per_sec", 1.0f),

View File

@ -941,9 +941,14 @@ LLMenuItemBranchGL::LLMenuItemBranchGL(const LLMenuItemBranchGL::Params& p)
LLMenuItemBranchGL::~LLMenuItemBranchGL()
{
LLView::deleteViewByHandle(mBranchHandle);
if (mBranchHandle.get())
{
mBranchHandle.get()->die();
}
}
// virtual
LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse) const
{
@ -1680,7 +1685,8 @@ LLMenuGL::LLMenuGL(const LLMenuGL::Params& p)
mSpilloverMenu(NULL),
mJumpKey(p.jump_key),
mCreateJumpKeys(p.create_jump_keys),
mNeedsArrange(FALSE),
mNeedsArrange(FALSE),
mResetScrollPositionOnShow(true),
mShortcutPad(p.shortcut_pad)
{
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
@ -1725,7 +1731,7 @@ void LLMenuGL::setCanTearOff(BOOL tear_off)
{
LLMenuItemTearOffGL::Params p;
mTearOffItem = LLUICtrlFactory::create<LLMenuItemTearOffGL>(p);
addChildInBack(mTearOffItem);
addChild(mTearOffItem);
}
else if (!tear_off && mTearOffItem != NULL)
{
@ -3037,7 +3043,7 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
S32 mouse_x, mouse_y;
// Resetting scrolling position
if (menu->isScrollable())
if (menu->isScrollable() && menu->isScrollPositionOnShowReset())
{
menu->mFirstVisibleItem = NULL;
}

View File

@ -516,6 +516,9 @@ public:
static class LLMenuHolderGL* sMenuContainer;
void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; }
bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; }
protected:
void createSpilloverBranch();
void cleanupSpilloverBranch();
@ -565,6 +568,7 @@ private:
KEY mJumpKey;
BOOL mCreateJumpKeys;
S32 mShortcutPad;
bool mResetScrollPositionOnShow;
}; // end class LLMenuGL
@ -677,7 +681,7 @@ public:
BOOL appendContextSubMenu(LLContextMenu *menu);
LLHandle<LLContextMenu> getHandle() { mHandle.bind(this); return mHandle; }
LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
// [SL:KB] - Patch: Misc-Spellcheck | Checked: 2010-12-19 (Catznip-2.5.0a) | Added: Catznip-2.5.0a
// NOTE: this is currently only used for spell checking so don't presume this will return something meaningful elsewhere

View File

@ -205,7 +205,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
// update torn off status and remove title bar
floaterp->setTornOff(FALSE);
floaterp->setTitleVisible(FALSE);
// floaterp->setTitleVisible(FALSE);
LLRect rect = floaterp->getRect();
rect.mTop -= floaterp->getHeaderHeight();
floaterp->setRect(rect);
@ -315,7 +315,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)
// update torn off status and add title bar
floaterp->setTornOff(TRUE);
floaterp->setTitleVisible(TRUE);
// floaterp->setTitleVisible(TRUE);
LLRect rect = floaterp->getRect();
rect.mTop += floaterp->getHeaderHeight();
floaterp->setRect(rect);

View File

@ -46,6 +46,7 @@
#include <algorithm>
#include <boost/regex.hpp>
#include <boost/foreach.hpp>
const std::string NOTIFICATION_PERSIST_VERSION = "0.93";
@ -416,23 +417,17 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound));
}
for(LLInitParam::ParamIterator<LLNotificationTemplate::UniquenessContext>::const_iterator it = p.unique.contexts.begin(),
end_it = p.unique.contexts.end();
it != end_it;
++it)
BOOST_FOREACH(const LLNotificationTemplate::UniquenessContext& context, p.unique.contexts)
{
mUniqueContext.push_back(it->value);
mUniqueContext.push_back(context.value);
}
lldebugs << "notification \"" << mName << "\": tag count is " << p.tags.size() << llendl;
for(LLInitParam::ParamIterator<LLNotificationTemplate::Tag>::const_iterator it = p.tags.begin(),
end_it = p.tags.end();
it != end_it;
++it)
BOOST_FOREACH(const LLNotificationTemplate::Tag& tag, p.tags)
{
lldebugs << " tag \"" << std::string(it->value) << "\"" << llendl;
mTags.push_back(it->value);
lldebugs << " tag \"" << std::string(tag.value) << "\"" << llendl;
mTags.push_back(tag.value);
}
mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form));
@ -1404,14 +1399,12 @@ void replaceFormText(LLNotificationForm::Params& form, const std::string& patter
{
form.ignore.text = replace;
}
for (LLInitParam::ParamIterator<LLNotificationForm::FormElement>::iterator it = form.form_elements.elements.begin(),
end_it = form.form_elements.elements.end();
it != end_it;
++it)
BOOST_FOREACH(LLNotificationForm::FormElement& element, form.form_elements.elements)
{
if (it->button.isChosen() && it->button.text() == pattern)
if (element.button.isChosen() && element.button.text() == pattern)
{
it->button.text = replace;
element.button.text = replace;
}
}
}
@ -1460,48 +1453,42 @@ bool LLNotifications::loadTemplates()
mTemplates.clear();
for(LLInitParam::ParamIterator<LLNotificationTemplate::GlobalString>::const_iterator it = params.strings.begin(), end_it = params.strings.end();
it != end_it;
++it)
BOOST_FOREACH(LLNotificationTemplate::GlobalString& string, params.strings)
{
mGlobalStrings[it->name] = it->value;
mGlobalStrings[string.name] = string.value;
}
std::map<std::string, LLNotificationForm::Params> form_templates;
for(LLInitParam::ParamIterator<LLNotificationTemplate::Template>::const_iterator it = params.templates.begin(), end_it = params.templates.end();
it != end_it;
++it)
BOOST_FOREACH(LLNotificationTemplate::Template& notification_template, params.templates)
{
form_templates[it->name] = it->form;
form_templates[notification_template.name] = notification_template.form;
}
for(LLInitParam::ParamIterator<LLNotificationTemplate::Params>::iterator it = params.notifications.begin(), end_it = params.notifications.end();
it != end_it;
++it)
BOOST_FOREACH(LLNotificationTemplate::Params& notification, params.notifications)
{
if (it->form_ref.form_template.isChosen())
if (notification.form_ref.form_template.isChosen())
{
// replace form contents from template
it->form_ref.form = form_templates[it->form_ref.form_template.name];
if(it->form_ref.form_template.yes_text.isProvided())
notification.form_ref.form = form_templates[notification.form_ref.form_template.name];
if(notification.form_ref.form_template.yes_text.isProvided())
{
replaceFormText(it->form_ref.form, "$yestext", it->form_ref.form_template.yes_text);
replaceFormText(notification.form_ref.form, "$yestext", notification.form_ref.form_template.yes_text);
}
if(it->form_ref.form_template.no_text.isProvided())
if(notification.form_ref.form_template.no_text.isProvided())
{
replaceFormText(it->form_ref.form, "$notext", it->form_ref.form_template.no_text);
replaceFormText(notification.form_ref.form, "$notext", notification.form_ref.form_template.no_text);
}
if(it->form_ref.form_template.cancel_text.isProvided())
if(notification.form_ref.form_template.cancel_text.isProvided())
{
replaceFormText(it->form_ref.form, "$canceltext", it->form_ref.form_template.cancel_text);
replaceFormText(notification.form_ref.form, "$canceltext", notification.form_ref.form_template.cancel_text);
}
if(it->form_ref.form_template.ignore_text.isProvided())
if(notification.form_ref.form_template.ignore_text.isProvided())
{
replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text);
replaceFormText(notification.form_ref.form, "$ignoretext", notification.form_ref.form_template.ignore_text);
}
}
mTemplates[it->name] = LLNotificationTemplatePtr(new LLNotificationTemplate(*it));
mTemplates[notification.name] = LLNotificationTemplatePtr(new LLNotificationTemplate(notification));
}
return true;
@ -1524,12 +1511,9 @@ bool LLNotifications::loadVisibilityRules()
mVisibilityRules.clear();
for(LLInitParam::ParamIterator<LLNotificationVisibilityRule::Rule>::iterator it = params.rules.begin(),
end_it = params.rules.end();
it != end_it;
++it)
BOOST_FOREACH(LLNotificationVisibilityRule::Rule& rule, params.rules)
{
mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(*it)));
mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(rule)));
}
return true;

View File

@ -201,7 +201,7 @@ public:
FormInput();
};
struct FormElement : public LLInitParam::Choice<FormElement>
struct FormElement : public LLInitParam::ChoiceBlock<FormElement>
{
Alternative<FormButton> button;
Alternative<FormInput> input;
@ -312,7 +312,7 @@ public:
Optional<LLNotificationContext*> context;
Optional<void*> responder;
struct Functor : public LLInitParam::Choice<Functor>
struct Functor : public LLInitParam::ChoiceBlock<Functor>
{
Alternative<std::string> name;
Alternative<LLNotificationFunctorRegistry::ResponseFunctor> function;

View File

@ -91,7 +91,7 @@ struct LLNotificationTemplate
// <notification> <unique/> </notification>
// as well as
// <notification> <unique> <context></context> </unique>...
Flag dummy_val;
Optional<LLInitParam::Flag> dummy_val;
public:
Multiple<UniquenessContext> contexts;
@ -147,7 +147,7 @@ struct LLNotificationTemplate
{}
};
struct FormRef : public LLInitParam::Choice<FormRef>
struct FormRef : public LLInitParam::ChoiceBlock<FormRef>
{
Alternative<LLNotificationForm::Params> form;
Alternative<TemplateRef> form_template;

View File

@ -59,7 +59,7 @@ struct LLNotificationVisibilityRule
{}
};
struct Rule : public LLInitParam::Choice<Rule>
struct Rule : public LLInitParam::ChoiceBlock<Rule>
{
Alternative<Filter> show;
Alternative<Filter> hide;

View File

@ -122,8 +122,6 @@ LLPanel::LLPanel(const LLPanel::Params& p)
{
addBorder(p.border);
}
mPanelHandle.bind(this);
}
LLPanel::~LLPanel()

View File

@ -96,9 +96,6 @@ public:
Params();
};
// valid children for LLPanel are stored in this registry
typedef LLDefaultChildRegistry child_registry_t;
protected:
friend class LLUICtrlFactory;
// RN: for some reason you can't just use LLUICtrlFactory::getDefaultParams as a default argument in VC8
@ -138,6 +135,8 @@ public:
const LLColor4& getBackgroundColor() const { return mBgOpaqueColor; }
void setTransparentColor(const LLColor4& color) { mBgAlphaColor = color; }
const LLColor4& getTransparentColor() const { return mBgAlphaColor; }
void setBackgroundImage(LLUIImage* image) { mBgOpaqueImage = image; }
void setTransparentImage(LLUIImage* image) { mBgAlphaImage = image; }
LLPointer<LLUIImage> getBackgroundImage() const { return mBgOpaqueImage; }
LLPointer<LLUIImage> getTransparentImage() const { return mBgAlphaImage; }
LLColor4 getBackgroundImageOverlay() { return mBgOpaqueImageOverlay; }
@ -156,7 +155,7 @@ public:
void setCtrlsEnabled(BOOL b);
LLHandle<LLPanel> getHandle() const { return mPanelHandle; }
LLHandle<LLPanel> getHandle() const { return getDerivedHandle<LLPanel>(); }
const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
@ -281,7 +280,6 @@ private:
LLViewBorder* mBorder;
LLButton* mDefaultBtn;
LLUIString mLabel;
LLRootHandle<LLPanel> mPanelHandle;
typedef std::map<std::string, std::string> ui_string_map_t;
ui_string_map_t mUIStrings;

View File

@ -55,7 +55,7 @@ public:
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
void setResizeLimits( S32 min_width, S32 min_height ) { mMinWidth = min_width; mMinHeight = min_height; }
private:
BOOL pointInHandle( S32 x, S32 y );

View File

@ -95,7 +95,7 @@ public:
Optional<ESortDirection, SortNames> sort_direction;
Optional<bool> sort_ascending;
struct Width : public LLInitParam::Choice<Width>
struct Width : public LLInitParam::ChoiceBlock<Width>
{
Alternative<bool> dynamic_width;
Alternative<S32> pixel_width;
@ -112,7 +112,7 @@ public:
Optional<Width> width;
// either an image or label is used in column header
struct Header : public LLInitParam::Choice<Header>
struct Header : public LLInitParam::ChoiceBlock<Header>
{
Alternative<std::string> label;
Alternative<LLUIImage*> image;

View File

@ -483,6 +483,7 @@ void LLScrollListCtrl::updateLayout()
{
mCommentTextView = getChildView("comment_text");
}
mCommentTextView->setShape(mItemListRect);
// how many lines of content in a single "page"

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