Pull and merge from https://bitbucket.org/lindenlab/viewer-development.
commit
a91c2d889a
|
|
@ -323,3 +323,26 @@ fba99f381b8d4ad1b7b42fa4993b29998d95be18 DRTVWR-179
|
|||
524da902713e8b60322640b9825101add4a7c497 3.4.1-beta7
|
||||
173c2809f9873499c4b9d6bc044ec941c954d3fb DRTVWR-228
|
||||
1dc94555582f52718834081e7659e973ae4521f7 3.4.1-beta8
|
||||
52c164c8023a5e65f3dc1b0bbb7fa1dd0c631b6b DRTVWR-231
|
||||
464cf7a63a9a2f95bc4972dc022ca765e93de7d3 DRTVWR-233
|
||||
637fe8bbee5e24940448198c221d5ee0fa3247b4 3.4.1-beta9
|
||||
4e0d84e92132e9e95a1d52a1e49bad69c278ea05 3.4.1-beta10
|
||||
f7cbd60a3f57ff1101157eeb79ea21e8898bedae DRTVWR-235
|
||||
baf97f06ae17223614c5e31aa42e71d87cff07fe DRTVWR-236
|
||||
18498afcdb835d6fc4d36ed935347d3b65307bad 3.4.1-beta11
|
||||
b2f21e3442542283a80e7eaebae9f833e5a927b6 DRTVWR-237
|
||||
3f9be82de642d468c5fc272cb9d96b46b5498402 3.4.1-beta12
|
||||
e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release
|
||||
81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
|
||||
cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
|
||||
c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
|
||||
4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
|
||||
78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
|
||||
248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
|
||||
de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
|
||||
34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
|
||||
6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
|
||||
7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
|
||||
b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
|
||||
32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217
|
||||
704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1
|
||||
|
|
|
|||
10
BuildParams
10
BuildParams
|
|
@ -3,6 +3,7 @@
|
|||
# Please refer to:
|
||||
# https://wiki.secondlife.com/wiki/Automated_Build_System
|
||||
|
||||
|
||||
# Global setting for now...
|
||||
Darwin.symbolfiles = "newview/Release/secondlife-symbols-darwin.tar.bz2"
|
||||
CYGWIN.symbolfiles = "newview/Release/secondlife-symbols-windows.tar.bz2"
|
||||
|
|
@ -20,8 +21,13 @@ email_status_this_is_os = true
|
|||
# Limit extent of codeticket updates to revisions after...
|
||||
codeticket_since = 3.3.0-release
|
||||
|
||||
clean_on_success = false
|
||||
run_tests = false
|
||||
build_Darwin_Debug = false
|
||||
build_Darwin_RelWithDebInfo = false
|
||||
|
||||
# ========================================
|
||||
# Viewer Development
|
||||
# Viewer Development --
|
||||
# ========================================
|
||||
|
||||
# Report changes since...
|
||||
|
|
@ -58,6 +64,7 @@ viewer-release.build_debug_release_separately = true
|
|||
viewer-release.build_viewer_update_version_manager = true
|
||||
viewer-release.codeticket_add_context = false
|
||||
|
||||
|
||||
# ========================================
|
||||
# mesh-development
|
||||
# ========================================
|
||||
|
|
@ -197,4 +204,5 @@ runway.build_debug_release_separately = true
|
|||
runway.build_CYGWIN_Debug = false
|
||||
runway.build_viewer_update_version_manager = false
|
||||
|
||||
|
||||
# eof
|
||||
|
|
|
|||
|
|
@ -1062,9 +1062,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>d91e1f483209cd3eba04135c6a59e829</string>
|
||||
<string>a5b2dff0d97b643227a58473e5c57906</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/221672/arch/Darwin/installer/kdu-6.4.1-darwin-20110218.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/256978/arch/Darwin/installer/kdu-7.0.0-darwin-20120515.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin</string>
|
||||
|
|
@ -1086,9 +1086,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>6cd9f36465ef73a3df34bf2b3bba2ced</string>
|
||||
<string>6d80d35524e1c0c32d3385014d02d48c</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/221672/arch/CYGWIN/installer/kdu-6.4.1-windows-20110218.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/256978/arch/CYGWIN/installer/kdu-7.0.0-windows-20120515.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -2183,6 +2183,8 @@
|
|||
<array>
|
||||
<string>-configuration Release</string>
|
||||
<string>-project SecondLife.xcodeproj</string>
|
||||
<string>-DENABLE_SIGNING:BOOL=YES</string>
|
||||
<string>-DSIGNING_IDENTITY:STRING="Developer ID Application: Linden Research, Inc."</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -2210,6 +2212,8 @@
|
|||
<array>
|
||||
<string>-configuration Release</string>
|
||||
<string>-project SecondLife.xcodeproj</string>
|
||||
<string>-DENABLE_SIGNING:BOOL=YES</string>
|
||||
<string>-DSIGNING_IDENTITY:STRING="Developer ID Application: Linden Research, Inc."</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -2459,6 +2463,18 @@
|
|||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>..\indra</string>
|
||||
<string>&&</string>
|
||||
<string>..\indra\tools\vstool\VSTool.exe</string>
|
||||
<string>--solution</string>
|
||||
<string>SecondLife.sln</string>
|
||||
<string>--config</string>
|
||||
<string>Debug</string>
|
||||
<string>--startup</string>
|
||||
<string>secondlife-bin</string>
|
||||
</array>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-G</string>
|
||||
|
|
@ -2535,6 +2551,18 @@
|
|||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>..\indra</string>
|
||||
<string>&&</string>
|
||||
<string>..\indra\tools\vstool\VSTool.exe</string>
|
||||
<string>--solution</string>
|
||||
<string>SecondLife.sln</string>
|
||||
<string>--config</string>
|
||||
<string>RelWithDebInfo</string>
|
||||
<string>--startup</string>
|
||||
<string>secondlife-bin</string>
|
||||
</array>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-G</string>
|
||||
|
|
@ -2611,6 +2639,18 @@
|
|||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>..\indra</string>
|
||||
<string>&&</string>
|
||||
<string>..\indra\tools\vstool\VSTool.exe</string>
|
||||
<string>--solution</string>
|
||||
<string>SecondLife.sln</string>
|
||||
<string>--config</string>
|
||||
<string>Release</string>
|
||||
<string>--startup</string>
|
||||
<string>secondlife-bin</string>
|
||||
</array>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>-G</string>
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ Ansariel Hiller
|
|||
VWR-26150
|
||||
STORM-1685
|
||||
STORM-1713
|
||||
STORM-1899
|
||||
Aralara Rajal
|
||||
Ardy Lay
|
||||
STORM-859
|
||||
|
|
@ -400,6 +401,7 @@ Gaberoonie Zanzibar
|
|||
Ganymedes Costagravas
|
||||
Geenz Spad
|
||||
STORM-1823
|
||||
STORM-1900
|
||||
Gene Frostbite
|
||||
GeneJ Composer
|
||||
Geneko Nemeth
|
||||
|
|
@ -636,6 +638,7 @@ Jonathan Yap
|
|||
STORM-1809
|
||||
STORM-1793
|
||||
STORM-1810
|
||||
STORM-1877
|
||||
STORM-1860
|
||||
STORM-1852
|
||||
STORM-1870
|
||||
|
|
@ -644,6 +647,7 @@ Jonathan Yap
|
|||
STORM-1862
|
||||
Kadah Coba
|
||||
STORM-1060
|
||||
STORM-1843
|
||||
Jondan Lundquist
|
||||
Josef Munster
|
||||
Josette Windlow
|
||||
|
|
@ -654,6 +658,8 @@ Kage Pixel
|
|||
VWR-11
|
||||
Kagehi Kohn
|
||||
Kaimen Takahe
|
||||
Katharine Berry
|
||||
STORM-1900
|
||||
Keklily Longfall
|
||||
Ken Lavender
|
||||
Ken March
|
||||
|
|
@ -739,6 +745,7 @@ Marianne McCann
|
|||
Marine Kelley
|
||||
STORM-281
|
||||
MartinRJ Fayray
|
||||
STORM-1844
|
||||
STORM-1845
|
||||
Matthew Anthony
|
||||
Matthew Dowd
|
||||
|
|
@ -1108,9 +1115,12 @@ Sudane Erato
|
|||
Synystyr Texan
|
||||
Takeda Terrawyng
|
||||
TankMaster Finesmith
|
||||
OPEN-140
|
||||
OPEN-142
|
||||
STORM-1100
|
||||
STORM-1602
|
||||
STORM-1258
|
||||
STORM-1602
|
||||
STORM-1868
|
||||
VWR-26622
|
||||
Talamasca
|
||||
Tali Rosca
|
||||
|
|
@ -1228,6 +1238,8 @@ Watty Berkson
|
|||
Westley Schridde
|
||||
Westley Streeter
|
||||
Whimsy Winx
|
||||
Whirly Fizzle
|
||||
STORM-1895
|
||||
Whoops Babii
|
||||
VWR-631
|
||||
VWR-1640
|
||||
|
|
|
|||
|
|
@ -385,14 +385,6 @@
|
|||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>ParcelMediaURLFilter</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>false</boolean>
|
||||
</map>
|
||||
|
||||
<key>ParcelNavigateMedia</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ if (WINDOWS)
|
|||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||
CACHE STRING "C++ compiler release options" FORCE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE")
|
||||
|
||||
set(CMAKE_CXX_STANDARD_LIBRARIES "")
|
||||
set(CMAKE_C_STANDARD_LIBRARIES "")
|
||||
|
|
@ -199,13 +200,17 @@ if (DARWIN)
|
|||
add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
|
||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
|
||||
set(DARWIN_extra_cstar_flags "-mlong-branch")
|
||||
set(DARWIN_extra_cstar_flags "-mlong-branch -g")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DARWIN_extra_cstar_flags}")
|
||||
# NOTE: it's critical that the optimization flag is put in front.
|
||||
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
if (XCODE_VERSION GREATER 4.2)
|
||||
set(ENABLE_SIGNING TRUE)
|
||||
set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.")
|
||||
endif (XCODE_VERSION GREATER 4.2)
|
||||
endif (DARWIN)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ include(Prebuilt)
|
|||
|
||||
# If you want to enable or disable TCMALLOC in viewer builds, this is the place.
|
||||
# set ON or OFF as desired.
|
||||
set (USE_TCMALLOC OFF)
|
||||
set (USE_TCMALLOC ON)
|
||||
|
||||
if (STANDALONE)
|
||||
include(FindGooglePerfTools)
|
||||
|
|
|
|||
|
|
@ -99,10 +99,20 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(DARWIN 1)
|
||||
|
||||
execute_process(
|
||||
COMMAND sh -c "xcodebuild -version | grep Xcode | cut -d ' ' -f2 | cut -d'.' -f1-2"
|
||||
OUTPUT_VARIABLE XCODE_VERSION )
|
||||
|
||||
# To support a different SDK update these Xcode settings:
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
|
||||
if (XCODE_VERSION GREATER 4.2)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
|
||||
else (XCODE_VERSION GREATER 4.2)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
|
||||
endif (XCODE_VERSION GREATER 4.2)
|
||||
|
||||
set(CMAKE_OSX_SYSROOT macosx10.6)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvmgcc42")
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
|
||||
|
||||
# NOTE: To attempt an i386/PPC Universal build, add this on the configure line:
|
||||
|
|
@ -134,6 +144,11 @@ set(VIEWER ON CACHE BOOL "Build Second Life viewer.")
|
|||
set(VIEWER_CHANNEL "LindenDeveloper" CACHE STRING "Viewer Channel Name")
|
||||
set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing")
|
||||
|
||||
if (XCODE_VERSION GREATER 4.2)
|
||||
set(ENABLE_SIGNING OFF CACHE BOOL "Enable signing the viewer")
|
||||
set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.")
|
||||
endif (XCODE_VERSION GREATER 4.2)
|
||||
|
||||
set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
|
||||
set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")
|
||||
set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
|
||||
|
|
|
|||
|
|
@ -167,7 +167,12 @@ ARGUMENTS=[
|
|||
dict(name='version',
|
||||
description="""This specifies the version of Second Life that is
|
||||
being packaged up.""",
|
||||
default=get_default_version)
|
||||
default=get_default_version),
|
||||
dict(name='signature',
|
||||
description="""This specifies an identity to sign the viewer with, if any.
|
||||
If no value is supplied, the default signature will be used, if any. Currently
|
||||
only used on Mac OS X.""",
|
||||
default=None)
|
||||
]
|
||||
|
||||
def usage(srctree=""):
|
||||
|
|
|
|||
|
|
@ -132,18 +132,68 @@ BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask)
|
|||
{
|
||||
if (mNewPose != HAND_POSE_RELAXED && mNewPose != mCurrentPose)
|
||||
{
|
||||
mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
|
||||
// Only set param weight for poses other than
|
||||
// default (HAND_POSE_SPREAD); HAND_POSE_SPREAD
|
||||
// is not an animatable morph!
|
||||
if (mNewPose != HAND_POSE_SPREAD)
|
||||
{
|
||||
mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
|
||||
}
|
||||
|
||||
// Reset morph weight for current pose back to its
|
||||
// full extend or it might be stuck somewhere in the middle if a
|
||||
// pose is requested and the old pose is requested again shortly
|
||||
// after while still blending to the other pose!
|
||||
if (mCurrentPose != HAND_POSE_SPREAD)
|
||||
{
|
||||
mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
|
||||
}
|
||||
|
||||
// Update visual params now if we won't blend
|
||||
if (mCurrentPose == HAND_POSE_RELAXED)
|
||||
{
|
||||
mCharacter->updateVisualParams();
|
||||
}
|
||||
}
|
||||
mNewPose = HAND_POSE_RELAXED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is a new morph we didn't know about before
|
||||
if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose && mNewPose != HAND_POSE_SPREAD)
|
||||
// Sometimes we seem to get garbage here, with poses that are out of bounds.
|
||||
// So check for a valid pose first.
|
||||
if (*requestedHandPose >= 0 && *requestedHandPose < NUM_HAND_POSES)
|
||||
{
|
||||
mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
|
||||
// This is a new morph we didn't know about before:
|
||||
// Reset morph weight for both current and new pose
|
||||
// back their starting values while still blending.
|
||||
if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose)
|
||||
{
|
||||
if (mNewPose != HAND_POSE_SPREAD)
|
||||
{
|
||||
mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
|
||||
}
|
||||
|
||||
// Reset morph weight for current pose back to its full extend
|
||||
// or it might be stuck somewhere in the middle if a pose is
|
||||
// requested and the old pose is requested again shortly after
|
||||
// while still blending to the other pose!
|
||||
if (mCurrentPose != HAND_POSE_SPREAD)
|
||||
{
|
||||
mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
|
||||
}
|
||||
|
||||
// Update visual params now if we won't blend
|
||||
if (mCurrentPose == *requestedHandPose)
|
||||
{
|
||||
mCharacter->updateVisualParams();
|
||||
}
|
||||
}
|
||||
mNewPose = *requestedHandPose;
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Requested hand pose out of range. Ignoring requested pose." << llendl;
|
||||
}
|
||||
mNewPose = *requestedHandPose;
|
||||
}
|
||||
|
||||
mCharacter->removeAnimationData("Hand Pose");
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ set(llcommon_HEADER_FILES
|
|||
llfoldertype.h
|
||||
llformat.h
|
||||
llframetimer.h
|
||||
llhandle.h
|
||||
llhash.h
|
||||
llheartbeat.h
|
||||
llhttpstatuscodes.h
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ enum LAND_STAT_FLAGS
|
|||
STAT_FILTER_BY_PARCEL = 0x00000001,
|
||||
STAT_FILTER_BY_OWNER = 0x00000002,
|
||||
STAT_FILTER_BY_OBJECT = 0x00000004,
|
||||
STAT_FILTER_BY_PARCEL_NAME = 0x00000008,
|
||||
STAT_REQUEST_LAST_ENTRY = 0x80000000,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@
|
|||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
/**
|
||||
* Helper object for LLHandle. Don't instantiate these directly, used
|
||||
* exclusively by LLHandle.
|
||||
*/
|
||||
class LLTombStone : public LLRefCount
|
||||
{
|
||||
public:
|
||||
|
|
@ -42,15 +46,37 @@ private:
|
|||
mutable void* mTarget;
|
||||
};
|
||||
|
||||
// LLHandles are used to refer to objects whose lifetime you do not control or influence.
|
||||
// Calling get() on a handle will return a pointer to the referenced object or NULL,
|
||||
// if the object no longer exists. Note that during the lifetime of the returned pointer,
|
||||
// you are assuming that the object will not be deleted by any action you perform,
|
||||
// or any other thread, as normal when using pointers, so avoid using that pointer outside of
|
||||
// the local code block.
|
||||
//
|
||||
// https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
|
||||
|
||||
/**
|
||||
* LLHandles are used to refer to objects whose lifetime you do not control or influence.
|
||||
* Calling get() on a handle will return a pointer to the referenced object or NULL,
|
||||
* if the object no longer exists. Note that during the lifetime of the returned pointer,
|
||||
* you are assuming that the object will not be deleted by any action you perform,
|
||||
* or any other thread, as normal when using pointers, so avoid using that pointer outside of
|
||||
* the local code block.
|
||||
*
|
||||
* https://wiki.lindenlab.com/mediawiki/index.php?title=LLHandle&oldid=79669
|
||||
*
|
||||
* The implementation is like some "weak pointer" implementations. When we
|
||||
* can't control the lifespan of the referenced object of interest, we can
|
||||
* still instantiate a proxy object whose lifespan we DO control, and store in
|
||||
* the proxy object a dumb pointer to the actual target. Then we just have to
|
||||
* ensure that on destruction of the target object, the proxy's dumb pointer
|
||||
* is set NULL.
|
||||
*
|
||||
* LLTombStone is our proxy object. LLHandle contains an LLPointer to the
|
||||
* LLTombStone, so every copy of an LLHandle increments the LLTombStone's ref
|
||||
* count as usual.
|
||||
*
|
||||
* One copy of the LLHandle, specifically the LLRootHandle, must be stored in
|
||||
* the referenced object. Destroying the LLRootHandle is what NULLs the
|
||||
* proxy's target pointer.
|
||||
*
|
||||
* Minor optimization: we want LLHandle's mTombStone to always be a valid
|
||||
* LLPointer, saving some conditionals in dereferencing. That's the
|
||||
* getDefaultTombStone() mechanism. The default LLTombStone object's target
|
||||
* pointer is always NULL, so it's semantically identical to allowing
|
||||
* mTombStone to be invalid.
|
||||
*/
|
||||
template <typename T>
|
||||
class LLHandle
|
||||
{
|
||||
|
|
@ -108,6 +134,14 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LLRootHandle isa LLHandle which must be stored in the referenced object.
|
||||
* You can either store it directly and explicitly bind(this), or derive from
|
||||
* LLHandleProvider (q.v.) which automates that for you. The essential point
|
||||
* is that destroying the LLRootHandle (as a consequence of destroying the
|
||||
* referenced object) calls unbind(), setting the LLTombStone's target pointer
|
||||
* NULL.
|
||||
*/
|
||||
template <typename T>
|
||||
class LLRootHandle : public LLHandle<T>
|
||||
{
|
||||
|
|
@ -144,8 +178,10 @@ private:
|
|||
LLRootHandle(const LLRootHandle& other) {};
|
||||
};
|
||||
|
||||
// Use this as a mixin for simple classes that need handles and when you don't
|
||||
// want handles at multiple points of the inheritance hierarchy
|
||||
/**
|
||||
* Use this as a mixin for simple classes that need handles and when you don't
|
||||
* want handles at multiple points of the inheritance hierarchy
|
||||
*/
|
||||
template <typename T>
|
||||
class LLHandleProvider
|
||||
{
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "llerror.h"
|
||||
#include "lltypeinfolookup.h"
|
||||
#include "llstl.h"
|
||||
|
||||
namespace LLInitParam
|
||||
{
|
||||
|
|
@ -212,14 +212,6 @@ namespace LLInitParam
|
|||
|
||||
public:
|
||||
|
||||
struct CompareTypeID
|
||||
{
|
||||
bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
|
||||
{
|
||||
return lhs->before(*rhs);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<std::pair<std::string, bool> > name_stack_t;
|
||||
typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t;
|
||||
typedef std::vector<std::string> possible_values_t;
|
||||
|
|
@ -228,9 +220,9 @@ namespace LLInitParam
|
|||
typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
|
||||
typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
|
||||
|
||||
typedef LLTypeInfoLookup<parser_read_func_t> parser_read_func_map_t;
|
||||
typedef LLTypeInfoLookup<parser_write_func_t> parser_write_func_map_t;
|
||||
typedef LLTypeInfoLookup<parser_inspect_func_t> parser_inspect_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_read_func_t> parser_read_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
|
||||
|
||||
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
|
||||
: mParseSilently(false),
|
||||
|
|
|
|||
|
|
@ -87,7 +87,11 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r
|
|||
void* ret = ll_aligned_malloc_16(size);
|
||||
if (ptr)
|
||||
{
|
||||
memcpy(ret, ptr, old_size);
|
||||
if (ret)
|
||||
{
|
||||
// Only copy the size of the smallest memory block to avoid memory corruption.
|
||||
memcpy(ret, ptr, llmin(old_size, size));
|
||||
}
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -31,30 +31,16 @@
|
|||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include "llsingleton.h"
|
||||
#include "lltypeinfolookup.h"
|
||||
#include "llstl.h"
|
||||
|
||||
template <typename T>
|
||||
class LLRegistryDefaultComparator
|
||||
struct LLRegistryDefaultComparator
|
||||
{
|
||||
bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; }
|
||||
};
|
||||
|
||||
template <typename KEY, typename VALUE>
|
||||
struct LLRegistryMapSelector
|
||||
{
|
||||
typedef std::map<KEY, VALUE> type;
|
||||
};
|
||||
|
||||
template <typename VALUE>
|
||||
struct LLRegistryMapSelector<std::type_info*, VALUE>
|
||||
{
|
||||
typedef LLTypeInfoLookup<VALUE> type;
|
||||
};
|
||||
|
||||
template <typename VALUE>
|
||||
struct LLRegistryMapSelector<const std::type_info*, VALUE>
|
||||
{
|
||||
typedef LLTypeInfoLookup<VALUE> type;
|
||||
bool operator()(const T& lhs, const T& rhs) const
|
||||
{
|
||||
using std::less;
|
||||
return less<T>()(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
|
||||
|
|
@ -72,7 +58,7 @@ public:
|
|||
{
|
||||
friend class LLRegistry<KEY, VALUE, COMPARATOR>;
|
||||
public:
|
||||
typedef typename LLRegistryMapSelector<KEY, VALUE>::type registry_map_t;
|
||||
typedef std::map<KEY, VALUE, COMPARATOR> registry_map_t;
|
||||
|
||||
bool add(ref_const_key_t key, ref_const_value_t value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include <vector>
|
||||
#include <set>
|
||||
#include <deque>
|
||||
#include <typeinfo>
|
||||
|
||||
// Use to compare the first element only of a pair
|
||||
// e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t;
|
||||
|
|
@ -470,4 +471,54 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
|
|||
return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare std::type_info* pointers a la std::less. We break this out as a
|
||||
* separate function for use in two different std::less specializations.
|
||||
*/
|
||||
inline
|
||||
bool before(const std::type_info* lhs, const std::type_info* rhs)
|
||||
{
|
||||
#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
|
||||
// If we're building on Linux with gcc, and it's either gcc 3.x or
|
||||
// 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on
|
||||
// Mac too, and some people build with gcc on Windows (cygwin or mingw).
|
||||
// On Linux, different load modules may produce different type_info*
|
||||
// pointers for the same type. Have to compare name strings to get good
|
||||
// results.
|
||||
return strcmp(lhs->name(), rhs->name()) < 0;
|
||||
#else // not Linux, or gcc 4.4+
|
||||
// Just use before(), as we normally would
|
||||
return lhs->before(*rhs);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialize std::less<std::type_info*> to use std::type_info::before().
|
||||
* See MAINT-1175. It is NEVER a good idea to directly compare std::type_info*
|
||||
* because, on Linux, you might get different std::type_info* pointers for the
|
||||
* same type (from different load modules)!
|
||||
*/
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct less<const std::type_info*>:
|
||||
public std::binary_function<const std::type_info*, const std::type_info*, bool>
|
||||
{
|
||||
bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
|
||||
{
|
||||
return before(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct less<std::type_info*>:
|
||||
public std::binary_function<std::type_info*, std::type_info*, bool>
|
||||
{
|
||||
bool operator()(std::type_info* lhs, std::type_info* rhs) const
|
||||
{
|
||||
return before(lhs, rhs);
|
||||
}
|
||||
};
|
||||
} // std
|
||||
|
||||
#endif // LL_LLSTL_H
|
||||
|
|
|
|||
|
|
@ -12,9 +12,49 @@
|
|||
#if ! defined(LL_LLTYPEINFOLOOKUP_H)
|
||||
#define LL_LLTYPEINFOLOOKUP_H
|
||||
|
||||
#include "llsortedvector.h"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <functional> // std::binary_function
|
||||
#include <typeinfo>
|
||||
|
||||
/**
|
||||
* The following helper classes are based on the Boost.Unordered documentation:
|
||||
* http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compute hash for a string passed as const char*
|
||||
*/
|
||||
struct const_char_star_hash: public std::unary_function<const char*, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const char* str) const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
for ( ; *str; ++str)
|
||||
{
|
||||
boost::hash_combine(seed, *str);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute equality for strings passed as const char*
|
||||
*
|
||||
* I (nat) suspect that this is where the default behavior breaks for the
|
||||
* const char* values returned from std::type_info::name(). If you compare the
|
||||
* two const char* pointer values, as a naive, unspecialized implementation
|
||||
* will surely do, they'll compare unequal.
|
||||
*/
|
||||
struct const_char_star_equal: public std::binary_function<const char*, const char*, bool>
|
||||
{
|
||||
bool operator()(const char* lhs, const char* rhs) const
|
||||
{
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LLTypeInfoLookup is specifically designed for use cases for which you might
|
||||
* consider std::map<std::type_info*, VALUE>. We have several such data
|
||||
|
|
@ -23,88 +63,55 @@
|
|||
* different load modules will produce different std::type_info*.
|
||||
* LLTypeInfoLookup contains a workaround to address this issue.
|
||||
*
|
||||
* Specifically, when we don't find the passed std::type_info*,
|
||||
* LLTypeInfoLookup performs a linear search over registered entries to
|
||||
* compare name() strings. Presuming that this succeeds, we cache the new
|
||||
* (previously unrecognized) std::type_info* to speed future lookups.
|
||||
*
|
||||
* This worst-case fallback search (linear search with string comparison)
|
||||
* should only happen the first time we look up a given type from a particular
|
||||
* load module other than the one from which we initially registered types.
|
||||
* (However, a lookup which wouldn't succeed anyway will always have
|
||||
* worst-case performance.) This class is probably best used with less than a
|
||||
* few dozen different types.
|
||||
* The API deliberately diverges from std::map in several respects:
|
||||
* * It avoids iterators, not only begin()/end() but also as return values
|
||||
* from insert() and find(). This bypasses transform_iterator overhead.
|
||||
* * Since we literally use compile-time types as keys, the essential insert()
|
||||
* and find() methods accept the key type as a @em template parameter,
|
||||
* accepting and returning value_type as a normal runtime value. This is to
|
||||
* permit future optimization (e.g. compile-time type hashing) without
|
||||
* changing the API.
|
||||
*/
|
||||
template <typename VALUE>
|
||||
class LLTypeInfoLookup
|
||||
{
|
||||
// Use this for our underlying implementation: lookup by
|
||||
// std::type_info::name() string. This is one of the rare cases in which I
|
||||
// dare use const char* directly, rather than std::string, because I'm
|
||||
// sure that every value returned by std::type_info::name() is static.
|
||||
// HOWEVER, specify our own hash + equality functors: naively comparing
|
||||
// distinct const char* values won't work.
|
||||
typedef boost::unordered_map<const char*, VALUE,
|
||||
const_char_star_hash, const_char_star_equal> impl_map_type;
|
||||
|
||||
public:
|
||||
typedef LLTypeInfoLookup<VALUE> self;
|
||||
typedef LLSortedVector<const std::type_info*, VALUE> vector_type;
|
||||
typedef typename vector_type::key_type key_type;
|
||||
typedef typename vector_type::mapped_type mapped_type;
|
||||
typedef typename vector_type::value_type value_type;
|
||||
typedef typename vector_type::iterator iterator;
|
||||
typedef typename vector_type::const_iterator const_iterator;
|
||||
typedef VALUE value_type;
|
||||
|
||||
LLTypeInfoLookup() {}
|
||||
|
||||
iterator begin() { return mVector.begin(); }
|
||||
iterator end() { return mVector.end(); }
|
||||
const_iterator begin() const { return mVector.begin(); }
|
||||
const_iterator end() const { return mVector.end(); }
|
||||
bool empty() const { return mVector.empty(); }
|
||||
std::size_t size() const { return mVector.size(); }
|
||||
bool empty() const { return mMap.empty(); }
|
||||
std::size_t size() const { return mMap.size(); }
|
||||
|
||||
std::pair<iterator, bool> insert(const std::type_info* key, const VALUE& value)
|
||||
template <typename KEY>
|
||||
bool insert(const value_type& value)
|
||||
{
|
||||
return insert(value_type(key, value));
|
||||
// Obtain and store the std::type_info::name() string as the key.
|
||||
// Return just the bool from std::map::insert()'s return pair.
|
||||
return mMap.insert(typename impl_map_type::value_type(typeid(KEY).name(), value)).second;
|
||||
}
|
||||
|
||||
std::pair<iterator, bool> insert(const value_type& pair)
|
||||
template <typename KEY>
|
||||
boost::optional<value_type> find() const
|
||||
{
|
||||
return mVector.insert(pair);
|
||||
}
|
||||
|
||||
// const find() forwards to non-const find(): this can alter mVector!
|
||||
const_iterator find(const std::type_info* key) const
|
||||
{
|
||||
return const_cast<self*>(this)->find(key);
|
||||
}
|
||||
|
||||
// non-const find() caches previously-unknown type_info* to speed future
|
||||
// lookups.
|
||||
iterator find(const std::type_info* key)
|
||||
{
|
||||
iterator found = mVector.find(key);
|
||||
if (found != mVector.end())
|
||||
{
|
||||
// If LLSortedVector::find() found, great, we're done.
|
||||
return found;
|
||||
}
|
||||
// Here we didn't find the passed type_info*. On Linux, though, even
|
||||
// for the same type, typeid(sametype) produces a different type_info*
|
||||
// when used in different load modules. So the fact that we didn't
|
||||
// find the type_info* we seek doesn't mean this type isn't
|
||||
// registered. Scan for matching name() string.
|
||||
for (typename vector_type::iterator ti(mVector.begin()), tend(mVector.end());
|
||||
ti != tend; ++ti)
|
||||
{
|
||||
if (std::string(ti->first->name()) == key->name())
|
||||
{
|
||||
// This unrecognized 'key' is for the same type as ti->first.
|
||||
// To speed future lookups, insert a new entry that lets us
|
||||
// look up ti->second using this same 'key'.
|
||||
return insert(key, ti->second).first;
|
||||
}
|
||||
}
|
||||
// We simply have never seen a type with this type_info* from any load
|
||||
// module.
|
||||
return mVector.end();
|
||||
// Use the std::type_info::name() string as the key.
|
||||
typename impl_map_type::const_iterator found = mMap.find(typeid(KEY).name());
|
||||
if (found == mMap.end())
|
||||
return boost::optional<value_type>();
|
||||
return found->second;
|
||||
}
|
||||
|
||||
private:
|
||||
vector_type mVector;
|
||||
impl_map_type mMap;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
const S32 LL_VERSION_MAJOR = 3;
|
||||
const S32 LL_VERSION_MINOR = 4;
|
||||
const S32 LL_VERSION_PATCH = 1;
|
||||
const S32 LL_VERSION_PATCH = 3;
|
||||
const S32 LL_VERSION_BUILD = 0;
|
||||
|
||||
const char * const LL_CHANNEL = "Second Life Developer";
|
||||
|
|
|
|||
|
|
@ -292,11 +292,16 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
|
|||
++sRawImageCount;
|
||||
}
|
||||
|
||||
LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)
|
||||
LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy)
|
||||
: LLImageBase()
|
||||
{
|
||||
mMemType = LLMemType::MTYPE_IMAGERAW;
|
||||
if(allocateDataSize(width, height, components))
|
||||
|
||||
if(no_copy)
|
||||
{
|
||||
setDataAndSize(data, width, height, components);
|
||||
}
|
||||
else if(allocateDataSize(width, height, components))
|
||||
{
|
||||
memcpy(getData(), data, width*height*components);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ protected:
|
|||
public:
|
||||
LLImageRaw();
|
||||
LLImageRaw(U16 width, U16 height, S8 components);
|
||||
LLImageRaw(U8 *data, U16 width, U16 height, S8 components);
|
||||
LLImageRaw(U8 *data, U16 width, U16 height, S8 components, bool no_copy = false);
|
||||
// Construct using createFromFile (used by tools)
|
||||
//LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only = false);
|
||||
|
||||
|
|
|
|||
|
|
@ -193,8 +193,6 @@ void LLParcel::init(const LLUUID &owner_id,
|
|||
mMediaWidth = 0;
|
||||
mMediaHeight = 0;
|
||||
setMediaCurrentURL(LLStringUtil::null);
|
||||
mMediaURLFilterEnable = FALSE;
|
||||
mMediaURLFilterList = LLSD::emptyArray();
|
||||
mMediaAllowNavigate = TRUE;
|
||||
mMediaURLTimeout = 0.0f;
|
||||
mMediaPreventCameraZoom = FALSE;
|
||||
|
|
@ -336,38 +334,6 @@ void LLParcel::setMediaURLResetTimer(F32 time)
|
|||
mMediaResetTimer.setTimerExpirySec(time);
|
||||
}
|
||||
|
||||
void LLParcel::setMediaURLFilterList(LLSD list)
|
||||
{
|
||||
// sanity check LLSD
|
||||
// must be array of strings
|
||||
if (!list.isArray())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < list.size(); i++)
|
||||
{
|
||||
if (!list[i].isString())
|
||||
return;
|
||||
}
|
||||
|
||||
// can't be too big
|
||||
const S32 MAX_SIZE = 50;
|
||||
if (list.size() > MAX_SIZE)
|
||||
{
|
||||
LLSD new_list = LLSD::emptyArray();
|
||||
|
||||
for (S32 i = 0; i < llmin(list.size(), MAX_SIZE); i++)
|
||||
{
|
||||
new_list.append(list[i]);
|
||||
}
|
||||
|
||||
list = new_list;
|
||||
}
|
||||
|
||||
mMediaURLFilterList = list;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLParcel::setLocalID(S32 local_id)
|
||||
{
|
||||
|
|
@ -622,34 +588,6 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr
|
|||
return input_stream.good();
|
||||
}
|
||||
|
||||
BOOL LLParcel::importMediaURLFilter(std::istream& input_stream, std::string& url)
|
||||
{
|
||||
skip_to_end_of_next_keyword("{", input_stream);
|
||||
|
||||
while(input_stream.good())
|
||||
{
|
||||
skip_comments_and_emptyspace(input_stream);
|
||||
std::string line, keyword, value;
|
||||
get_line(line, input_stream, MAX_STRING);
|
||||
get_keyword_and_value(keyword, value, line);
|
||||
|
||||
if ("}" == keyword)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if ("url" == keyword)
|
||||
{
|
||||
url = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Unknown keyword in parcel media url filter section: <"
|
||||
<< keyword << ">" << llendl;
|
||||
}
|
||||
}
|
||||
return input_stream.good();
|
||||
}
|
||||
|
||||
// Assumes we are in a block "ParcelData"
|
||||
void LLParcel::packMessage(LLMessageSystem* msg)
|
||||
{
|
||||
|
|
@ -696,8 +634,6 @@ void LLParcel::packMessage(LLSD& msg)
|
|||
msg["media_allow_navigate"] = getMediaAllowNavigate();
|
||||
msg["media_prevent_camera_zoom"] = getMediaPreventCameraZoom();
|
||||
msg["media_url_timeout"] = getMediaURLTimeout();
|
||||
msg["media_url_filter_enable"] = getMediaURLFilterEnable();
|
||||
msg["media_url_filter_list"] = getMediaURLFilterList();
|
||||
msg["group_id"] = getGroupID();
|
||||
msg["pass_price"] = mPassPrice;
|
||||
msg["pass_hours"] = mPassHours;
|
||||
|
|
@ -789,7 +725,6 @@ void LLParcel::unpackMessage(LLMessageSystem* msg)
|
|||
msg->getString("MediaLinkSharing", "MediaCurrentURL", buffer);
|
||||
setMediaCurrentURL(buffer);
|
||||
msg->getU8 ( "MediaLinkSharing", "MediaAllowNavigate", mMediaAllowNavigate );
|
||||
msg->getU8 ( "MediaLinkSharing", "MediaURLFilterEnable", mMediaURLFilterEnable );
|
||||
msg->getU8 ( "MediaLinkSharing", "MediaPreventCameraZoom", mMediaPreventCameraZoom );
|
||||
msg->getF32( "MediaLinkSharing", "MediaURLTimeout", mMediaURLTimeout);
|
||||
}
|
||||
|
|
@ -1250,8 +1185,6 @@ void LLParcel::clearParcel()
|
|||
mMediaWidth = 0;
|
||||
mMediaHeight = 0;
|
||||
setMediaCurrentURL(LLStringUtil::null);
|
||||
setMediaURLFilterList(LLSD::emptyArray());
|
||||
setMediaURLFilterEnable(FALSE);
|
||||
setMediaAllowNavigate(TRUE);
|
||||
setMediaPreventCameraZoom(FALSE);
|
||||
setMediaURLTimeout(0.0f);
|
||||
|
|
|
|||
|
|
@ -247,8 +247,6 @@ public:
|
|||
void setMediaWidth(S32 width);
|
||||
void setMediaHeight(S32 height);
|
||||
void setMediaCurrentURL(const std::string& url);
|
||||
void setMediaURLFilterEnable(U8 enable) { mMediaURLFilterEnable = enable; }
|
||||
void setMediaURLFilterList(LLSD list);
|
||||
void setMediaAllowNavigate(U8 enable) { mMediaAllowNavigate = enable; }
|
||||
void setMediaURLTimeout(F32 timeout) { mMediaURLTimeout = timeout; }
|
||||
void setMediaPreventCameraZoom(U8 enable) { mMediaPreventCameraZoom = enable; }
|
||||
|
|
@ -310,7 +308,6 @@ public:
|
|||
|
||||
// BOOL importStream(std::istream& input_stream);
|
||||
BOOL importAccessEntry(std::istream& input_stream, LLAccessEntry* entry);
|
||||
BOOL importMediaURLFilter(std::istream& input_stream, std::string& url);
|
||||
// BOOL exportStream(std::ostream& output_stream);
|
||||
|
||||
void packMessage(LLMessageSystem* msg);
|
||||
|
|
@ -354,8 +351,6 @@ public:
|
|||
U8 getMediaAutoScale() const { return mMediaAutoScale; }
|
||||
U8 getMediaLoop() const { return mMediaLoop; }
|
||||
const std::string& getMediaCurrentURL() const { return mMediaCurrentURL; }
|
||||
U8 getMediaURLFilterEnable() const { return mMediaURLFilterEnable; }
|
||||
LLSD getMediaURLFilterList() const { return mMediaURLFilterList; }
|
||||
U8 getMediaAllowNavigate() const { return mMediaAllowNavigate; }
|
||||
F32 getMediaURLTimeout() const { return mMediaURLTimeout; }
|
||||
U8 getMediaPreventCameraZoom() const { return mMediaPreventCameraZoom; }
|
||||
|
|
@ -651,8 +646,6 @@ protected:
|
|||
U8 mMediaLoop;
|
||||
std::string mMediaCurrentURL;
|
||||
LLUUID mMediaID;
|
||||
U8 mMediaURLFilterEnable;
|
||||
LLSD mMediaURLFilterList;
|
||||
U8 mMediaAllowNavigate;
|
||||
U8 mMediaPreventCameraZoom;
|
||||
F32 mMediaURLTimeout;
|
||||
|
|
|
|||
|
|
@ -1179,7 +1179,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)
|
|||
llassert(mDims == comp_dims); // Safety check; the caller has ensured this
|
||||
}
|
||||
bool use_shorts = (mComps[c].get_bit_depth(true) <= 16);
|
||||
mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts);
|
||||
mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts,0,0);
|
||||
if (res.which() == 0) // No DWT levels used
|
||||
{
|
||||
mEngines[c] = kdu_decoder(res.access_subband(LL_BAND),&mAllocator,use_shorts);
|
||||
|
|
@ -1223,7 +1223,7 @@ separation between consecutive rows in the real buffer. */
|
|||
{
|
||||
for (c = 0; c < mNumComponents; c++)
|
||||
{
|
||||
mEngines[c].pull(mLines[c],true);
|
||||
mEngines[c].pull(mLines[c]);
|
||||
}
|
||||
if ((mNumComponents >= 3) && mUseYCC)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
//
|
||||
// KDU core header files
|
||||
//
|
||||
#define KDU_NO_THREADS
|
||||
#include "kdu_elementary.h"
|
||||
#include "kdu_messaging.h"
|
||||
#include "kdu_params.h"
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#define LL_LLKDUMEM_H
|
||||
|
||||
// Support classes for reading and writing from memory buffers in KDU
|
||||
#define KDU_NO_THREADS
|
||||
#include "kdu_image.h"
|
||||
#include "kdu_elementary.h"
|
||||
#include "kdu_messaging.h"
|
||||
|
|
|
|||
|
|
@ -127,7 +127,6 @@ kdu_subband kdu_resolution::access_subband(int ) { kdu_subband a; return a; }
|
|||
void kdu_resolution::get_dims(kdu_dims& ) { }
|
||||
int kdu_resolution::which() { return 0; }
|
||||
int kdu_resolution::get_valid_band_indices(int &) { return 1; }
|
||||
kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { }
|
||||
kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { }
|
||||
kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { }
|
||||
kdu_params::~kdu_params() { }
|
||||
|
|
@ -153,7 +152,6 @@ void kdu_codestream::destroy() { }
|
|||
void kdu_codestream::collect_timing_stats(int ) { }
|
||||
void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { }
|
||||
void kdu_codestream::get_valid_tiles(kdu_dims& ) { }
|
||||
void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { }
|
||||
void kdu_codestream::create(kdu_compressed_source*, kdu_thread_env*) { }
|
||||
void kdu_codestream::apply_input_restrictions( int, int, int, int, kdu_dims*, kdu_component_access_mode ) { }
|
||||
void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { }
|
||||
|
|
@ -175,7 +173,7 @@ kdu_block* kdu_subband::open_block(kdu_coords, int*, kdu_thread_env*) { return N
|
|||
bool kdu_codestream_comment::put_text(const char*) { return false; }
|
||||
void kdu_customize_warnings(kdu_message*) { }
|
||||
void kdu_customize_errors(kdu_message*) { }
|
||||
void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { }
|
||||
|
||||
kdu_long kdu_multi_analysis::create(kdu_codestream, kdu_tile, bool, kdu_roi_image*, bool, int, kdu_thread_env*, kdu_thread_queue*, bool ) { kdu_long a = 0; return a; }
|
||||
siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { }
|
||||
void siz_params::finalize(bool ) { }
|
||||
|
|
@ -184,6 +182,21 @@ int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0;
|
|||
bool siz_params::check_marker_segment(kdu_uint16, int, kdu_byte a[], int&) { return false; }
|
||||
bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { return false; }
|
||||
|
||||
#ifdef LL_LINUX
|
||||
// Linux use the old pre KDU v7.0.0
|
||||
// *TODO: Supress this legacy stubbs once Linux migrates to v7.0.0
|
||||
kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { }
|
||||
void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long ) { }
|
||||
void kdu_convert_ycc_to_rgb(kdu_line_buf&, kdu_line_buf&, kdu_line_buf&, int) { }
|
||||
#else
|
||||
kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*, int) { }
|
||||
void kdu_codestream::create(siz_params*, kdu_compressed_target*, kdu_dims*, int, kdu_long, kdu_thread_env* ) { }
|
||||
void (*kdu_convert_ycc_to_rgb_rev16)(kdu_int16*,kdu_int16*,kdu_int16*,int);
|
||||
void (*kdu_convert_ycc_to_rgb_irrev16)(kdu_int16*,kdu_int16*,kdu_int16*,int);
|
||||
void (*kdu_convert_ycc_to_rgb_rev32)(kdu_int32*,kdu_int32*,kdu_int32*,int);
|
||||
void (*kdu_convert_ycc_to_rgb_irrev32)(float*,float*,float*,int);
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------------------------
|
||||
// TUT
|
||||
// -------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public:
|
|||
|
||||
typedef LLOctreeTraveler<T> oct_traveler;
|
||||
typedef LLTreeTraveler<T> tree_traveler;
|
||||
typedef LLPointer<T>* element_list;
|
||||
typedef std::vector<LLPointer<T> > element_list;
|
||||
typedef LLPointer<T>* element_iter;
|
||||
typedef const LLPointer<T>* const_element_iter;
|
||||
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
|
||||
|
|
@ -106,8 +106,9 @@ public:
|
|||
: mParent((oct_node*)parent),
|
||||
mOctant(octant)
|
||||
{
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
//always keep a NULL terminated list to avoid out of bounds exceptions in debug builds
|
||||
mData.push_back(NULL);
|
||||
mDataEnd = &mData[0];
|
||||
|
||||
mCenter = center;
|
||||
mSize = size;
|
||||
|
|
@ -133,9 +134,9 @@ public:
|
|||
mData[i] = NULL;
|
||||
}
|
||||
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
mData.clear();
|
||||
mData.push_back(NULL);
|
||||
mDataEnd = &mData[0];
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
|
|
@ -239,9 +240,9 @@ public:
|
|||
bool isEmpty() const { return mElementCount == 0; }
|
||||
element_list& getData() { return mData; }
|
||||
const element_list& getData() const { return mData; }
|
||||
element_iter getDataBegin() { return mData; }
|
||||
element_iter getDataBegin() { return &mData[0]; }
|
||||
element_iter getDataEnd() { return mDataEnd; }
|
||||
const_element_iter getDataBegin() const { return mData; }
|
||||
const_element_iter getDataBegin() const { return &mData[0]; }
|
||||
const_element_iter getDataEnd() const { return mDataEnd; }
|
||||
|
||||
U32 getChildCount() const { return mChildCount; }
|
||||
|
|
@ -321,14 +322,10 @@ public:
|
|||
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
|
||||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
||||
{ //it belongs here
|
||||
mData.push_back(NULL);
|
||||
mData[mElementCount] = data;
|
||||
mElementCount++;
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
//avoid unref on uninitialized memory
|
||||
memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
mDataEnd = &mData[mElementCount];
|
||||
data->setBinIndex(mElementCount-1);
|
||||
BaseType::insert(data);
|
||||
return true;
|
||||
|
|
@ -364,14 +361,10 @@ public:
|
|||
|
||||
if( lt == 0x7 )
|
||||
{
|
||||
mData.push_back(NULL);
|
||||
mData[mElementCount] = data;
|
||||
mElementCount++;
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
//avoid unref on uninitialized memory
|
||||
memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
mDataEnd = &mData[mElementCount];
|
||||
data->setBinIndex(mElementCount-1);
|
||||
BaseType::insert(data);
|
||||
return true;
|
||||
|
|
@ -436,16 +429,15 @@ public:
|
|||
mData[i]->setBinIndex(i);
|
||||
}
|
||||
|
||||
mData[mElementCount] = NULL; //needed for unref
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
mDataEnd = mData+mElementCount;
|
||||
mData[mElementCount] = NULL;
|
||||
mData.pop_back();
|
||||
mDataEnd = &mData[mElementCount];
|
||||
}
|
||||
else
|
||||
{
|
||||
mData[0] = NULL; //needed for unref
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
mData.clear();
|
||||
mData.push_back(NULL);
|
||||
mDataEnd = &mData[0];
|
||||
}
|
||||
|
||||
notifyRemoval(data);
|
||||
|
|
@ -491,7 +483,7 @@ public:
|
|||
}
|
||||
|
||||
//node is now root
|
||||
llwarns << "!!! OCTREE REMOVING FACE BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl;
|
||||
llwarns << "!!! OCTREE REMOVING ELEMENT BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl;
|
||||
node->removeByAddress(data);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ namespace LLAvatarNameCache
|
|||
/// Time when unrefreshed cached names were checked last
|
||||
static F64 sLastExpireCheck;
|
||||
|
||||
/// Time-to-live for a temp cache entry.
|
||||
const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Internal methods
|
||||
//-----------------------------------------------------------------------
|
||||
|
|
@ -274,7 +277,7 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
|
|||
{
|
||||
// there is no existing cache entry, so make a temporary name from legacy
|
||||
LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
|
||||
<< agent_id << LL_ENDL;
|
||||
<< agent_id << LL_ENDL;
|
||||
gCacheName->get(agent_id, false, // legacy compatibility
|
||||
boost::bind(&LLAvatarNameCache::legacyNameCallback,
|
||||
_1, _2, _3));
|
||||
|
|
@ -287,13 +290,14 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
|
|||
// Clear this agent from the pending list
|
||||
LLAvatarNameCache::sPendingQueue.erase(agent_id);
|
||||
|
||||
const LLAvatarName& av_name = existing->second;
|
||||
LLAvatarName& av_name = existing->second;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
|
||||
<< agent_id
|
||||
<< "user '" << av_name.mUsername << "' "
|
||||
<< "display '" << av_name.mDisplayName << "' "
|
||||
<< "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
|
||||
<< LL_ENDL;
|
||||
av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -402,10 +406,12 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
|
|||
<< LL_ENDL;
|
||||
buildLegacyName(full_name, &av_name);
|
||||
|
||||
// Don't add to cache, the data already exists in the legacy name system
|
||||
// cache and we don't want or need duplicate storage, because keeping the
|
||||
// two copies in sync is complex.
|
||||
processName(agent_id, av_name, false);
|
||||
// Add to cache, because if we don't we'll keep rerequesting the
|
||||
// same record forever. buildLegacyName should always guarantee
|
||||
// that these records expire reasonably soon
|
||||
// (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due
|
||||
// to something temporary we will eventually request and get the right data.
|
||||
processName(agent_id, av_name, true);
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::requestNamesViaLegacy()
|
||||
|
|
@ -583,7 +589,7 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
|
|||
av_name->mDisplayName = full_name;
|
||||
av_name->mIsDisplayNameDefault = true;
|
||||
av_name->mIsTemporaryName = true;
|
||||
av_name->mExpires = F64_MAX; // not used because these are not cached
|
||||
av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
|
||||
<< full_name
|
||||
<< LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -938,8 +938,8 @@ bool LLCurlThread::CurlRequest::processRequest()
|
|||
|
||||
if(!completed)
|
||||
{
|
||||
setPriority(LLQueuedThread::PRIORITY_LOW) ;
|
||||
}
|
||||
setPriority(LLQueuedThread::PRIORITY_LOW) ;
|
||||
}
|
||||
}
|
||||
|
||||
return completed ;
|
||||
|
|
@ -949,7 +949,7 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed)
|
|||
{
|
||||
if(mMulti->isDead())
|
||||
{
|
||||
mCurlThread->deleteMulti(mMulti) ;
|
||||
mCurlThread->deleteMulti(mMulti) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -993,6 +993,7 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi)
|
|||
return ;
|
||||
}
|
||||
|
||||
|
||||
multi->markDead() ;
|
||||
}
|
||||
|
||||
|
|
@ -1098,7 +1099,9 @@ void LLCurlRequest::get(const std::string& url, LLCurl::ResponderPtr responder)
|
|||
{
|
||||
getByteRange(url, headers_t(), 0, -1, responder);
|
||||
}
|
||||
|
||||
|
||||
// Note: (length==0) is interpreted as "the rest of the file", i.e. the whole file if (offset==0) or
|
||||
// the remainder of the file if not.
|
||||
bool LLCurlRequest::getByteRange(const std::string& url,
|
||||
const headers_t& headers,
|
||||
S32 offset, S32 length,
|
||||
|
|
@ -1117,6 +1120,11 @@ bool LLCurlRequest::getByteRange(const std::string& url,
|
|||
std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1);
|
||||
easy->slist_append(range.c_str());
|
||||
}
|
||||
else if (offset > 0)
|
||||
{
|
||||
std::string range = llformat("Range: bytes=%d-", offset);
|
||||
easy->slist_append(range.c_str());
|
||||
}
|
||||
easy->setHeaders();
|
||||
bool res = addEasy(easy);
|
||||
return res;
|
||||
|
|
@ -1244,6 +1252,208 @@ S32 LLCurlRequest::getQueued()
|
|||
return queued;
|
||||
}
|
||||
|
||||
LLCurlTextureRequest::LLCurlTextureRequest(S32 concurrency) :
|
||||
LLCurlRequest(),
|
||||
mConcurrency(concurrency),
|
||||
mInQueue(0),
|
||||
mMutex(NULL),
|
||||
mHandleCounter(1),
|
||||
mTotalIssuedRequests(0),
|
||||
mTotalReceivedBits(0)
|
||||
{
|
||||
mGlobalTimer.reset();
|
||||
}
|
||||
|
||||
LLCurlTextureRequest::~LLCurlTextureRequest()
|
||||
{
|
||||
mRequestMap.clear();
|
||||
|
||||
for(req_queue_t::iterator iter = mCachedRequests.begin(); iter != mCachedRequests.end(); ++iter)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
mCachedRequests.clear();
|
||||
}
|
||||
|
||||
//return 0: success
|
||||
// > 0: cached handle
|
||||
U32 LLCurlTextureRequest::getByteRange(const std::string& url,
|
||||
const headers_t& headers,
|
||||
S32 offset, S32 length, U32 pri,
|
||||
LLCurl::ResponderPtr responder, F32 delay_time)
|
||||
{
|
||||
U32 ret_val = 0;
|
||||
bool success = false;
|
||||
|
||||
if(mInQueue < mConcurrency && delay_time < 0.f)
|
||||
{
|
||||
success = LLCurlRequest::getByteRange(url, headers, offset, length, responder);
|
||||
}
|
||||
|
||||
LLMutexLock lock(&mMutex);
|
||||
|
||||
if(success)
|
||||
{
|
||||
mInQueue++;
|
||||
mTotalIssuedRequests++;
|
||||
}
|
||||
else
|
||||
{
|
||||
request_t* request = new request_t(mHandleCounter, url, headers, offset, length, pri, responder);
|
||||
if(delay_time > 0.f)
|
||||
{
|
||||
request->mStartTime = mGlobalTimer.getElapsedTimeF32() + delay_time;
|
||||
}
|
||||
|
||||
mCachedRequests.insert(request);
|
||||
mRequestMap[mHandleCounter] = request;
|
||||
ret_val = mHandleCounter;
|
||||
mHandleCounter++;
|
||||
|
||||
if(!mHandleCounter)
|
||||
{
|
||||
mHandleCounter = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void LLCurlTextureRequest::completeRequest(S32 received_bytes)
|
||||
{
|
||||
LLMutexLock lock(&mMutex);
|
||||
|
||||
llassert_always(mInQueue > 0);
|
||||
|
||||
mInQueue--;
|
||||
mTotalReceivedBits += received_bytes * 8;
|
||||
}
|
||||
|
||||
void LLCurlTextureRequest::nextRequests()
|
||||
{
|
||||
if(mCachedRequests.empty() || mInQueue >= mConcurrency)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
F32 cur_time = mGlobalTimer.getElapsedTimeF32();
|
||||
|
||||
req_queue_t::iterator iter;
|
||||
{
|
||||
LLMutexLock lock(&mMutex);
|
||||
iter = mCachedRequests.begin();
|
||||
}
|
||||
while(1)
|
||||
{
|
||||
request_t* request = *iter;
|
||||
if(request->mStartTime < cur_time)
|
||||
{
|
||||
if(!LLCurlRequest::getByteRange(request->mUrl, request->mHeaders, request->mOffset, request->mLength, request->mResponder))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
LLMutexLock lock(&mMutex);
|
||||
++iter;
|
||||
mInQueue++;
|
||||
mTotalIssuedRequests++;
|
||||
mCachedRequests.erase(request);
|
||||
mRequestMap.erase(request->mHandle);
|
||||
delete request;
|
||||
|
||||
if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLMutexLock lock(&mMutex);
|
||||
++iter;
|
||||
if(iter == mCachedRequests.end() || mInQueue >= mConcurrency)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void LLCurlTextureRequest::updatePriority(U32 handle, U32 pri)
|
||||
{
|
||||
if(!handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLMutexLock lock(&mMutex);
|
||||
|
||||
std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
|
||||
if(iter != mRequestMap.end())
|
||||
{
|
||||
request_t* req = iter->second;
|
||||
|
||||
if(req->mPriority != pri)
|
||||
{
|
||||
mCachedRequests.erase(req);
|
||||
req->mPriority = pri;
|
||||
mCachedRequests.insert(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLCurlTextureRequest::removeRequest(U32 handle)
|
||||
{
|
||||
if(!handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLMutexLock lock(&mMutex);
|
||||
|
||||
std::map<S32, request_t*>::iterator iter = mRequestMap.find(handle);
|
||||
if(iter != mRequestMap.end())
|
||||
{
|
||||
request_t* req = iter->second;
|
||||
mRequestMap.erase(iter);
|
||||
mCachedRequests.erase(req);
|
||||
delete req;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLCurlTextureRequest::isWaiting(U32 handle)
|
||||
{
|
||||
if(!handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLMutexLock lock(&mMutex);
|
||||
return mRequestMap.find(handle) != mRequestMap.end();
|
||||
}
|
||||
|
||||
U32 LLCurlTextureRequest::getTotalReceivedBits()
|
||||
{
|
||||
LLMutexLock lock(&mMutex);
|
||||
|
||||
U32 bits = mTotalReceivedBits;
|
||||
mTotalReceivedBits = 0;
|
||||
return bits;
|
||||
}
|
||||
|
||||
U32 LLCurlTextureRequest::getTotalIssuedRequests()
|
||||
{
|
||||
LLMutexLock lock(&mMutex);
|
||||
return mTotalIssuedRequests;
|
||||
}
|
||||
|
||||
S32 LLCurlTextureRequest::getNumRequests()
|
||||
{
|
||||
LLMutexLock lock(&mMutex);
|
||||
return mInQueue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// For generating one easy request
|
||||
// associated with a single multi request
|
||||
|
|
|
|||
|
|
@ -407,6 +407,71 @@ private:
|
|||
BOOL mProcessing;
|
||||
};
|
||||
|
||||
//for texture fetch only
|
||||
class LLCurlTextureRequest : public LLCurlRequest
|
||||
{
|
||||
public:
|
||||
LLCurlTextureRequest(S32 concurrency);
|
||||
~LLCurlTextureRequest();
|
||||
|
||||
U32 getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder, F32 delay_time = -1.f);
|
||||
void nextRequests();
|
||||
void completeRequest(S32 received_bytes);
|
||||
|
||||
void updatePriority(U32 handle, U32 pri);
|
||||
void removeRequest(U32 handle);
|
||||
|
||||
U32 getTotalReceivedBits();
|
||||
U32 getTotalIssuedRequests();
|
||||
S32 getNumRequests();
|
||||
bool isWaiting(U32 handle);
|
||||
|
||||
private:
|
||||
LLMutex mMutex;
|
||||
S32 mConcurrency;
|
||||
S32 mInQueue; //request currently in queue.
|
||||
U32 mHandleCounter;
|
||||
U32 mTotalIssuedRequests;
|
||||
U32 mTotalReceivedBits;
|
||||
|
||||
typedef struct _request_t
|
||||
{
|
||||
_request_t(U32 handle, const std::string& url, const headers_t& headers, S32 offset, S32 length, U32 pri, LLCurl::ResponderPtr responder) :
|
||||
mHandle(handle), mUrl(url), mHeaders(headers), mOffset(offset), mLength(length), mPriority(pri), mResponder(responder), mStartTime(0.f)
|
||||
{}
|
||||
|
||||
U32 mHandle;
|
||||
std::string mUrl;
|
||||
LLCurlRequest::headers_t mHeaders;
|
||||
S32 mOffset;
|
||||
S32 mLength;
|
||||
LLCurl::ResponderPtr mResponder;
|
||||
U32 mPriority;
|
||||
F32 mStartTime; //start time to issue this request
|
||||
} request_t;
|
||||
|
||||
struct request_compare
|
||||
{
|
||||
bool operator()(const request_t* lhs, const request_t* rhs) const
|
||||
{
|
||||
if(lhs->mPriority != rhs->mPriority)
|
||||
{
|
||||
return lhs->mPriority > rhs->mPriority; // higher priority in front of queue (set)
|
||||
}
|
||||
else
|
||||
{
|
||||
return (U32)lhs < (U32)rhs;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::set<request_t*, request_compare> req_queue_t;
|
||||
req_queue_t mCachedRequests;
|
||||
std::map<S32, request_t*> mRequestMap;
|
||||
|
||||
LLFrameTimer mGlobalTimer;
|
||||
};
|
||||
|
||||
class LLCurlEasyRequest
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -149,7 +149,8 @@ bool LLPrimitive::cleanupVolumeManager()
|
|||
LLPrimitive::LLPrimitive()
|
||||
: mTextureList(),
|
||||
mNumTEs(0),
|
||||
mMiscFlags(0)
|
||||
mMiscFlags(0),
|
||||
mNumBumpmapTEs(0)
|
||||
{
|
||||
mPrimitiveCode = 0;
|
||||
|
||||
|
|
@ -237,7 +238,10 @@ void LLPrimitive::setAllTETextures(const LLUUID &tex_id)
|
|||
//===============================================================
|
||||
void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te)
|
||||
{
|
||||
mTextureList.copyTexture(index, te);
|
||||
if(mTextureList.copyTexture(index, te) != TEM_CHANGE_NONE && te.getBumpmap() > 0)
|
||||
{
|
||||
mNumBumpmapTEs++;
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id)
|
||||
|
|
@ -316,6 +320,7 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r)
|
|||
//===============================================================
|
||||
S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
|
||||
{
|
||||
updateNumBumpmap(index, bump);
|
||||
return mTextureList.setBumpShinyFullbright(index, bump);
|
||||
}
|
||||
|
||||
|
|
@ -326,11 +331,13 @@ S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media)
|
|||
|
||||
S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump)
|
||||
{
|
||||
updateNumBumpmap(index, bump);
|
||||
return mTextureList.setBumpMap(index, bump);
|
||||
}
|
||||
|
||||
S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny)
|
||||
{
|
||||
updateNumBumpmap(index, bump_shiny);
|
||||
return mTextureList.setBumpShiny(index, bump_shiny);
|
||||
}
|
||||
|
||||
|
|
@ -1445,6 +1452,26 @@ void LLPrimitive::takeTextureList(LLPrimTextureList& other_list)
|
|||
mTextureList.take(other_list);
|
||||
}
|
||||
|
||||
void LLPrimitive::updateNumBumpmap(const U8 index, const U8 bump)
|
||||
{
|
||||
LLTextureEntry* te = getTE(index);
|
||||
if(!te)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
U8 old_bump = te->getBumpmap();
|
||||
if(old_bump > 0)
|
||||
{
|
||||
mNumBumpmapTEs--;
|
||||
}
|
||||
if((bump & TEM_BUMP_MASK) > 0)
|
||||
{
|
||||
mNumBumpmapTEs++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
//============================================================================
|
||||
|
||||
// Moved from llselectmgr.cpp
|
||||
|
|
|
|||
|
|
@ -421,7 +421,8 @@ public:
|
|||
inline BOOL isAvatar() const;
|
||||
inline BOOL isSittingAvatar() const;
|
||||
inline BOOL isSittingAvatarOnGround() const;
|
||||
|
||||
inline bool hasBumpmap() const { return mNumBumpmapTEs > 0;}
|
||||
|
||||
void setFlags(U32 flags) { mMiscFlags = flags; }
|
||||
void addFlags(U32 flags) { mMiscFlags |= flags; }
|
||||
void removeFlags(U32 flags) { mMiscFlags &= ~flags; }
|
||||
|
|
@ -435,6 +436,9 @@ public:
|
|||
inline static BOOL isPrimitive(const LLPCode pcode);
|
||||
inline static BOOL isApp(const LLPCode pcode);
|
||||
|
||||
private:
|
||||
void updateNumBumpmap(const U8 index, const U8 bump);
|
||||
|
||||
protected:
|
||||
LLPCode mPrimitiveCode; // Primitive code
|
||||
LLVector3 mVelocity; // how fast are we moving?
|
||||
|
|
@ -444,6 +448,7 @@ protected:
|
|||
LLPrimTextureList mTextureList; // list of texture GUIDs, scales, offsets
|
||||
U8 mMaterial; // Material code
|
||||
U8 mNumTEs; // # of faces on the primitve
|
||||
U8 mNumBumpmapTEs; // number of bumpmap TEs.
|
||||
U32 mMiscFlags; // home for misc bools
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -993,7 +993,12 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
|
|||
}
|
||||
#endif
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1070
|
||||
#include <OpenGL/gl.h>
|
||||
#else
|
||||
#include <AGL/gl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#endif // LL_MESA / LL_WINDOWS / LL_DARWIN
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ protected:
|
|||
LLGLEnable mColorMaterial;
|
||||
LLGLDisable mAlphaTest, mBlend, mCullFace, mDither, mFog,
|
||||
mLineSmooth, mLineStipple, mNormalize, mPolygonSmooth,
|
||||
mTextureGenQ, mTextureGenR, mTextureGenS, mTextureGenT,
|
||||
mGLMultisample;
|
||||
public:
|
||||
LLGLSDefault()
|
||||
|
|
@ -76,10 +75,6 @@ public:
|
|||
mLineStipple(GL_LINE_STIPPLE),
|
||||
mNormalize(GL_NORMALIZE),
|
||||
mPolygonSmooth(GL_POLYGON_SMOOTH),
|
||||
mTextureGenQ(GL_TEXTURE_GEN_Q),
|
||||
mTextureGenR(GL_TEXTURE_GEN_R),
|
||||
mTextureGenS(GL_TEXTURE_GEN_S),
|
||||
mTextureGenT(GL_TEXTURE_GEN_T),
|
||||
mGLMultisample(GL_MULTISAMPLE_ARB)
|
||||
{ }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -478,7 +478,7 @@ bool LLImageGL::checkSize(S32 width, S32 height)
|
|||
return check_power_of_two(width) && check_power_of_two(height);
|
||||
}
|
||||
|
||||
void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
|
||||
void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level)
|
||||
{
|
||||
if (width != mWidth || height != mHeight || ncomponents != mComponents)
|
||||
{
|
||||
|
|
@ -511,6 +511,11 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
|
|||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
|
||||
if(discard_level > 0)
|
||||
{
|
||||
mMaxDiscardLevel = llmax(mMaxDiscardLevel, (S8)discard_level);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -860,14 +865,13 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
|
|||
llassert(mCurrentDiscardLevel >= 0);
|
||||
discard_level = mCurrentDiscardLevel;
|
||||
}
|
||||
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
|
||||
|
||||
|
||||
// Actual image width/height = raw image width/height * 2^discard_level
|
||||
S32 w = raw_image->getWidth() << discard_level;
|
||||
S32 h = raw_image->getHeight() << discard_level;
|
||||
|
||||
// setSize may call destroyGLTexture if the size does not match
|
||||
setSize(w, h, raw_image->getComponents());
|
||||
setSize(w, h, raw_image->getComponents(), discard_level);
|
||||
|
||||
if( !mHasExplicitFormat )
|
||||
{
|
||||
|
|
@ -1264,8 +1268,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
llassert(mCurrentDiscardLevel >= 0);
|
||||
discard_level = mCurrentDiscardLevel;
|
||||
}
|
||||
discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel);
|
||||
|
||||
|
||||
// Actual image width/height = raw image width/height * 2^discard_level
|
||||
S32 raw_w = imageraw->getWidth() ;
|
||||
S32 raw_h = imageraw->getHeight() ;
|
||||
|
|
@ -1273,7 +1276,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
|
|||
S32 h = raw_h << discard_level;
|
||||
|
||||
// setSize may call destroyGLTexture if the size does not match
|
||||
setSize(w, h, imageraw->getComponents());
|
||||
setSize(w, h, imageraw->getComponents(), discard_level);
|
||||
|
||||
if( !mHasExplicitFormat )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ protected:
|
|||
public:
|
||||
virtual void dump(); // debugging info to llinfos
|
||||
|
||||
void setSize(S32 width, S32 height, S32 ncomponents);
|
||||
void setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1);
|
||||
void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
|
||||
void setAllowCompression(bool allow) { mAllowCompression = allow; }
|
||||
|
||||
|
|
|
|||
|
|
@ -648,7 +648,7 @@ void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eT
|
|||
gGL.flush();
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
|
||||
}
|
||||
|
||||
|
||||
// We want an early out, because this function does a LOT of stuff.
|
||||
if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2))
|
||||
|| (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty)
|
||||
|
|
@ -1437,6 +1437,17 @@ void LLRender::matrixMode(U32 mode)
|
|||
mMatrixMode = mode;
|
||||
}
|
||||
|
||||
U32 LLRender::getMatrixMode()
|
||||
{
|
||||
if (mMatrixMode >= MM_TEXTURE0 && mMatrixMode <= MM_TEXTURE3)
|
||||
{ //always return MM_TEXTURE if current matrix mode points at any texture matrix
|
||||
return MM_TEXTURE;
|
||||
}
|
||||
|
||||
return mMatrixMode;
|
||||
}
|
||||
|
||||
|
||||
void LLRender::loadIdentity()
|
||||
{
|
||||
flush();
|
||||
|
|
|
|||
|
|
@ -346,6 +346,7 @@ public:
|
|||
void loadIdentity();
|
||||
void multMatrix(const GLfloat* m);
|
||||
void matrixMode(U32 mode);
|
||||
U32 getMatrixMode();
|
||||
|
||||
const glh::matrix4f& getModelviewMatrix();
|
||||
const glh::matrix4f& getProjectionMatrix();
|
||||
|
|
|
|||
|
|
@ -643,7 +643,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
|||
text[count++] = strdup("#define textureCube texture\n");
|
||||
text[count++] = strdup("#define texture2DLod textureLod\n");
|
||||
text[count++] = strdup("#define shadow2D(a,b) vec2(texture(a,b))\n");
|
||||
|
||||
|
||||
if (major_version > 1 || minor_version >= 40)
|
||||
{ //GLSL 1.40 replaces texture2DRect et al with texture
|
||||
text[count++] = strdup("#define texture2DRect texture\n");
|
||||
|
|
|
|||
|
|
@ -38,10 +38,6 @@
|
|||
#include "llglslshader.h"
|
||||
#include "llmemory.h"
|
||||
|
||||
#if LL_DARWIN
|
||||
#define LL_VBO_POOLING 1
|
||||
#else
|
||||
#endif
|
||||
//Next Highest Power Of Two
|
||||
//helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
|
||||
U32 nhpo2(U32 v)
|
||||
|
|
@ -294,6 +290,7 @@ void LLVBOPool::seedPool()
|
|||
}
|
||||
|
||||
|
||||
|
||||
void LLVBOPool::cleanup()
|
||||
{
|
||||
U32 size = LL_VBO_BLOCK_SIZE;
|
||||
|
|
|
|||
|
|
@ -155,7 +155,6 @@ set(llui_HEADER_FILES
|
|||
llflyoutbutton.h
|
||||
llfocusmgr.h
|
||||
llfunctorregistry.h
|
||||
llhandle.h
|
||||
llhelp.h
|
||||
lliconctrl.h
|
||||
llkeywords.h
|
||||
|
|
|
|||
|
|
@ -748,6 +748,10 @@ void LLFloater::closeFloater(bool app_quitting)
|
|||
dependee->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// STORM-1879: since this floater has focus, treat the closeFloater- call
|
||||
// like a click on the close-button, and close gear- and contextmenus
|
||||
LLMenuGL::sMenuContainer->hideMenus();
|
||||
}
|
||||
|
||||
dirtyRect();
|
||||
|
|
|
|||
|
|
@ -2720,6 +2720,11 @@ BOOL LLScrollListCtrl::hasSortOrder() const
|
|||
return !mSortColumns.empty();
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::clearSortOrder()
|
||||
{
|
||||
mSortColumns.clear();
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::clearColumns()
|
||||
{
|
||||
column_map_t::iterator itor;
|
||||
|
|
|
|||
|
|
@ -374,6 +374,7 @@ public:
|
|||
std::string getSortColumnName();
|
||||
BOOL getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
|
||||
BOOL hasSortOrder() const;
|
||||
void clearSortOrder();
|
||||
|
||||
S32 selectMultiple( uuid_vec_t ids );
|
||||
// conceptually const, but mutates mItemList
|
||||
|
|
|
|||
|
|
@ -57,7 +57,9 @@ void LLToggleableMenu::handleVisibilityChange (BOOL curVisibilityIn)
|
|||
S32 x,y;
|
||||
LLUI::getMousePositionLocal(LLUI::getRootView(), &x, &y);
|
||||
|
||||
if (!curVisibilityIn && mButtonRect.pointInRect(x, y))
|
||||
// STORM-1879: also check MouseCapture to see if the button was really
|
||||
// clicked (otherwise the VisibilityChange was triggered via keyboard shortcut)
|
||||
if (!curVisibilityIn && mButtonRect.pointInRect(x, y) && gFocusMgr.getMouseCapture())
|
||||
{
|
||||
mClosedByButtonClick = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,18 +31,10 @@
|
|||
#include "llinitparam.h"
|
||||
#include "llregistry.h"
|
||||
#include "llxuiparser.h"
|
||||
#include "llstl.h"
|
||||
|
||||
class LLView;
|
||||
|
||||
// sort functor for typeid maps
|
||||
struct LLCompareTypeID
|
||||
{
|
||||
bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
|
||||
{
|
||||
return lhs->before(*rhs);
|
||||
}
|
||||
};
|
||||
|
||||
// lookup widget constructor funcs by widget name
|
||||
template <typename DERIVED_TYPE>
|
||||
class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE>
|
||||
|
|
@ -71,14 +63,14 @@ protected:
|
|||
|
||||
// lookup widget name by type
|
||||
class LLWidgetNameRegistry
|
||||
: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID>
|
||||
: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry>
|
||||
{};
|
||||
|
||||
// lookup function for generating empty param block by widget type
|
||||
// this is used for schema generation
|
||||
//typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
|
||||
//class LLDefaultParamBlockRegistry
|
||||
//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID>
|
||||
//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry>
|
||||
//{};
|
||||
|
||||
extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file lldir.h
|
||||
* @brief Definition of directory utilities class
|
||||
*
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
*/
|
||||
|
||||
#if LL_DARWIN
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
*/
|
||||
|
||||
#if !LL_DARWIN
|
||||
#error This header must not be included when compiling for any target other than Mac OS. Consider including lldir.h instead.
|
||||
|
|
|
|||
|
|
@ -1956,6 +1956,12 @@ if (DARWIN)
|
|||
)
|
||||
|
||||
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-updater mac-crash-logger)
|
||||
|
||||
if (ENABLE_SIGNING)
|
||||
set(SIGNING_SETTING "--signature=${SIGNING_IDENTITY}")
|
||||
else (ENABLE_SIGNING)
|
||||
set(SIGNING_SETTING "")
|
||||
endif (ENABLE_SIGNING)
|
||||
|
||||
if (PACKAGE)
|
||||
add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME})
|
||||
|
|
@ -1975,6 +1981,7 @@ if (DARWIN)
|
|||
--login_channel=${VIEWER_LOGIN_CHANNEL}
|
||||
--source=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
|
||||
${SIGNING_SETTING}
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
|
||||
)
|
||||
|
|
@ -1986,8 +1993,9 @@ if (INSTALL)
|
|||
endif (INSTALL)
|
||||
|
||||
if (PACKAGE)
|
||||
set(SYMBOL_SEARCH_DIRS "")
|
||||
if (WINDOWS)
|
||||
set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
|
||||
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows.tar.bz2")
|
||||
# slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
|
||||
# set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
|
||||
|
|
@ -1996,13 +2004,20 @@ if (PACKAGE)
|
|||
set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
|
||||
endif (WINDOWS)
|
||||
if (DARWIN)
|
||||
set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
|
||||
# *TODO: Generate these search dirs in the cmake files related to each binary.
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_updater/${CMAKE_CFG_INTDIR}")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}")
|
||||
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2")
|
||||
set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin")
|
||||
set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-updater mac-crash-logger")
|
||||
set(VIEWER_LIB_GLOB "*.dylib")
|
||||
endif (DARWIN)
|
||||
if (LINUX)
|
||||
set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/packaged")
|
||||
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
|
||||
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2")
|
||||
set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
|
||||
set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
|
||||
|
|
@ -2022,7 +2037,7 @@ if (PACKAGE)
|
|||
ARGS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
|
||||
"${LLBUILD_CONFIG}"
|
||||
"${VIEWER_DIST_DIR}"
|
||||
"${SYMBOL_SEARCH_DIRS}"
|
||||
"${VIEWER_EXE_GLOBS}"
|
||||
"${VIEWER_LIB_GLOB}"
|
||||
"${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@
|
|||
<key>count</key>
|
||||
<integer>1</integer>
|
||||
<key>map-to</key>
|
||||
<string>SkinFolder</string>
|
||||
<string>SkinCurrent</string>
|
||||
</map>
|
||||
|
||||
<key>slurl</key>
|
||||
|
|
|
|||
|
|
@ -3269,6 +3269,17 @@
|
|||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FastCacheFetchEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Enable texture fast cache fetching if set</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<string>1</string>
|
||||
</map>
|
||||
<key>FeatureManagerHTTPTable</key>
|
||||
<map>
|
||||
|
|
@ -8090,7 +8101,7 @@
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>0</real>
|
||||
<real>-0.007</real>
|
||||
</map>
|
||||
<key>RenderShadowOffsetError</key>
|
||||
<map>
|
||||
|
|
@ -10789,6 +10800,83 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureFetchSource</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Debug use: Source to fetch textures</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdateHighPriority</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Number of high priority textures to update per frame</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>32</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdateMaxMediumPriority</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Maximum number of medium priority textures to update per frame</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>256</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdateMinMediumPriority</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Minimum number of medium priority textures to update per frame</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>32</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdatePriorityThreshold</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Threshold under which textures will be considered too low priority and skipped for update</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<integer>0.0</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdateSkipLowPriority</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Flag indicating if we want to skip textures with too low of a priority</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>TextureFetchUpdatePriorities</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Number of priority texture to update per frame</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>32</integer>
|
||||
</map>
|
||||
<key>TextureLoadFullRes</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -46,6 +46,6 @@ void main()
|
|||
frag_data[0] = vec4(diff.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,5 +52,5 @@ void main()
|
|||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(tnorm);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,6 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,5 +48,5 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,6 @@ void main()
|
|||
frag_data[0] = vec4(col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0); // spec
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,6 @@ void main()
|
|||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,5 +41,5 @@ void main()
|
|||
frag_data[1] = vertex_color.aaaa; // spec
|
||||
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ void main()
|
|||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = (norm.xyz-0.5)*2.0; // unpack norm
|
||||
norm = normalize(norm);
|
||||
vec4 spec = texture2DRect(specularRect, frag.xy);
|
||||
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ void main()
|
|||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = (norm.xyz-0.5)*2.0; // unpack norm
|
||||
float da = dot(norm, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ void main()
|
|||
float depth = texture2DRect(depthMap, tc.xy).r;
|
||||
vec3 pos = getPosition_d(tc, depth).xyz;
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = (norm.xyz-0.5)*2.0; // unpack norm
|
||||
|
||||
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ void main()
|
|||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = (norm.xyz-0.5)*2.0; // unpack norm
|
||||
|
||||
frag_color[0] = 1.0;
|
||||
frag_color[1] = calcAmbientOcclusion(pos, norm);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,6 @@ void main()
|
|||
frag_data[0] = vec4(outColor.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,5 +48,5 @@ void main()
|
|||
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
|
||||
frag_data[1] = vec4(0,0,0,0);
|
||||
vec3 nvn = normalize(vary_normal);
|
||||
frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
|
||||
frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,5 +161,5 @@ void main()
|
|||
|
||||
frag_data[0] = vec4(color.rgb, 0.5); // diffuse
|
||||
frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
|
||||
frag_data[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace
|
||||
frag_data[2] = vec4(screenspacewavef.xyz*0.5+0.5, screenspacewavef.z*0.5); // normalxyz, displace
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@ out vec4 frag_color;
|
|||
VARYING vec4 vertex_color;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2DRect depthMap;
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
|
|
@ -58,22 +58,22 @@ uniform float shadow_bias;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(stc.y*shadow_res.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -99,8 +99,7 @@ void main()
|
|||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos)*w;
|
||||
|
|
@ -111,8 +110,7 @@ void main()
|
|||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
|
|
@ -123,8 +121,7 @@ void main()
|
|||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
|
|
@ -135,8 +132,7 @@ void main()
|
|||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,17 +31,16 @@ out vec4 frag_color;
|
|||
#define frag_color gl_FragColor
|
||||
#endif
|
||||
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
|
@ -54,6 +53,7 @@ VARYING vec3 vary_pointlight_col;
|
|||
VARYING vec2 vary_texcoord0;
|
||||
VARYING vec4 vertex_color;
|
||||
|
||||
uniform vec2 shadow_res;
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
|
@ -71,22 +71,22 @@ vec4 getPosition(vec2 pos_screen)
|
|||
return pos;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(stc.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
|
||||
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -112,8 +112,7 @@ void main()
|
|||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos)*w;
|
||||
|
|
@ -124,8 +123,7 @@ void main()
|
|||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
|
|
@ -136,8 +134,7 @@ void main()
|
|||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
|
|
@ -148,8 +145,7 @@ void main()
|
|||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,17 +33,16 @@ out vec4 frag_color;
|
|||
|
||||
uniform float minimum_alpha;
|
||||
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2D diffuseMap;
|
||||
|
||||
uniform mat4 shadow_matrix[6];
|
||||
uniform vec4 shadow_clip;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
vec3 atmosLighting(vec3 light);
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
|
@ -55,6 +54,8 @@ VARYING vec3 vary_position;
|
|||
VARYING vec3 vary_pointlight_col;
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
uniform float shadow_bias;
|
||||
|
||||
uniform mat4 inv_proj;
|
||||
|
|
@ -72,20 +73,20 @@ vec4 getPosition(vec2 pos_screen)
|
|||
return pos;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(stc.y*12345))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
|
@ -120,8 +121,7 @@ void main()
|
|||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos)*w;
|
||||
|
|
@ -132,8 +132,7 @@ void main()
|
|||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
|
|
@ -144,8 +143,7 @@ void main()
|
|||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
|
|
@ -156,8 +154,7 @@ void main()
|
|||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ void main()
|
|||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = (norm.xyz-0.5)*2.0; // unpack norm
|
||||
|
||||
norm = normalize(norm);
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ void main()
|
|||
float depth = texture2DRect(depthMap, tc.xy).r;
|
||||
vec3 pos = getPosition_d(tc, depth).xyz;
|
||||
vec3 norm = texture2DRect(normalMap, tc).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = (norm.xyz-0.5)*2.0; // unpack norm
|
||||
|
||||
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ void main()
|
|||
}
|
||||
|
||||
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
|
||||
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
|
||||
norm = (norm.xyz-0.5)*2.0; // unpack norm
|
||||
|
||||
norm = normalize(norm);
|
||||
float l_dist = -dot(lv, proj_n);
|
||||
|
|
|
|||
|
|
@ -35,10 +35,10 @@ out vec4 frag_color;
|
|||
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap4;
|
||||
uniform sampler2DShadow shadowMap5;
|
||||
|
||||
|
|
@ -55,10 +55,10 @@ VARYING vec2 vary_fragcoord;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
uniform vec2 proj_shadow_res;
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
uniform vec2 shadow_res;
|
||||
uniform float shadow_bias;
|
||||
uniform float shadow_offset;
|
||||
|
||||
|
|
@ -78,30 +78,31 @@ vec4 getPosition(vec2 pos_screen)
|
|||
return pos;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias*scl;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(pos_screen.y*0.666666666)); // add some jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x; // add some jitter to X sample pos according to Y to disguise the snapping going on here
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
|
||||
return shadow*0.2;
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += spot_shadow_bias*scl;
|
||||
stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
|
||||
|
||||
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
|
|
@ -125,7 +126,7 @@ void main()
|
|||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec4 nmap4 = texture2DRect(normalMap, pos_screen);
|
||||
nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
|
||||
nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm
|
||||
float displace = nmap4.w;
|
||||
vec3 norm = nmap4.xyz;
|
||||
|
||||
|
|
@ -162,8 +163,7 @@ void main()
|
|||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
|
||||
|
|
@ -174,8 +174,7 @@ void main()
|
|||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
|
|
@ -186,7 +185,6 @@ void main()
|
|||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
|
|
@ -198,7 +196,6 @@ void main()
|
|||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
|
@ -237,11 +234,11 @@ void main()
|
|||
|
||||
//spotlight shadow 1
|
||||
vec4 lpos = shadow_matrix[4]*spos;
|
||||
frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen);
|
||||
frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
|
||||
|
||||
//spotlight shadow 2
|
||||
lpos = shadow_matrix[5]*spos;
|
||||
frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen);
|
||||
frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
|
||||
|
||||
//frag_color.rgb = pos.xyz;
|
||||
//frag_color.b = shadow;
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@ out vec4 frag_color;
|
|||
|
||||
uniform sampler2DRect depthMap;
|
||||
uniform sampler2DRect normalMap;
|
||||
uniform sampler2DRectShadow shadowMap0;
|
||||
uniform sampler2DRectShadow shadowMap1;
|
||||
uniform sampler2DRectShadow shadowMap2;
|
||||
uniform sampler2DRectShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap0;
|
||||
uniform sampler2DShadow shadowMap1;
|
||||
uniform sampler2DShadow shadowMap2;
|
||||
uniform sampler2DShadow shadowMap3;
|
||||
uniform sampler2DShadow shadowMap4;
|
||||
uniform sampler2DShadow shadowMap5;
|
||||
uniform sampler2D noiseMap;
|
||||
|
|
@ -55,10 +55,11 @@ VARYING vec2 vary_fragcoord;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
uniform vec2 screen_res;
|
||||
uniform vec2 shadow_res;
|
||||
uniform vec2 proj_shadow_res;
|
||||
uniform vec3 sun_dir;
|
||||
|
||||
uniform vec2 shadow_res;
|
||||
|
||||
uniform float shadow_bias;
|
||||
uniform float shadow_offset;
|
||||
|
||||
|
|
@ -139,30 +140,30 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm)
|
|||
return min(ret, 1.0);
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += shadow_bias*scl;
|
||||
stc.z += shadow_bias;
|
||||
|
||||
stc.x = floor(stc.x + fract(pos_screen.y*0.666666666));
|
||||
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*0.666666666))/shadow_res.x;
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
|
||||
float cs = shadow2DRect(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
|
||||
shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
|
||||
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(2.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(1.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.0/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
|
||||
shadow += shadow2D(shadowMap, stc.xyz+vec3(-2.0/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
|
||||
|
||||
return shadow*0.2;
|
||||
}
|
||||
|
||||
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
|
||||
{
|
||||
stc.xyz /= stc.w;
|
||||
stc.z += spot_shadow_bias*scl;
|
||||
stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
|
||||
|
||||
|
||||
float cs = shadow2D(shadowMap, stc.xyz).x;
|
||||
float shadow = cs;
|
||||
|
||||
|
|
@ -186,7 +187,7 @@ void main()
|
|||
vec4 pos = getPosition(pos_screen);
|
||||
|
||||
vec4 nmap4 = texture2DRect(normalMap, pos_screen);
|
||||
nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
|
||||
nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm
|
||||
float displace = nmap4.w;
|
||||
vec3 norm = nmap4.xyz;
|
||||
|
||||
|
|
@ -223,8 +224,7 @@ void main()
|
|||
if (spos.z < near_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[3]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.z, 0.0)/transition_domain.z;
|
||||
shadow += pcfShadow(shadowMap3, lpos, 0.25, pos_screen)*w;
|
||||
|
|
@ -235,8 +235,7 @@ void main()
|
|||
if (spos.z < near_split.y && spos.z > far_split.z)
|
||||
{
|
||||
lpos = shadow_matrix[2]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.y, 0.0)/transition_domain.y;
|
||||
w -= max(near_split.z-spos.z, 0.0)/transition_domain.z;
|
||||
|
|
@ -247,8 +246,7 @@ void main()
|
|||
if (spos.z < near_split.x && spos.z > far_split.y)
|
||||
{
|
||||
lpos = shadow_matrix[1]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(spos.z-far_split.x, 0.0)/transition_domain.x;
|
||||
w -= max(near_split.y-spos.z, 0.0)/transition_domain.y;
|
||||
|
|
@ -259,8 +257,7 @@ void main()
|
|||
if (spos.z > far_split.x)
|
||||
{
|
||||
lpos = shadow_matrix[0]*spos;
|
||||
lpos.xy *= shadow_res;
|
||||
|
||||
|
||||
float w = 1.0;
|
||||
w -= max(near_split.x-spos.z, 0.0)/transition_domain.x;
|
||||
|
||||
|
|
@ -298,11 +295,11 @@ void main()
|
|||
|
||||
//spotlight shadow 1
|
||||
vec4 lpos = shadow_matrix[4]*spos;
|
||||
frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen);
|
||||
frag_color[2] = pcfSpotShadow(shadowMap4, lpos, 0.8, pos_screen);
|
||||
|
||||
//spotlight shadow 2
|
||||
lpos = shadow_matrix[5]*spos;
|
||||
frag_color[3] = pcfShadow(shadowMap5, lpos, 0.8, pos_screen);
|
||||
frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
|
||||
|
||||
//frag_color.rgb = pos.xyz;
|
||||
//frag_color.b = shadow;
|
||||
|
|
|
|||
|
|
@ -39,17 +39,20 @@ import shlex
|
|||
import subprocess
|
||||
import tarfile
|
||||
import StringIO
|
||||
import pprint
|
||||
|
||||
DEBUG=False
|
||||
|
||||
def usage():
|
||||
print >>sys.stderr, "usage: %s viewer_dir viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0]
|
||||
print >>sys.stderr, "usage: %s search_dirs viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0]
|
||||
|
||||
class MissingModuleError(Exception):
|
||||
def __init__(self, modules):
|
||||
Exception.__init__(self, "Failed to find required modules: %r" % modules)
|
||||
self.modules = modules
|
||||
|
||||
def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
|
||||
print "generate_breakpad_symbols run with args: %s" % str((configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
|
||||
def main(configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
|
||||
print "generate_breakpad_symbols run with args: %s" % str((configuration, search_dirs, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
|
||||
|
||||
if not re.match("release", configuration, re.IGNORECASE):
|
||||
print "skipping breakpad symbol generation for non-release build."
|
||||
|
|
@ -67,21 +70,49 @@ def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, vi
|
|||
return True
|
||||
return fnmatch.fnmatch(f, libs_suffix)
|
||||
|
||||
search_dirs = search_dirs.split(";")
|
||||
|
||||
def list_files():
|
||||
for (dirname, subdirs, filenames) in os.walk(viewer_dir):
|
||||
#print "scanning '%s' for modules..." % dirname
|
||||
for f in itertools.ifilter(matches, filenames):
|
||||
yield os.path.join(dirname, f)
|
||||
for search_dir in search_dirs:
|
||||
for (dirname, subdirs, filenames) in os.walk(search_dir):
|
||||
if DEBUG:
|
||||
print "scanning '%s' for modules..." % dirname
|
||||
for f in itertools.ifilter(matches, filenames):
|
||||
yield os.path.join(dirname, f)
|
||||
|
||||
def dump_module(m):
|
||||
print "dumping module '%s' with '%s'..." % (m, dump_syms_tool)
|
||||
child = subprocess.Popen([dump_syms_tool, m] , stdout=subprocess.PIPE)
|
||||
dsym_full_path = m
|
||||
child = subprocess.Popen([dump_syms_tool, dsym_full_path] , stdout=subprocess.PIPE)
|
||||
out, err = child.communicate()
|
||||
return (m,child.returncode, out, err)
|
||||
|
||||
out = tarfile.open(viewer_symbol_file, 'w:bz2')
|
||||
|
||||
modules = {}
|
||||
|
||||
for m in list_files():
|
||||
if DEBUG:
|
||||
print "examining module '%s' ... " % m,
|
||||
filename=os.path.basename(m)
|
||||
if -1 != m.find("DWARF"):
|
||||
# Just use this module; it has the symbols we want.
|
||||
modules[filename] = m
|
||||
if DEBUG:
|
||||
print "found dSYM entry"
|
||||
elif filename not in modules:
|
||||
# Only use this if we don't already have a (possibly better) entry.
|
||||
modules[filename] = m
|
||||
if DEBUG:
|
||||
print "found new entry"
|
||||
elif DEBUG:
|
||||
print "ignoring entry"
|
||||
|
||||
for (filename,status,symbols,err) in itertools.imap(dump_module, list_files()):
|
||||
|
||||
print "Found these following modules:"
|
||||
pprint.pprint( modules )
|
||||
|
||||
out = tarfile.open(viewer_symbol_file, 'w:bz2')
|
||||
for (filename,status,symbols,err) in itertools.imap(dump_module, modules.values()):
|
||||
if status == 0:
|
||||
module_line = symbols[:symbols.index('\n')]
|
||||
module_line = module_line.split()
|
||||
|
|
|
|||
|
|
@ -379,6 +379,9 @@ void init_default_trans_args()
|
|||
default_trans_args.insert("CAPITALIZED_APP_NAME");
|
||||
default_trans_args.insert("SECOND_LIFE_GRID");
|
||||
default_trans_args.insert("SUPPORT_SITE");
|
||||
// This URL shows up in a surprising number of places in various skin
|
||||
// files. We really only want to have to maintain a single copy of it.
|
||||
default_trans_args.insert("create_account_url");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
@ -4356,6 +4359,10 @@ void LLAppViewer::idle()
|
|||
{
|
||||
return;
|
||||
}
|
||||
if (gTeleportDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gViewerWindow->updateUI();
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ void LLDrawable::init()
|
|||
mPositionGroup.clear();
|
||||
mExtents[0].clear();
|
||||
mExtents[1].clear();
|
||||
mQuietCount = 0;
|
||||
|
||||
mState = 0;
|
||||
mVObjp = NULL;
|
||||
|
|
@ -407,6 +406,8 @@ void LLDrawable::makeActive()
|
|||
if (!isRoot() && !mParent->isActive())
|
||||
{
|
||||
mParent->makeActive();
|
||||
//NOTE: linked set will now NEVER become static
|
||||
mParent->setState(LLDrawable::ACTIVE_CHILD);
|
||||
}
|
||||
|
||||
//all child objects must also be active
|
||||
|
|
@ -424,14 +425,6 @@ void LLDrawable::makeActive()
|
|||
}
|
||||
}
|
||||
|
||||
if (mVObjp->getPCode() == LL_PCODE_VOLUME)
|
||||
{
|
||||
if (mVObjp->isFlexible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mVObjp->getPCode() == LL_PCODE_VOLUME)
|
||||
{
|
||||
gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
|
||||
|
|
@ -439,28 +432,22 @@ void LLDrawable::makeActive()
|
|||
updatePartition();
|
||||
}
|
||||
|
||||
if (isRoot())
|
||||
{
|
||||
mQuietCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
getParent()->mQuietCount = 0;
|
||||
}
|
||||
llassert(isAvatar() || isRoot() || mParent->isActive());
|
||||
}
|
||||
|
||||
|
||||
void LLDrawable::makeStatic(BOOL warning_enabled)
|
||||
{
|
||||
if (isState(ACTIVE))
|
||||
if (isState(ACTIVE) &&
|
||||
!isState(ACTIVE_CHILD) &&
|
||||
!mVObjp->isAttachment() &&
|
||||
!mVObjp->isFlexible())
|
||||
{
|
||||
clearState(ACTIVE | ANIMATED_CHILD);
|
||||
|
||||
if (mParent.notNull() && mParent->isActive() && warning_enabled)
|
||||
{
|
||||
LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL;
|
||||
}
|
||||
|
||||
//drawable became static with active parent, not acceptable
|
||||
llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled);
|
||||
|
||||
LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
|
||||
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
|
||||
iter != child_list.end(); iter++)
|
||||
|
|
@ -487,8 +474,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
|
|||
mSpatialBridge->markDead();
|
||||
setSpatialBridge(NULL);
|
||||
}
|
||||
updatePartition();
|
||||
}
|
||||
updatePartition();
|
||||
}
|
||||
|
||||
// Returns "distance" between target destination and resulting xfrom
|
||||
|
|
@ -638,8 +625,6 @@ BOOL LLDrawable::updateMove()
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
makeActive();
|
||||
|
||||
BOOL done;
|
||||
|
||||
if (isState(MOVE_UNDAMPED))
|
||||
|
|
@ -648,6 +633,7 @@ BOOL LLDrawable::updateMove()
|
|||
}
|
||||
else
|
||||
{
|
||||
makeActive();
|
||||
done = updateMoveDamped();
|
||||
}
|
||||
return done;
|
||||
|
|
|
|||
|
|
@ -292,6 +292,7 @@ public:
|
|||
RIGGED = 0x08000000,
|
||||
PARTITION_MOVE = 0x10000000,
|
||||
ANIMATED_CHILD = 0x20000000,
|
||||
ACTIVE_CHILD = 0x40000000,
|
||||
} EDrawableFlags;
|
||||
|
||||
private: //aligned members
|
||||
|
|
@ -305,8 +306,6 @@ public:
|
|||
LLPointer<LLDrawable> mParent;
|
||||
|
||||
F32 mDistanceWRTCamera;
|
||||
|
||||
S32 mQuietCount;
|
||||
|
||||
static S32 getCurrentFrame() { return sCurVisible; }
|
||||
static S32 getMinVisFrameRange();
|
||||
|
|
|
|||
|
|
@ -419,6 +419,7 @@ void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
|
|||
gGL.loadMatrix(gGLModelView);
|
||||
if (params.mModelMatrix)
|
||||
{
|
||||
llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
|
||||
gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix);
|
||||
}
|
||||
gPipeline.mMatrixOpCount++;
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ void LLDrawPoolTerrain::drawLoop()
|
|||
|
||||
if (model_matrix != gGLLastMatrix)
|
||||
{
|
||||
llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
|
||||
gGLLastMatrix = model_matrix;
|
||||
gGL.loadMatrix(gGLModelView);
|
||||
if (model_matrix)
|
||||
|
|
@ -594,7 +595,8 @@ void LLDrawPoolTerrain::renderFull4TU()
|
|||
gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
gGL.loadIdentity();
|
||||
gGL.translatef(-1.f, 0.f, 0.f);
|
||||
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
||||
// Set alpha texture and do lighting modulation
|
||||
gGL.getTexUnit(3)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_PREV_COLOR, LLTexUnit::TBS_VERT_COLOR);
|
||||
gGL.getTexUnit(3)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_ALPHA);
|
||||
|
|
@ -742,6 +744,7 @@ void LLDrawPoolTerrain::renderFull2TU()
|
|||
gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
gGL.loadIdentity();
|
||||
gGL.translatef(-1.f, 0.f, 0.f);
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
||||
// Care about alpha only
|
||||
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
|
||||
|
|
@ -781,6 +784,7 @@ void LLDrawPoolTerrain::renderFull2TU()
|
|||
gGL.matrixMode(LLRender::MM_TEXTURE);
|
||||
gGL.loadIdentity();
|
||||
gGL.translatef(-2.f, 0.f, 0.f);
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
|
||||
// Care about alpha only
|
||||
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ void LLDrawPoolTree::render(S32 pass)
|
|||
gGL.loadMatrix(gGLModelView);
|
||||
if (model_matrix)
|
||||
{
|
||||
llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
|
||||
gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
|
||||
}
|
||||
gPipeline.mMatrixOpCount++;
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
|
|||
llassert(mFullHeight <= 512);
|
||||
llassert(mFullWidth <= 512);
|
||||
|
||||
if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete())
|
||||
if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI)
|
||||
{ //using offscreen render target, just use the bottom left corner
|
||||
mOrigin.set(0, 0);
|
||||
}
|
||||
|
|
@ -216,14 +216,12 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0 //THIS CAUSES MAINT-1092
|
||||
bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete();
|
||||
bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
|
||||
|
||||
if (use_fbo)
|
||||
{
|
||||
gPipeline.mWaterDis.bindTarget();
|
||||
}
|
||||
#endif
|
||||
|
||||
LLGLSLShader::bindNoShader();
|
||||
LLVertexBuffer::unbind();
|
||||
|
|
@ -258,12 +256,10 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (use_fbo)
|
||||
{
|
||||
gPipeline.mWaterDis.flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2168,6 +2168,12 @@ BOOL LLFace::hasMedia() const
|
|||
const F32 LEAST_IMPORTANCE = 0.05f ;
|
||||
const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ;
|
||||
|
||||
void LLFace::resetVirtualSize()
|
||||
{
|
||||
setVirtualSize(0.f);
|
||||
mImportanceToCamera = 0.f;
|
||||
}
|
||||
|
||||
F32 LLFace::getTextureVirtualSize()
|
||||
{
|
||||
F32 radius;
|
||||
|
|
@ -2233,8 +2239,17 @@ BOOL LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
|
|||
LLVector4a t;
|
||||
t.load3(camera->getOrigin().mV);
|
||||
lookAt.setSub(center, t);
|
||||
|
||||
F32 dist = lookAt.getLength3().getF32();
|
||||
dist = llmax(dist-size.getLength3().getF32(), 0.f);
|
||||
dist = llmax(dist-size.getLength3().getF32(), 0.001f);
|
||||
//ramp down distance for nearby objects
|
||||
if (dist < 16.f)
|
||||
{
|
||||
dist /= 16.f;
|
||||
dist *= dist;
|
||||
dist *= 16.f;
|
||||
}
|
||||
|
||||
lookAt.normalize3fast() ;
|
||||
|
||||
//get area of circle around node
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ public:
|
|||
|
||||
F32 getTextureVirtualSize() ;
|
||||
F32 getImportanceToCamera()const {return mImportanceToCamera ;}
|
||||
void resetVirtualSize();
|
||||
|
||||
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
|
||||
BOOL hasMedia() const ;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
#include "llvoavatar.h"
|
||||
|
||||
/*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f;
|
||||
std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList;
|
||||
std::vector<S32> LLVolumeImplFlexible::sUpdateDelay;
|
||||
|
||||
static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild");
|
||||
static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update");
|
||||
|
|
@ -70,8 +72,45 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD
|
|||
{
|
||||
mVO->mDrawable->makeActive() ;
|
||||
}
|
||||
|
||||
mInstanceIndex = sInstanceList.size();
|
||||
sInstanceList.push_back(this);
|
||||
sUpdateDelay.push_back(0);
|
||||
}//-----------------------------------------------
|
||||
|
||||
LLVolumeImplFlexible::~LLVolumeImplFlexible()
|
||||
{
|
||||
S32 end_idx = sInstanceList.size()-1;
|
||||
|
||||
if (end_idx != mInstanceIndex)
|
||||
{
|
||||
sInstanceList[mInstanceIndex] = sInstanceList[end_idx];
|
||||
sInstanceList[mInstanceIndex]->mInstanceIndex = mInstanceIndex;
|
||||
sUpdateDelay[mInstanceIndex] = sUpdateDelay[end_idx];
|
||||
}
|
||||
|
||||
sInstanceList.pop_back();
|
||||
sUpdateDelay.pop_back();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLVolumeImplFlexible::updateClass()
|
||||
{
|
||||
std::vector<S32>::iterator delay_iter = sUpdateDelay.begin();
|
||||
|
||||
for (std::vector<LLVolumeImplFlexible*>::iterator iter = sInstanceList.begin();
|
||||
iter != sInstanceList.end();
|
||||
++iter)
|
||||
{
|
||||
--(*delay_iter);
|
||||
if (*delay_iter <= 0)
|
||||
{
|
||||
(*iter)->doIdleUpdate();
|
||||
}
|
||||
++delay_iter;
|
||||
}
|
||||
}
|
||||
|
||||
LLVector3 LLVolumeImplFlexible::getFramePosition() const
|
||||
{
|
||||
return mVO->getRenderPosition();
|
||||
|
|
@ -296,22 +335,17 @@ void LLVolumeImplFlexible::updateRenderRes()
|
|||
// optimization similar to what Havok does for objects that are stationary.
|
||||
//---------------------------------------------------------------------------------
|
||||
static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
|
||||
void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
|
||||
void LLVolumeImplFlexible::doIdleUpdate()
|
||||
{
|
||||
LLDrawable* drawablep = mVO->mDrawable;
|
||||
|
||||
if (drawablep)
|
||||
{
|
||||
//LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
|
||||
|
||||
//flexible objects never go static
|
||||
drawablep->mQuietCount = 0;
|
||||
if (!drawablep->isRoot())
|
||||
{
|
||||
LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
|
||||
parent->mDrawable->mQuietCount = 0;
|
||||
}
|
||||
|
||||
|
||||
//ensure drawable is active
|
||||
drawablep->makeActive();
|
||||
|
||||
if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
|
||||
{
|
||||
bool visible = drawablep->isVisible();
|
||||
|
|
@ -321,31 +355,45 @@ void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6
|
|||
updateRenderRes();
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
}
|
||||
else if (visible &&
|
||||
!drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
|
||||
mVO->getPixelArea() > 256.f)
|
||||
else
|
||||
{
|
||||
U32 id;
|
||||
F32 pixel_area = mVO->getPixelArea();
|
||||
|
||||
if (mVO->isRootEdit())
|
||||
{
|
||||
id = mID;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
|
||||
id = parent->getVolumeInterfaceID();
|
||||
}
|
||||
|
||||
U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
|
||||
|
||||
if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
|
||||
if (visible)
|
||||
{
|
||||
updateRenderRes();
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
|
||||
mVO->getPixelArea() > 256.f)
|
||||
{
|
||||
U32 id;
|
||||
|
||||
if (mVO->isRootEdit())
|
||||
{
|
||||
id = mID;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
|
||||
id = parent->getVolumeInterfaceID();
|
||||
}
|
||||
|
||||
if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
|
||||
{
|
||||
sUpdateDelay[mInstanceIndex] = (S32) update_period-1;
|
||||
|
||||
updateRenderRes();
|
||||
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sUpdateDelay[mInstanceIndex] = (S32) update_period;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -370,7 +418,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
|
|||
{
|
||||
BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
|
||||
|
||||
doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0);
|
||||
doIdleUpdate();
|
||||
|
||||
if (!force_update || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -70,8 +70,16 @@ struct LLFlexibleObjectSection
|
|||
//---------------------------------------------------------
|
||||
class LLVolumeImplFlexible : public LLVolumeInterface
|
||||
{
|
||||
private:
|
||||
static std::vector<LLVolumeImplFlexible*> sInstanceList;
|
||||
static std::vector<S32> sUpdateDelay;
|
||||
S32 mInstanceIndex;
|
||||
|
||||
public:
|
||||
static void updateClass();
|
||||
|
||||
LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes);
|
||||
~LLVolumeImplFlexible();
|
||||
|
||||
// Implements LLVolumeInterface
|
||||
U32 getID() const { return mID; }
|
||||
|
|
@ -79,7 +87,7 @@ class LLVolumeImplFlexible : public LLVolumeInterface
|
|||
LLQuaternion getFrameRotation() const;
|
||||
LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; }
|
||||
void updateRenderRes();
|
||||
void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
|
||||
void doIdleUpdate();
|
||||
BOOL doUpdateGeometry(LLDrawable *drawable);
|
||||
LLVector3 getPivotPosition() const;
|
||||
void onSetVolume(const LLVolumeParams &volume_params, const S32 detail);
|
||||
|
|
|
|||
|
|
@ -2362,12 +2362,6 @@ LLPanelLandAccess::~LLPanelLandAccess()
|
|||
void LLPanelLandAccess::refresh()
|
||||
{
|
||||
LLFloater* parent_floater = gFloaterView->getParentFloater(this);
|
||||
|
||||
if (mListAccess)
|
||||
mListAccess->deleteAllItems();
|
||||
if (mListBanned)
|
||||
mListBanned->deleteAllItems();
|
||||
|
||||
LLParcel *parcel = mParcel->getParcel();
|
||||
|
||||
// Display options
|
||||
|
|
@ -2385,7 +2379,11 @@ void LLPanelLandAccess::refresh()
|
|||
getChild<LLUICtrl>("GroupCheck")->setLabelArg("[GROUP]", group_name );
|
||||
|
||||
// Allow list
|
||||
if (mListAccess)
|
||||
{
|
||||
// Clear the sort order so we don't re-sort on every add.
|
||||
mListAccess->clearSortOrder();
|
||||
mListAccess->deleteAllItems();
|
||||
S32 count = parcel->mAccessList.size();
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
getChild<LLUICtrl>("AccessList")->setToolTipArg(LLStringExplicit("[MAX]"), llformat("%d",PARCEL_MAX_ACCESS_LIST));
|
||||
|
|
@ -2420,13 +2418,17 @@ void LLPanelLandAccess::refresh()
|
|||
}
|
||||
suffix.append(" " + parent_floater->getString("Remaining") + ")");
|
||||
}
|
||||
if (mListAccess)
|
||||
mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix);
|
||||
mListAccess->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix);
|
||||
}
|
||||
mListAccess->sortByName(TRUE);
|
||||
}
|
||||
|
||||
// Ban List
|
||||
if(mListBanned)
|
||||
{
|
||||
// Clear the sort order so we don't re-sort on every add.
|
||||
mListBanned->clearSortOrder();
|
||||
mListBanned->deleteAllItems();
|
||||
S32 count = parcel->mBanList.size();
|
||||
|
||||
getChild<LLUICtrl>("BannedList")->setToolTipArg(LLStringExplicit("[LISTED]"), llformat("%d",count));
|
||||
|
|
@ -2464,6 +2466,7 @@ void LLPanelLandAccess::refresh()
|
|||
}
|
||||
mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix);
|
||||
}
|
||||
mListBanned->sortByName(TRUE);
|
||||
}
|
||||
|
||||
if(parcel->getRegionDenyAnonymousOverride())
|
||||
|
|
@ -2599,13 +2602,13 @@ void LLPanelLandAccess::refresh_ui()
|
|||
getChildView("AccessList")->setEnabled(can_manage_allowed);
|
||||
S32 allowed_list_count = parcel->mAccessList.size();
|
||||
getChildView("add_allowed")->setEnabled(can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST);
|
||||
BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0;
|
||||
BOOL has_selected = (mListAccess && mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0);
|
||||
getChildView("remove_allowed")->setEnabled(can_manage_allowed && has_selected);
|
||||
|
||||
getChildView("BannedList")->setEnabled(can_manage_banned);
|
||||
S32 banned_list_count = parcel->mBanList.size();
|
||||
getChildView("add_banned")->setEnabled(can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST);
|
||||
has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0;
|
||||
has_selected = (mListBanned && mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0);
|
||||
getChildView("remove_banned")->setEnabled(can_manage_banned && has_selected);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -287,8 +287,7 @@ void LLFloaterRegionInfo::processEstateOwnerRequest(LLMessageSystem* msg,void**)
|
|||
//dispatch the message
|
||||
dispatch.dispatch(request, invoice, strings);
|
||||
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
panel->updateControls(region);
|
||||
panel->updateControls(gAgent.getRegion());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1924,10 +1923,18 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
|
|||
BOOL manager = (region && region->isEstateManager());
|
||||
setCtrlsEnabled(god || owner || manager);
|
||||
|
||||
BOOL has_allowed_avatar = getChild<LLNameListCtrl>("allowed_avatar_name_list")->getFirstSelected() ? TRUE : FALSE;
|
||||
BOOL has_allowed_group = getChild<LLNameListCtrl>("allowed_group_name_list")->getFirstSelected() ? TRUE : FALSE;
|
||||
BOOL has_banned_agent = getChild<LLNameListCtrl>("banned_avatar_name_list")->getFirstSelected() ? TRUE : FALSE;
|
||||
BOOL has_estate_manager = getChild<LLNameListCtrl>("estate_manager_name_list")->getFirstSelected() ? TRUE : FALSE;
|
||||
|
||||
getChildView("add_allowed_avatar_btn")->setEnabled(god || owner || manager);
|
||||
getChildView("remove_allowed_avatar_btn")->setEnabled(god || owner || manager);
|
||||
getChildView("remove_allowed_avatar_btn")->setEnabled(has_allowed_avatar && (god || owner || manager));
|
||||
getChildView("allowed_avatar_name_list")->setEnabled(god || owner || manager);
|
||||
|
||||
getChildView("add_allowed_group_btn")->setEnabled(god || owner || manager);
|
||||
getChildView("remove_allowed_group_btn")->setEnabled(god || owner || manager);
|
||||
getChildView("remove_allowed_group_btn")->setEnabled(has_allowed_group && (god || owner || manager) );
|
||||
getChildView("allowed_group_name_list")->setEnabled(god || owner || manager);
|
||||
|
||||
// Can't ban people from mainland, orientation islands, etc. because this
|
||||
// creates much network traffic and server load.
|
||||
|
|
@ -1935,14 +1942,15 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
|
|||
bool linden_estate = isLindenEstate();
|
||||
bool enable_ban = (god || owner || manager) && !linden_estate;
|
||||
getChildView("add_banned_avatar_btn")->setEnabled(enable_ban);
|
||||
getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban);
|
||||
getChildView("remove_banned_avatar_btn")->setEnabled(has_banned_agent && enable_ban);
|
||||
getChildView("banned_avatar_name_list")->setEnabled(god || owner || manager);
|
||||
|
||||
getChildView("message_estate_btn")->setEnabled(god || owner || manager);
|
||||
getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
|
||||
|
||||
// estate managers can't add estate managers
|
||||
getChildView("add_estate_manager_btn")->setEnabled(god || owner);
|
||||
getChildView("remove_estate_manager_btn")->setEnabled(god || owner);
|
||||
getChildView("remove_estate_manager_btn")->setEnabled(has_estate_manager && (god || owner));
|
||||
getChildView("estate_manager_name_list")->setEnabled(god || owner);
|
||||
|
||||
refresh();
|
||||
|
|
@ -1979,10 +1987,8 @@ bool LLPanelEstateInfo::refreshFromRegion(LLViewerRegion* region)
|
|||
|
||||
void LLPanelEstateInfo::updateChild(LLUICtrl* child_ctrl)
|
||||
{
|
||||
if (checkRemovalButton(child_ctrl->getName()))
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
// Ensure appropriate state of the management ui.
|
||||
updateControls(gAgent.getRegion());
|
||||
}
|
||||
|
||||
bool LLPanelEstateInfo::estateUpdate(LLMessageSystem* msg)
|
||||
|
|
@ -2080,23 +2086,8 @@ void LLPanelEstateInfo::refreshFromEstate()
|
|||
getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
|
||||
getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
|
||||
|
||||
// If visible from mainland, disable the access allowed
|
||||
// UI, as anyone can teleport there.
|
||||
// However, gods need to be able to edit the access list for
|
||||
// linden estates, regardless of visibility, to allow object
|
||||
// and L$ transfers.
|
||||
{
|
||||
bool visible_from_mainland = estate_info.getIsExternallyVisible();
|
||||
bool god = gAgent.isGodlike();
|
||||
bool linden_estate = isLindenEstate();
|
||||
|
||||
bool enable_agent = (!visible_from_mainland || (god && linden_estate));
|
||||
bool enable_group = enable_agent;
|
||||
bool enable_ban = !linden_estate;
|
||||
|
||||
setAccessAllowedEnabled(enable_agent, enable_group, enable_ban);
|
||||
}
|
||||
|
||||
// Ensure appriopriate state of the management UI
|
||||
updateControls(gAgent.getRegion());
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
|
@ -2225,47 +2216,6 @@ void LLPanelEstateInfo::setOwnerName(const std::string& name)
|
|||
getChild<LLUICtrl>("estate_owner")->setValue(LLSD(name));
|
||||
}
|
||||
|
||||
void LLPanelEstateInfo::setAccessAllowedEnabled(bool enable_agent,
|
||||
bool enable_group,
|
||||
bool enable_ban)
|
||||
{
|
||||
getChildView("allow_resident_label")->setEnabled(enable_agent);
|
||||
getChildView("allowed_avatar_name_list")->setEnabled(enable_agent);
|
||||
getChildView("allowed_avatar_name_list")->setVisible( enable_agent);
|
||||
getChildView("add_allowed_avatar_btn")->setEnabled(enable_agent);
|
||||
getChildView("remove_allowed_avatar_btn")->setEnabled(enable_agent);
|
||||
|
||||
// Groups
|
||||
getChildView("allow_group_label")->setEnabled(enable_group);
|
||||
getChildView("allowed_group_name_list")->setEnabled(enable_group);
|
||||
getChildView("allowed_group_name_list")->setVisible( enable_group);
|
||||
getChildView("add_allowed_group_btn")->setEnabled(enable_group);
|
||||
getChildView("remove_allowed_group_btn")->setEnabled(enable_group);
|
||||
|
||||
// Ban
|
||||
getChildView("ban_resident_label")->setEnabled(enable_ban);
|
||||
getChildView("banned_avatar_name_list")->setEnabled(enable_ban);
|
||||
getChildView("banned_avatar_name_list")->setVisible( enable_ban);
|
||||
getChildView("add_banned_avatar_btn")->setEnabled(enable_ban);
|
||||
getChildView("remove_banned_avatar_btn")->setEnabled(enable_ban);
|
||||
|
||||
// Update removal buttons if needed
|
||||
if (enable_agent)
|
||||
{
|
||||
checkRemovalButton("allowed_avatar_name_list");
|
||||
}
|
||||
|
||||
if (enable_group)
|
||||
{
|
||||
checkRemovalButton("allowed_group_name_list");
|
||||
}
|
||||
|
||||
if (enable_ban)
|
||||
{
|
||||
checkRemovalButton("banned_avatar_name_list");
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelEstateInfo::clearAccessLists()
|
||||
{
|
||||
LLNameListCtrl* name_list = getChild<LLNameListCtrl>("allowed_avatar_name_list");
|
||||
|
|
@ -2279,39 +2229,7 @@ void LLPanelEstateInfo::clearAccessLists()
|
|||
{
|
||||
name_list->deleteAllItems();
|
||||
}
|
||||
}
|
||||
|
||||
// enables/disables the "remove" button for the various allow/ban lists
|
||||
BOOL LLPanelEstateInfo::checkRemovalButton(std::string name)
|
||||
{
|
||||
std::string btn_name = "";
|
||||
if (name == "allowed_avatar_name_list")
|
||||
{
|
||||
btn_name = "remove_allowed_avatar_btn";
|
||||
}
|
||||
else if (name == "allowed_group_name_list")
|
||||
{
|
||||
btn_name = "remove_allowed_group_btn";
|
||||
}
|
||||
else if (name == "banned_avatar_name_list")
|
||||
{
|
||||
btn_name = "remove_banned_avatar_btn";
|
||||
}
|
||||
else if (name == "estate_manager_name_list")
|
||||
{
|
||||
//ONLY OWNER CAN ADD /DELET ESTATE MANAGER
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region && (region->getOwner() == gAgent.getID()))
|
||||
{
|
||||
btn_name = "remove_estate_manager_btn";
|
||||
}
|
||||
}
|
||||
|
||||
// enable the remove button if something is selected
|
||||
LLNameListCtrl* name_list = getChild<LLNameListCtrl>(name);
|
||||
getChildView(btn_name)->setEnabled(name_list && name_list->getFirstSelected() ? TRUE : FALSE);
|
||||
|
||||
return (btn_name != "");
|
||||
updateControls(gAgent.getRegion());
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -2792,15 +2710,15 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
|
||||
if (allowed_agent_name_list)
|
||||
{
|
||||
//allowed_agent_name_list->deleteAllItems();
|
||||
// Don't sort these as we add them, sort them when we are done.
|
||||
allowed_agent_name_list->clearSortOrder();
|
||||
for (S32 i = 0; i < num_allowed_agents && i < ESTATE_MAX_ACCESS_IDS; i++)
|
||||
{
|
||||
LLUUID id;
|
||||
memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */
|
||||
allowed_agent_name_list->addNameItem(id);
|
||||
}
|
||||
panel->getChildView("remove_allowed_avatar_btn")->setEnabled(allowed_agent_name_list->getFirstSelected() ? TRUE : FALSE);
|
||||
allowed_agent_name_list->sortByColumnIndex(0, TRUE);
|
||||
allowed_agent_name_list->sortByName(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2817,6 +2735,8 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
|
||||
if (allowed_group_name_list)
|
||||
{
|
||||
// Don't sort these as we add them, sort them when we are done.
|
||||
allowed_group_name_list->clearSortOrder();
|
||||
allowed_group_name_list->deleteAllItems();
|
||||
for (S32 i = 0; i < num_allowed_groups && i < ESTATE_MAX_GROUP_IDS; i++)
|
||||
{
|
||||
|
|
@ -2824,8 +2744,7 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */
|
||||
allowed_group_name_list->addGroupNameItem(id);
|
||||
}
|
||||
panel->getChildView("remove_allowed_group_btn")->setEnabled(allowed_group_name_list->getFirstSelected() ? TRUE : FALSE);
|
||||
allowed_group_name_list->sortByColumnIndex(0, TRUE);
|
||||
allowed_group_name_list->sortByName(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2849,15 +2768,16 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
|
||||
if (banned_agent_name_list)
|
||||
{
|
||||
//banned_agent_name_list->deleteAllItems();
|
||||
// Don't sort these as we add them, sort them when we are done.
|
||||
banned_agent_name_list->clearSortOrder();
|
||||
|
||||
for (S32 i = 0; i < num_banned_agents && i < ESTATE_MAX_ACCESS_IDS; i++)
|
||||
{
|
||||
LLUUID id;
|
||||
memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */
|
||||
banned_agent_name_list->addNameItem(id);
|
||||
}
|
||||
panel->getChildView("remove_banned_avatar_btn")->setEnabled(banned_agent_name_list->getFirstSelected() ? TRUE : FALSE);
|
||||
banned_agent_name_list->sortByColumnIndex(0, TRUE);
|
||||
banned_agent_name_list->sortByName(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2872,6 +2792,9 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
panel->getChild<LLNameListCtrl>("estate_manager_name_list");
|
||||
if (estate_manager_name_list)
|
||||
{
|
||||
// Don't sort these as we add them, sort them when we are done.
|
||||
estate_manager_name_list->clearSortOrder();
|
||||
|
||||
estate_manager_name_list->deleteAllItems(); // Clear existing entries
|
||||
|
||||
// There should be only ESTATE_MAX_MANAGERS people in the list, but if the database gets more (SL-46107) don't
|
||||
|
|
@ -2883,11 +2806,13 @@ bool LLDispatchSetEstateAccess::operator()(
|
|||
memcpy(id.mData, strings[index++].data(), UUID_BYTES); /* Flawfinder: ignore */
|
||||
estate_manager_name_list->addNameItem(id);
|
||||
}
|
||||
panel->getChildView("remove_estate_manager_btn")->setEnabled(estate_manager_name_list->getFirstSelected() ? TRUE : FALSE);
|
||||
estate_manager_name_list->sortByColumnIndex(0, TRUE);
|
||||
estate_manager_name_list->sortByName(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the buttons which may change based on the list contents but also needs to account for general access features.
|
||||
panel->updateControls(gAgent.getRegion());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -312,9 +312,6 @@ public:
|
|||
const std::string getOwnerName() const;
|
||||
void setOwnerName(const std::string& name);
|
||||
|
||||
// If visible from mainland, allowed agent and allowed groups
|
||||
// are ignored, so must disable UI.
|
||||
void setAccessAllowedEnabled(bool enable_agent, bool enable_group, bool enable_ban);
|
||||
protected:
|
||||
virtual BOOL sendUpdate();
|
||||
// confirmation dialog callback
|
||||
|
|
@ -324,7 +321,6 @@ protected:
|
|||
void commitEstateManagers();
|
||||
|
||||
void clearAccessLists();
|
||||
BOOL checkRemovalButton(std::string name);
|
||||
BOOL checkSunHourSlider(LLUICtrl* child_ctrl);
|
||||
|
||||
U32 mEstateID;
|
||||
|
|
|
|||
|
|
@ -59,12 +59,15 @@ LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key)
|
|||
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this));
|
||||
mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this));
|
||||
}
|
||||
//----------------------------------------------
|
||||
|
||||
BOOL LLFloaterTextureFetchDebugger::postBuild(void)
|
||||
{
|
||||
mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger();
|
||||
mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
|
||||
|
||||
//set states for buttons
|
||||
mButtonStateMap["start_btn"] = true;
|
||||
|
|
@ -76,8 +79,10 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void)
|
|||
mButtonStateMap["decode_btn"] = false;
|
||||
mButtonStateMap["gl_btn"] = false;
|
||||
|
||||
mButtonStateMap["refetchviscache_btn"] = true;
|
||||
mButtonStateMap["refetchvishttp_btn"] = true;
|
||||
mButtonStateMap["refetchviscache_btn"] = false;
|
||||
mButtonStateMap["refetchvishttp_btn"] = false;
|
||||
mButtonStateMap["refetchallcache_btn"] = false;
|
||||
mButtonStateMap["refetchallhttp_btn"] = false;
|
||||
|
||||
updateButtons();
|
||||
|
||||
|
|
@ -89,7 +94,7 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void)
|
|||
LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger()
|
||||
{
|
||||
//stop everything
|
||||
mDebugger->stopDebug();
|
||||
mDebugger->setStopDebug();
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::updateButtons()
|
||||
|
|
@ -118,47 +123,81 @@ void LLFloaterTextureFetchDebugger::disableButtons()
|
|||
childDisable("gl_btn");
|
||||
childDisable("refetchviscache_btn");
|
||||
childDisable("refetchvishttp_btn");
|
||||
childDisable("refetchallcache_btn");
|
||||
childDisable("refetchallhttp_btn");
|
||||
}
|
||||
void LLFloaterTextureFetchDebugger::setStartStatus(S32 status)
|
||||
{
|
||||
llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ;
|
||||
mStartStatus = status;
|
||||
}
|
||||
|
||||
bool LLFloaterTextureFetchDebugger::idleStart()
|
||||
{
|
||||
if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE)
|
||||
{
|
||||
mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus);
|
||||
mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::idle()
|
||||
{
|
||||
LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();
|
||||
|
||||
if(mDebugger->update())
|
||||
if(idleStart())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const F32 max_time = 0.005f; //5ms
|
||||
LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();
|
||||
if(mDebugger->update(max_time))
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case LLTextureFetchDebugger::IDLE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::READ_CACHE:
|
||||
mButtonStateMap["cachewrite_btn"] = true;
|
||||
mButtonStateMap["decode_btn"] = true;
|
||||
updateButtons();
|
||||
case LLTextureFetchDebugger::START_DEBUG:
|
||||
mButtonStateMap["cacheread_btn"] = true;
|
||||
mButtonStateMap["http_btn"] = true;
|
||||
mButtonStateMap["refetchviscache_btn"] = true;
|
||||
mButtonStateMap["refetchvishttp_btn"] = true;
|
||||
mButtonStateMap["refetchallcache_btn"] = true;
|
||||
mButtonStateMap["refetchallhttp_btn"] = true;
|
||||
break;
|
||||
case LLTextureFetchDebugger::WRITE_CACHE:
|
||||
updateButtons();
|
||||
case LLTextureFetchDebugger::READ_CACHE:
|
||||
mButtonStateMap["decode_btn"] = true;
|
||||
break;
|
||||
case LLTextureFetchDebugger::WRITE_CACHE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::DECODING:
|
||||
mButtonStateMap["gl_btn"] = true;
|
||||
updateButtons();
|
||||
mButtonStateMap["gl_btn"] = true;
|
||||
break;
|
||||
case LLTextureFetchDebugger::HTTP_FETCHING:
|
||||
mButtonStateMap["cacheread_btn"] = true;
|
||||
mButtonStateMap["cachewrite_btn"] = true;
|
||||
mButtonStateMap["decode_btn"] = true;
|
||||
updateButtons();
|
||||
mButtonStateMap["decode_btn"] = true;
|
||||
break;
|
||||
case LLTextureFetchDebugger::GL_TEX:
|
||||
updateButtons();
|
||||
case LLTextureFetchDebugger::GL_TEX:
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_VIS_CACHE:
|
||||
updateButtons();
|
||||
case LLTextureFetchDebugger::REFETCH_VIS_HTTP:
|
||||
updateButtons();
|
||||
case LLTextureFetchDebugger::REFETCH_VIS_CACHE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_VIS_HTTP:
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_ALL_CACHE:
|
||||
break;
|
||||
case LLTextureFetchDebugger::REFETCH_ALL_HTTP:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(state != LLTextureFetchDebugger::IDLE)
|
||||
{
|
||||
updateButtons();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -172,11 +211,10 @@ void LLFloaterTextureFetchDebugger::onClickStart()
|
|||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->startDebug();
|
||||
setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG);
|
||||
|
||||
mButtonStateMap["start_btn"] = false;
|
||||
mButtonStateMap["cacheread_btn"] = true;
|
||||
mButtonStateMap["http_btn"] = true;
|
||||
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +223,9 @@ void LLFloaterTextureFetchDebugger::onClickClose()
|
|||
setVisible(FALSE);
|
||||
|
||||
//stop everything
|
||||
mDebugger->stopDebug();
|
||||
mDebugger->setStopDebug();
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickClear()
|
||||
|
|
@ -203,7 +243,7 @@ void LLFloaterTextureFetchDebugger::onClickClear()
|
|||
updateButtons();
|
||||
|
||||
//stop everything
|
||||
mDebugger->stopDebug();
|
||||
mDebugger->setStopDebug();
|
||||
mDebugger->clearHistory();
|
||||
}
|
||||
|
||||
|
|
@ -211,49 +251,63 @@ void LLFloaterTextureFetchDebugger::onClickCacheRead()
|
|||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugCacheRead();
|
||||
setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickCacheWrite()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugCacheWrite();
|
||||
setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickHTTPLoad()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugHTTP();
|
||||
setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickDecode()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugDecoder();
|
||||
setStartStatus((S32)LLTextureFetchDebugger::DECODING);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickGLTexture()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugGLTextureCreation();
|
||||
setStartStatus((S32)LLTextureFetchDebugger::GL_TEX);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchVisCache()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugRefetchVisibleFromCache();
|
||||
setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
mDebugger->debugRefetchVisibleFromHTTP();
|
||||
setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchAllCache()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP()
|
||||
{
|
||||
disableButtons();
|
||||
|
||||
setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP);
|
||||
}
|
||||
|
||||
void LLFloaterTextureFetchDebugger::draw()
|
||||
|
|
@ -368,8 +422,22 @@ void LLFloaterTextureFetchDebugger::draw()
|
|||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on refetching all textures from cache
|
||||
if(mDebugger->getRefetchAllCacheTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on refetching visible textures from http
|
||||
|
|
@ -382,8 +450,22 @@ void LLFloaterTextureFetchDebugger::draw()
|
|||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
//total time on refetching all textures from http
|
||||
if(mDebugger->getRefetchAllHTTPTime() < 0.f)
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----"));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime()));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10));
|
||||
getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));
|
||||
}
|
||||
|
||||
LLFloater::draw();
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ public:
|
|||
|
||||
void onClickRefetchVisCache();
|
||||
void onClickRefetchVisHTTP();
|
||||
void onClickRefetchAllCache();
|
||||
void onClickRefetchAllHTTP();
|
||||
public:
|
||||
void idle() ;
|
||||
|
||||
|
|
@ -63,9 +65,12 @@ private:
|
|||
void updateButtons();
|
||||
void disableButtons();
|
||||
|
||||
void setStartStatus(S32 status);
|
||||
bool idleStart();
|
||||
private:
|
||||
LLTextureFetchDebugger* mDebugger;
|
||||
std::map<std::string, bool> mButtonStateMap;
|
||||
S32 mStartStatus;
|
||||
};
|
||||
|
||||
#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key)
|
|||
mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this));
|
||||
mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this));
|
||||
mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this));
|
||||
mCommitCallbackRegistrar.add("TopObjects.GetByParcelName", boost::bind(&LLFloaterTopObjects::onGetByParcelName, this));
|
||||
mCommitCallbackRegistrar.add("TopObjects.CommitObjectsList",boost::bind(&LLFloaterTopObjects::onCommitObjectsList, this));
|
||||
}
|
||||
|
||||
|
|
@ -99,21 +100,6 @@ BOOL LLFloaterTopObjects::postBuild()
|
|||
|
||||
setDefaultBtn("show_beacon_btn");
|
||||
|
||||
/*
|
||||
LLLineEditor* line_editor = getChild<LLLineEditor>("owner_name_editor");
|
||||
if (line_editor)
|
||||
{
|
||||
line_editor->setCommitOnFocusLost(FALSE);
|
||||
line_editor->setCommitCallback(onGetByOwnerName, this);
|
||||
}
|
||||
|
||||
line_editor = getChild<LLLineEditor>("object_name_editor");
|
||||
if (line_editor)
|
||||
{
|
||||
line_editor->setCommitOnFocusLost(FALSE);
|
||||
line_editor->setCommitCallback(onGetByObjectName, this);
|
||||
}*/
|
||||
|
||||
mCurrentMode = STAT_REPORT_TOP_SCRIPTS;
|
||||
mFlags = 0;
|
||||
mFilter.clear();
|
||||
|
|
@ -168,9 +154,11 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
|
|||
F32 score;
|
||||
std::string name_buf;
|
||||
std::string owner_buf;
|
||||
std::string parcel_buf("unknown");
|
||||
F32 mono_score = 0.f;
|
||||
bool have_extended_data = false;
|
||||
S32 public_urls = 0;
|
||||
F32 script_memory = 0.f;
|
||||
|
||||
msg->getU32Fast(_PREHASH_ReportData, _PREHASH_TaskLocalID, task_local_id, block);
|
||||
msg->getUUIDFast(_PREHASH_ReportData, _PREHASH_TaskID, task_id, block);
|
||||
|
|
@ -180,12 +168,18 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
|
|||
msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);
|
||||
msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);
|
||||
msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block);
|
||||
|
||||
if(msg->has("DataExtended"))
|
||||
{
|
||||
have_extended_data = true;
|
||||
msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
|
||||
msg->getF32("DataExtended", "MonoScore", mono_score, block);
|
||||
msg->getS32("DataExtended", "PublicURLs", public_urls, block);
|
||||
if (msg->getSize("DataExtended", "ParcelName") > 0)
|
||||
{
|
||||
msg->getString("DataExtended", "ParcelName", parcel_buf, block);
|
||||
msg->getF32("DataExtended", "Size", script_memory, block);
|
||||
}
|
||||
}
|
||||
|
||||
LLSD element;
|
||||
|
|
@ -193,13 +187,14 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
|
|||
element["id"] = task_id;
|
||||
|
||||
LLSD columns;
|
||||
columns[0]["column"] = "score";
|
||||
columns[0]["value"] = llformat("%0.3f", score);
|
||||
columns[0]["font"] = "SANSSERIF";
|
||||
S32 column_num = 0;
|
||||
columns[column_num]["column"] = "score";
|
||||
columns[column_num]["value"] = llformat("%0.3f", score);
|
||||
columns[column_num++]["font"] = "SANSSERIF";
|
||||
|
||||
columns[1]["column"] = "name";
|
||||
columns[1]["value"] = name_buf;
|
||||
columns[1]["font"] = "SANSSERIF";
|
||||
columns[column_num]["column"] = "name";
|
||||
columns[column_num]["value"] = name_buf;
|
||||
columns[column_num++]["font"] = "SANSSERIF";
|
||||
|
||||
// Owner names can have trailing spaces sent from server
|
||||
LLStringUtil::trim(owner_buf);
|
||||
|
|
@ -215,28 +210,33 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
|
|||
// ...just strip out legacy "Resident" name
|
||||
owner_buf = LLCacheName::cleanFullName(owner_buf);
|
||||
}
|
||||
columns[2]["column"] = "owner";
|
||||
columns[2]["value"] = owner_buf;
|
||||
columns[2]["font"] = "SANSSERIF";
|
||||
columns[column_num]["column"] = "owner";
|
||||
columns[column_num]["value"] = owner_buf;
|
||||
columns[column_num++]["font"] = "SANSSERIF";
|
||||
|
||||
columns[3]["column"] = "location";
|
||||
columns[3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
|
||||
columns[3]["font"] = "SANSSERIF";
|
||||
columns[4]["column"] = "time";
|
||||
columns[4]["type"] = "date";
|
||||
columns[4]["value"] = LLDate((time_t)time_stamp);
|
||||
columns[4]["font"] = "SANSSERIF";
|
||||
columns[column_num]["column"] = "location";
|
||||
columns[column_num]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
|
||||
columns[column_num++]["font"] = "SANSSERIF";
|
||||
|
||||
columns[column_num]["column"] = "parcel";
|
||||
columns[column_num]["value"] = parcel_buf;
|
||||
columns[column_num++]["font"] = "SANSSERIF";
|
||||
|
||||
columns[column_num]["column"] = "time";
|
||||
columns[column_num]["type"] = "date";
|
||||
columns[column_num]["value"] = LLDate((time_t)time_stamp);
|
||||
columns[column_num++]["font"] = "SANSSERIF";
|
||||
|
||||
if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS
|
||||
&& have_extended_data)
|
||||
{
|
||||
columns[5]["column"] = "mono_time";
|
||||
columns[5]["value"] = llformat("%0.3f", mono_score);
|
||||
columns[5]["font"] = "SANSSERIF";
|
||||
columns[column_num]["column"] = "memory";
|
||||
columns[column_num]["value"] = llformat("%0.0f", (script_memory / 1000.f));
|
||||
columns[column_num++]["font"] = "SANSSERIF";
|
||||
|
||||
columns[6]["column"] = "URLs";
|
||||
columns[6]["value"] = llformat("%d", public_urls);
|
||||
columns[6]["font"] = "SANSSERIF";
|
||||
columns[column_num]["column"] = "URLs";
|
||||
columns[column_num]["value"] = llformat("%d", public_urls);
|
||||
columns[column_num++]["font"] = "SANSSERIF";
|
||||
}
|
||||
element["columns"] = columns;
|
||||
list->addElement(element);
|
||||
|
|
@ -260,18 +260,18 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
|
|||
{
|
||||
setTitle(getString("top_scripts_title"));
|
||||
list->setColumnLabel("score", getString("scripts_score_label"));
|
||||
list->setColumnLabel("mono_time", getString("scripts_mono_time_label"));
|
||||
|
||||
LLUIString format = getString("top_scripts_text");
|
||||
format.setArg("[COUNT]", llformat("%d", total_count));
|
||||
format.setArg("[TIME]", llformat("%0.1f", mtotalScore));
|
||||
format.setArg("[TIME]", llformat("%0.3f", mtotalScore));
|
||||
getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
|
||||
}
|
||||
else
|
||||
{
|
||||
setTitle(getString("top_colliders_title"));
|
||||
list->setColumnLabel("score", getString("colliders_score_label"));
|
||||
list->setColumnLabel("mono_time", "");
|
||||
list->setColumnLabel("URLs", "");
|
||||
list->setColumnLabel("memory", "");
|
||||
LLUIString format = getString("top_colliders_text");
|
||||
format.setArg("[COUNT]", llformat("%d", total_count));
|
||||
getChild<LLUICtrl>("title_text")->setValue(LLSD(format));
|
||||
|
|
@ -301,6 +301,7 @@ void LLFloaterTopObjects::updateSelectionInfo()
|
|||
{
|
||||
getChild<LLUICtrl>("object_name_editor")->setValue(sli->getColumn(1)->getValue().asString());
|
||||
getChild<LLUICtrl>("owner_name_editor")->setValue(sli->getColumn(2)->getValue().asString());
|
||||
getChild<LLUICtrl>("parcel_name_editor")->setValue(sli->getColumn(4)->getValue().asString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -480,6 +481,15 @@ void LLFloaterTopObjects::onGetByOwnerName()
|
|||
onRefresh();
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterTopObjects::onGetByParcelName()
|
||||
{
|
||||
mFlags = STAT_FILTER_BY_PARCEL_NAME;
|
||||
mFilter = getChild<LLUICtrl>("parcel_name_editor")->getValue().asString();
|
||||
onRefresh();
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterTopObjects::showBeacon()
|
||||
{
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("objects_list");
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue