diff options
48 files changed, 1184 insertions, 510 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt index 32ae801d19..212dffda31 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -366,12 +366,13 @@ JB Kraft Joghert LeSabre VWR-64 Jonathan Yap - VWR-17801 + STORM-596 STORM-523 STORM-616 STORM-679 - STORM-596 + STORM-737 STORM-726 + VWR-17801 STORM-785 Kage Pixel VWR-11 @@ -750,6 +751,8 @@ Tue Torok CT-74 Twisted Laws SNOW-352 + STORM-466 + STORM-467 Vadim Bigbear VWR-2681 Vector Hastings diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index 0828635881..bd594b06cf 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -860,6 +860,9 @@ U64 LLFastTimer::getCPUClockCount64() } return ret_val; } + +std::string LLFastTimer::sClockType = "rdtsc"; + #else //LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp // These use QueryPerformanceCounter, which is arguably fine and also works on amd architectures. @@ -872,6 +875,8 @@ U64 LLFastTimer::getCPUClockCount64() { return get_clock_count(); } + +std::string LLFastTimer::sClockType = "QueryPerformanceCounter"; #endif #endif @@ -904,6 +909,9 @@ U32 LLFastTimer::getCPUClockCount32() { return (U32)(LLFastTimer::getCPUClockCount64() >> 8); } + +std::string LLFastTimer::sClockType = "clock_gettime"; + #endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) @@ -923,23 +931,7 @@ U64 LLFastTimer::getCPUClockCount64() __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); return x; } -#endif - - -#if ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__))) -// -// Mac PPC (deprecated) implementation of CPU clock -// -// Just use gettimeofday implementation for now -U32 LLFastTimer::getCPUClockCount32() -{ - return (U32)(get_clock_count()>>8); -} - -U64 LLFastTimer::getCPUClockCount64() -{ - return get_clock_count(); -} +std::string LLFastTimer::sClockType = "rdtsc"; #endif diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h index 038a2d246a..827747f0c6 100644 --- a/indra/llcommon/llfasttimer_class.h +++ b/indra/llcommon/llfasttimer_class.h @@ -180,8 +180,10 @@ public: sTimerCycles += timer_end - timer_start; #endif #if DEBUG_FAST_TIMER_THREADS +#if !LL_RELEASE assert_main_thread(); #endif +#endif } LL_FORCE_INLINE ~LLFastTimer() @@ -251,6 +253,7 @@ public: U32 mChildTime; }; static CurTimerData sCurTimerData; + static std::string sClockType; private: static U32 getCPUClockCount32(); diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp index 55d0c85cbd..e1876599fc 100644 --- a/indra/llcommon/llrefcount.cpp +++ b/indra/llcommon/llrefcount.cpp @@ -29,9 +29,25 @@ #include "llerror.h" +#if LL_REF_COUNT_DEBUG +#include "llthread.h" +#include "llapr.h" +#endif + LLRefCount::LLRefCount(const LLRefCount& other) : mRef(0) { +#if LL_REF_COUNT_DEBUG + if(gAPRPoolp) + { + mMutexp = new LLMutex(gAPRPoolp) ; + } + else + { + mMutexp = NULL ; + } + mCrashAtUnlock = FALSE ; +#endif } LLRefCount& LLRefCount::operator=(const LLRefCount&) @@ -43,6 +59,17 @@ LLRefCount& LLRefCount::operator=(const LLRefCount&) LLRefCount::LLRefCount() : mRef(0) { +#if LL_REF_COUNT_DEBUG + if(gAPRPoolp) + { + mMutexp = new LLMutex(gAPRPoolp) ; + } + else + { + mMutexp = NULL ; + } + mCrashAtUnlock = FALSE ; +#endif } LLRefCount::~LLRefCount() @@ -51,4 +78,87 @@ LLRefCount::~LLRefCount() { llerrs << "deleting non-zero reference" << llendl; } + +#if LL_REF_COUNT_DEBUG + if(gAPRPoolp) + { + delete mMutexp ; + } +#endif } + +#if LL_REF_COUNT_DEBUG +void LLRefCount::ref() const +{ + if(mMutexp) + { + if(mMutexp->isLocked()) + { + mCrashAtUnlock = TRUE ; + llerrs << "the mutex is locked by the thread: " << mLockedThreadID + << " Current thread: " << LLThread::currentID() << llendl ; + } + + mMutexp->lock() ; + mLockedThreadID = LLThread::currentID() ; + + mRef++; + + if(mCrashAtUnlock) + { + while(1); //crash here. + } + mMutexp->unlock() ; + } + else + { + mRef++; + } +} + +S32 LLRefCount::unref() const +{ + if(mMutexp) + { + if(mMutexp->isLocked()) + { + mCrashAtUnlock = TRUE ; + llerrs << "the mutex is locked by the thread: " << mLockedThreadID + << " Current thread: " << LLThread::currentID() << llendl ; + } + + mMutexp->lock() ; + mLockedThreadID = LLThread::currentID() ; + + llassert(mRef >= 1); + if (0 == --mRef) + { + if(mCrashAtUnlock) + { + while(1); //crash here. + } + mMutexp->unlock() ; + + delete this; + return 0; + } + + if(mCrashAtUnlock) + { + while(1); //crash here. + } + mMutexp->unlock() ; + return mRef; + } + else + { + llassert(mRef >= 1); + if (0 == --mRef) + { + delete this; + return 0; + } + return mRef; + } +} +#endif diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 19f008b15c..8eb5d53f3f 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -28,6 +28,11 @@ #include <boost/noncopyable.hpp> +#define LL_REF_COUNT_DEBUG 0 +#if LL_REF_COUNT_DEBUG +class LLMutex ; +#endif + //---------------------------------------------------------------------------- // RefCount objects should generally only be accessed by way of LLPointer<>'s // see llthread.h for LLThreadSafeRefCount @@ -43,12 +48,16 @@ protected: public: LLRefCount(); - void ref() const +#if LL_REF_COUNT_DEBUG + void ref() const ; + S32 unref() const ; +#else + inline void ref() const { mRef++; } - S32 unref() const + inline S32 unref() const { llassert(mRef >= 1); if (0 == --mRef) @@ -58,6 +67,7 @@ public: } return mRef; } +#endif //NOTE: when passing around a const LLRefCount object, this can return different results // at different types, since mRef is mutable @@ -68,6 +78,12 @@ public: private: mutable S32 mRef; + +#if LL_REF_COUNT_DEBUG + LLMutex* mMutexp ; + mutable U32 mLockedThreadID ; + mutable BOOL mCrashAtUnlock ; +#endif }; #endif diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index 6834267d4b..ea8c1a1107 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -3,12 +3,13 @@ project(llimage) include(00-Common) -include(LLAddBuildTest) include(LLCommon) include(LLImage) include(LLMath) include(LLVFS) include(ZLIB) +include(LLAddBuildTest) +include(Tut) include_directories( ${LLCOMMON_INCLUDE_DIRS} @@ -63,4 +64,12 @@ target_link_libraries(llimage ) # Add tests -#ADD_BUILD_TEST(llimageworker llimage) +if (LL_TESTS) + SET(llimage_TEST_SOURCE_FILES + llimageworker.cpp + ) + LL_ADD_PROJECT_UNIT_TESTS(llimage "${llimage_TEST_SOURCE_FILES}") +endif (LL_TESTS) + + + diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index a109276709..08476fb72c 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -26,10 +26,8 @@ */ // Precompiled header: almost always required for newview cpp files -#include <list> -#include <map> -#include <algorithm> -// Class to test +#include "linden_common.h" +// Class to test #include "../llimageworker.h" // For timer class #include "../llcommon/lltimer.h" @@ -44,7 +42,17 @@ // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code) // * A simulator for a class can be implemented here. Please comment and document thoroughly. -LLImageBase::LLImageBase() {} +LLImageBase::LLImageBase() +: mData(NULL), +mDataSize(0), +mWidth(0), +mHeight(0), +mComponents(0), +mBadBufferAllocation(false), +mAllowOverSize(false), +mMemType(LLMemType::MTYPE_IMAGEBASE) +{ +} LLImageBase::~LLImageBase() {} void LLImageBase::dump() { } void LLImageBase::sanityCheck() { } diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 95e0997d5b..13b12c0928 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -90,6 +90,12 @@ void info_callback(const char* msg, void*) lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl; } +// Divide a by 2 to the power of b and round upwards +int ceildivpow2(int a, int b) +{ + return (a + (1 << b) - 1) >> b; +} + LLImageJ2COJ::LLImageJ2COJ() : LLImageJ2CImpl() diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h index 7edacbe97c..9476665ccb 100644 --- a/indra/llimagej2coj/llimagej2coj.h +++ b/indra/llimagej2coj/llimagej2coj.h @@ -34,17 +34,11 @@ class LLImageJ2COJ : public LLImageJ2CImpl public: LLImageJ2COJ(); virtual ~LLImageJ2COJ(); - protected: /*virtual*/ BOOL getMetadata(LLImageJ2C &base); /*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count); /*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0, BOOL reversible = FALSE); - int ceildivpow2(int a, int b) - { - // Divide a by b to the power of 2 and round upwards. - return (a + (1 << b) - 1) >> b; - } }; #endif diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index b8b44b44fc..7ed1c6c694 100644 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -42,4 +42,14 @@ list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES}) if (USE_KDU) add_library (${LLKDU_LIBRARIES} ${llkdu_SOURCE_FILES}) + # Add tests + if (LL_TESTS) + include(LLAddBuildTest) + include(Tut) + SET(llkdu_TEST_SOURCE_FILES + llimagej2ckdu.cpp + ) + LL_ADD_PROJECT_UNIT_TESTS(llkdu "${llkdu_TEST_SOURCE_FILES}") + endif (LL_TESTS) + endif (USE_KDU) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 1a286d1406..10ea5685e8 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -229,16 +229,17 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod mCodeStreamp = NULL; } - if (!mInputp) + if (!mInputp && base.getData()) { - llassert(base.getData()); // The compressed data has been loaded - // Setup the source for the codestrea + // Setup the source for the codestream mInputp = new LLKDUMemSource(base.getData(), data_size); } - llassert(mInputp); - mInputp->reset(); + if (mInputp) + { + mInputp->reset(); + } mCodeStreamp = new kdu_codestream; mCodeStreamp->create(mInputp); @@ -1017,7 +1018,7 @@ kdc_flow_control::kdc_flow_control (kdu_image_in_base *img_in, kdu_codestream co comp->ratio_counter = 0; comp->remaining_lines = comp->initial_lines = dims.size.y; } - assert(num_components > 0); + assert(num_components >= 0); tile.set_components_of_interest(num_components); max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false); diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 03f289f8b1..5628f69eeb 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -50,17 +50,16 @@ public: MODE_RESILIENT = 1, MODE_FUSSY = 2 }; - -public: LLImageJ2CKDU(); virtual ~LLImageJ2CKDU(); - + protected: /*virtual*/ BOOL getMetadata(LLImageJ2C &base); /*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count); /*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0, BOOL reversible=FALSE); +private: void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode); void cleanupCodeStream(); BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count ); diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp new file mode 100644 index 0000000000..1ccee4bb64 --- /dev/null +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -0,0 +1,248 @@ +/** + * @file llimagej2ckdu_test.cpp + * @author Merov Linden + * @date 2010-12-17 + * + * $LicenseInfo:firstyear=2006&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +// Class to test +#include "../llimagej2ckdu.h" +#include "../llkdumem.h" +// Tut header +#include "../test/lltut.h" + +// ------------------------------------------------------------------------------------------- +// Stubbing: Declarations required to link and run the class being tested +// Notes: +// * Add here stubbed implementation of the few classes and methods used in the class to be tested +// * Add as little as possible (let the link errors guide you) +// * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code) +// * A simulator for a class can be implemented here. Please comment and document thoroughly. + +// End Stubbing +// ------------------------------------------------------------------------------------------- +// Stubb the LL Image Classes +LLImageRaw::LLImageRaw() { } +LLImageRaw::~LLImageRaw() { } +U8* LLImageRaw::allocateData(S32 ) { return NULL; } +void LLImageRaw::deleteData() { } +U8* LLImageRaw::reallocateData(S32 ) { return NULL; } +BOOL LLImageRaw::resize(U16, U16, S8) { return TRUE; } // this method always returns TRUE... + +LLImageBase::LLImageBase() +: mData(NULL), +mDataSize(0), +mWidth(0), +mHeight(0), +mComponents(0), +mBadBufferAllocation(false), +mAllowOverSize(false), +mMemType(LLMemType::MTYPE_IMAGEBASE) +{ } +LLImageBase::~LLImageBase() { } +U8* LLImageBase::allocateData(S32 ) { return NULL; } +void LLImageBase::deleteData() { } +void LLImageBase::dump() { } +const U8* LLImageBase::getData() const { return NULL; } +U8* LLImageBase::getData() { return NULL; } +U8* LLImageBase::reallocateData(S32 ) { return NULL; } +void LLImageBase::sanityCheck() { } +void LLImageBase::setSize(S32 , S32 , S32 ) { } + +LLImageJ2CImpl::~LLImageJ2CImpl() { } + +LLImageFormatted::LLImageFormatted(S8 ) { } +LLImageFormatted::~LLImageFormatted() { } +U8* LLImageFormatted::allocateData(S32 ) { return NULL; } +S32 LLImageFormatted::calcDataSize(S32 ) { return 0; } +S32 LLImageFormatted::calcDiscardLevelBytes(S32 ) { return 0; } +BOOL LLImageFormatted::decodeChannels(LLImageRaw*, F32, S32, S32) { return FALSE; } +BOOL LLImageFormatted::copyData(U8 *, S32) { return TRUE; } // this method always returns TRUE... +void LLImageFormatted::deleteData() { } +void LLImageFormatted::dump() { } +U8* LLImageFormatted::reallocateData(S32 ) { return NULL; } +void LLImageFormatted::resetLastError() { } +void LLImageFormatted::sanityCheck() { } +void LLImageFormatted::setLastError(const std::string& , const std::string& ) { } + +LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C) { } +LLImageJ2C::~LLImageJ2C() { } +S32 LLImageJ2C::calcDataSize(S32 ) { return 0; } +S32 LLImageJ2C::calcDiscardLevelBytes(S32 ) { return 0; } +S32 LLImageJ2C::calcHeaderSize() { return 0; } +BOOL LLImageJ2C::decode(LLImageRaw*, F32) { return FALSE; } +BOOL LLImageJ2C::decodeChannels(LLImageRaw*, F32, S32, S32 ) { return FALSE; } +void LLImageJ2C::decodeFailed() { } +BOOL LLImageJ2C::encode(const LLImageRaw*, F32) { return FALSE; } +S8 LLImageJ2C::getRawDiscardLevel() { return 0; } +void LLImageJ2C::resetLastError() { } +void LLImageJ2C::setLastError(const std::string&, const std::string&) { } +BOOL LLImageJ2C::updateData() { return FALSE; } +void LLImageJ2C::updateRawDiscardLevel() { } + +LLKDUMemIn::LLKDUMemIn(const U8*, const U32, const U16, const U16, const U8, siz_params*) { } +LLKDUMemIn::~LLKDUMemIn() { } +bool LLKDUMemIn::get(int, kdu_line_buf&, int) { return false; } + +// Stub Kakadu Library calls +kdu_tile_comp kdu_tile::access_component(int ) { kdu_tile_comp a; return a; } +void kdu_tile::close(kdu_thread_env* ) { } +int kdu_tile::get_num_components() { return 0; } +bool kdu_tile::get_ycc() { return false; } +void kdu_tile::set_components_of_interest(int , const int* ) { } +kdu_resolution kdu_tile_comp::access_resolution() { kdu_resolution a; return a; } +int kdu_tile_comp::get_bit_depth(bool ) { return 8; } +bool kdu_tile_comp::get_reversible() { return false; } +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; } +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() { } +void kdu_params::set(const char* , int , int , bool ) { } +void kdu_params::set(const char* , int , int , int ) { } +void kdu_params::finalize_all(bool ) { } +void kdu_params::copy_from(kdu_params*, int, int, int, int, int, bool, bool, bool) { } +bool kdu_params::parse_string(const char*) { return false; } +bool kdu_params::get(const char*, int, int, bool&, bool, bool, bool) { return false; } +bool kdu_params::get(const char*, int, int, float&, bool, bool, bool) { return false; } +bool kdu_params::get(const char*, int, int, int&, bool, bool, bool) { return false; } +kdu_params* kdu_params::access_relation(int, int, int, bool) { return NULL; } +kdu_params* kdu_params::access_cluster(const char*) { return NULL; } +void kdu_codestream::set_fast() { } +void kdu_codestream::set_fussy() { } +void kdu_codestream::get_dims(int, kdu_dims&, bool ) { } +void kdu_codestream::change_appearance(bool, bool, bool) { } +void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { } +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 ) { } +void kdu_codestream::flush(kdu_long *, int , kdu_uint16 *, bool, bool, double, kdu_thread_env*) { } +void kdu_codestream::set_resilient(bool ) { } +int kdu_codestream::get_num_components(bool ) { return 0; } +siz_params* kdu_codestream::access_siz() { return NULL; } +kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; } +kdu_codestream_comment kdu_codestream::add_comment() { kdu_codestream_comment a; return a; } +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 ) { } +void siz_params::copy_with_xforms(kdu_params*, int, int, bool, bool, bool) { } +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; } + +// ------------------------------------------------------------------------------------------- +// TUT +// ------------------------------------------------------------------------------------------- + +namespace tut +{ + // Test wrapper declarations + struct llimagej2ckdu_test + { + // Derived test class + class LLTestImageJ2CKDU : public LLImageJ2CKDU + { + public: + // Provides public access to some protected methods for testing + BOOL callGetMetadata(LLImageJ2C &base) { return getMetadata(base); } + BOOL callDecodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) + { + return decodeImpl(base, raw_image, decode_time, first_channel, max_channel_count); + } + BOOL callEncodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text) + { + return encodeImpl(base, raw_image, comment_text); + } + }; + // Instance to be tested + LLTestImageJ2CKDU* mImage; + + // Constructor and destructor of the test wrapper + llimagej2ckdu_test() + { + mImage = new LLTestImageJ2CKDU; + } + ~llimagej2ckdu_test() + { + delete mImage; + } + }; + + // Tut templating thingamagic: test group, object and test instance + typedef test_group<llimagej2ckdu_test> llimagej2ckdu_t; + typedef llimagej2ckdu_t::object llimagej2ckdu_object_t; + tut::llimagej2ckdu_t tut_llimagej2ckdu("LLImageJ2CKDU"); + + // --------------------------------------------------------------------------------------- + // Test functions + // Notes: + // * Test as many as you possibly can without requiring a full blown simulation of everything + // * The tests are executed in sequence so the test instance state may change between calls + // * Remember that you cannot test private methods with tut + // --------------------------------------------------------------------------------------- + + // Test 1 : test getMetadata() + template<> template<> + void llimagej2ckdu_object_t::test<1>() + { + LLImageJ2C* image = new LLImageJ2C(); + BOOL res = mImage->callGetMetadata(*image); + // Trying to set up a data stream with all NIL values and stubbed KDU will "work" and return TRUE + // Note that is linking with KDU, that call will throw an exception and fail, returning FALSE + ensure("getMetadata() test failed", res == TRUE); + } + + // Test 2 : test decodeImpl() + template<> template<> + void llimagej2ckdu_object_t::test<2>() + { + LLImageJ2C* image = new LLImageJ2C(); + LLImageRaw* raw = new LLImageRaw(); + BOOL res = mImage->callDecodeImpl(*image, *raw, 0.0, 0, 0); + // Decoding returns TRUE whenever there's nothing else to do, including if decoding failed, so we'll get TRUE here + ensure("decodeImpl() test failed", res == TRUE); + } + + // Test 3 : test encodeImpl() + template<> template<> + void llimagej2ckdu_object_t::test<3>() + { + LLImageJ2C* image = new LLImageJ2C(); + LLImageRaw* raw = new LLImageRaw(); + BOOL res = mImage->callEncodeImpl(*image, *raw, NULL); + // Encoding returns TRUE unless an exception was raised, so we'll get TRUE here though nothing really was done + ensure("encodeImpl() test failed", res == TRUE); + } +} diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 04fe99ec1f..9022026248 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -325,6 +325,7 @@ LLGLManager::LLGLManager() : mHasVertexShader(FALSE), mHasFragmentShader(FALSE), mHasOcclusionQuery(FALSE), + mHasOcclusionQuery2(FALSE), mHasPointParameters(FALSE), mHasDrawBuffers(FALSE), mHasTextureRectangle(FALSE), @@ -666,6 +667,7 @@ void LLGLManager::initExtensions() mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts); mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression"); mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); + mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts); mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad @@ -782,6 +784,10 @@ void LLGLManager::initExtensions() { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL; } + if (!mHasOcclusionQuery2) + { + LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL; + } if (!mHasPointParameters) { LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 4630811679..ff4e6078c9 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -89,6 +89,7 @@ public: BOOL mHasVertexShader; BOOL mHasFragmentShader; BOOL mHasOcclusionQuery; + BOOL mHasOcclusionQuery2; BOOL mHasPointParameters; BOOL mHasDrawBuffers; BOOL mHasDepthClamp; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 1265733bf5..d30697e178 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2910,7 +2910,9 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str params.from_xui = true; applyXUILayout(params, parent); initFromParams(params); - + // chrome floaters don't take focus at all + setFocusRoot(!getIsChrome()); + initFloater(params); LLMultiFloater* last_host = LLFloater::getFloaterHost(); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 18e1dd6e59..9be40fbf17 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1926,6 +1926,8 @@ if (LL_TESTS) llremoteparcelrequest.cpp llviewerhelputil.cpp llversioninfo.cpp + llworldmap.cpp + llworldmipmap.cpp ) ################################################## @@ -2013,8 +2015,6 @@ if (LL_TESTS) #ADD_VIEWER_BUILD_TEST(llmemoryview viewer) #ADD_VIEWER_BUILD_TEST(llagentaccess viewer) - #ADD_VIEWER_BUILD_TEST(llworldmap viewer) - #ADD_VIEWER_BUILD_TEST(llworldmipmap viewer) #ADD_VIEWER_BUILD_TEST(lltextureinfo viewer) #ADD_VIEWER_BUILD_TEST(lltextureinfodetails viewer) #ADD_VIEWER_BUILD_TEST(lltexturestatsuploader viewer) diff --git a/indra/newview/app_settings/shaders/shader_heirarchy.txt b/indra/newview/app_settings/shaders/shader_hierarchy.txt index d8bbf69b38..d8bbf69b38 100644 --- a/indra/newview/app_settings/shaders/shader_heirarchy.txt +++ b/indra/newview/app_settings/shaders/shader_hierarchy.txt diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 3c6b881eeb..0093279859 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2874,6 +2874,8 @@ void LLAppViewer::writeSystemInfo() LL_INFOS("SystemInfo") << "OS: " << getOSInfo().getOSStringSimple() << LL_ENDL; LL_INFOS("SystemInfo") << "OS info: " << getOSInfo() << LL_ENDL; + LL_INFOS("SystemInfo") << "Timers: " << LLFastTimer::sClockType << LL_ENDL; + writeDebugInfo(); // Save out debug_info.log early, in case of crash. } diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 351b9ac5da..1b94d8cbcd 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -83,7 +83,6 @@ LLFloaterMap::~LLFloaterMap() BOOL LLFloaterMap::postBuild() { mMap = getChild<LLNetMap>("Net Map"); - mMap->setScale(gSavedSettings.getF32("MiniMapScale")); mMap->setToolTipMsg(getString("ToolTipMsg")); sendChildToBack(mMap); @@ -288,7 +287,16 @@ void LLFloaterMap::handleZoom(const LLSD& userdata) std::string level = userdata.asString(); F32 scale = 0.0f; - if (level == std::string("close")) + if (level == std::string("default")) + { + LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); + if(pvar) + { + pvar->resetToDefault(); + scale = gSavedSettings.getF32("MiniMapScale"); + } + } + else if (level == std::string("close")) scale = LLNetMap::MAP_SCALE_MAX; else if (level == std::string("medium")) scale = LLNetMap::MAP_SCALE_MID; @@ -296,7 +304,6 @@ void LLFloaterMap::handleZoom(const LLSD& userdata) scale = LLNetMap::MAP_SCALE_MIN; if (scale != 0.0f) { - gSavedSettings.setF32("MiniMapScale", scale ); mMap->setScale(scale); } } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 46c7cba53a..c948efe17f 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -283,6 +283,7 @@ BOOL LLFloaterModelPreview::postBuild() childSetAction("lod_browse", onBrowseLOD, this); + childSetCommitCallback("cancel_btn", onCancel, this); childSetCommitCallback("crease_angle", onGenerateNormalsCommit, this); childSetCommitCallback("generate_normals", onGenerateNormalsCommit, this); @@ -379,7 +380,7 @@ LLFloaterModelPreview::~LLFloaterModelPreview() { sInstance = NULL; - if ( mModelPreview->containsRiggedAsset() ) + if ( mModelPreview->mModelLoader->mResetJoints ) { gAgentAvatarp->resetJointPositions(); } @@ -560,7 +561,14 @@ void LLFloaterModelPreview::draw() LLMutexLock lock(mStatusLock); childSetTextArg("status", "[STATUS]", mStatusMessage); } - + else + { + childSetVisible("Simplify", true); + childSetVisible("simplify_cancel", false); + childSetVisible("Decompose", true); + childSetVisible("decompose_cancel", false); + } + U32 resource_cost = mModelPreview->mResourceCost*10; if (childGetValue("upload_textures").asBoolean()) @@ -736,7 +744,8 @@ void LLFloaterModelPreview::onPhysicsParamCommit(LLUICtrl* ctrl, void* data) //static void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data) { - LLCDStageData* stage = (LLCDStageData*) data; + LLCDStageData* stage_data = (LLCDStageData*) data; + std::string stage = stage_data->mName; if (sInstance) { @@ -751,11 +760,22 @@ void LLFloaterModelPreview::onPhysicsStageExecute(LLUICtrl* ctrl, void* data) for (S32 i = 0; i < sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS].size(); ++i) { LLModel* mdl = sInstance->mModelPreview->mModel[LLModel::LOD_PHYSICS][i]; - DecompRequest* request = new DecompRequest(stage->mName, mdl); + DecompRequest* request = new DecompRequest(stage, mdl); sInstance->mCurRequest.insert(request); gMeshRepo.mDecompThread->submitRequest(request); } } + + if (stage == "Decompose") + { + sInstance->childSetVisible("Decompose", false); + sInstance->childSetVisible("decompose_cancel", true); + } + else if (stage == "Simplify") + { + sInstance->childSetVisible("Simplify", false); + sInstance->childSetVisible("simplify_cancel", true); + } } } @@ -778,6 +798,15 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) sInstance->mModelPreview->setPhysicsFromLOD(which_mode); } +//static +void LLFloaterModelPreview::onCancel(LLUICtrl* ctrl, void* data) +{ + if (sInstance) + { + sInstance->closeFloater(false); + } +} + //static void LLFloaterModelPreview::onPhysicsStageCancel(LLUICtrl* ctrl, void*data) { @@ -796,7 +825,9 @@ void LLFloaterModelPreview::initDecompControls() { LLSD key; - childSetCommitCallback("cancel_btn", onPhysicsStageCancel, NULL); + childSetCommitCallback("simplify_cancel", onPhysicsStageCancel, NULL); + childSetCommitCallback("decompose_cancel", onPhysicsStageCancel, NULL); + childSetCommitCallback("physics_lod_combo", onPhysicsUseLOD, NULL); childSetCommitCallback("physics_browse", onPhysicsBrowse, NULL); @@ -929,7 +960,7 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl // LLModelLoader //----------------------------------------------------------------------------- LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* preview) -: LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mState(STARTING), mFirstTransform(TRUE) +: LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mState(STARTING), mFirstTransform(TRUE), mResetJoints( FALSE ) { mJointMap["mPelvis"] = "mPelvis"; mJointMap["mTorso"] = "mTorso"; @@ -1006,6 +1037,28 @@ LLModelLoader::LLModelLoader(std::string filename, S32 lod, LLModelPreview* prev mJointMap["lThigh"] = "mHipLeft"; mJointMap["lShin"] = "mKneeLeft"; mJointMap["lFoot"] = "mFootLeft"; + + //move into joint mapper class + mMasterJointList.push_front("mPelvis"); + mMasterJointList.push_front("mTorso"); + mMasterJointList.push_front("mChest"); + mMasterJointList.push_front("mNeck"); + mMasterJointList.push_front("mHead"); + mMasterJointList.push_front("mSkull"); + mMasterJointList.push_front("mCollarLeft"); + mMasterJointList.push_front("mShoulderLeft"); + mMasterJointList.push_front("mElbowLeft"); + mMasterJointList.push_front("mWristLeft"); + mMasterJointList.push_front("mCollarRight"); + mMasterJointList.push_front("mShoulderRight"); + mMasterJointList.push_front("mElbowRight"); + mMasterJointList.push_front("mWristRight"); + mMasterJointList.push_front("mHipRight"); + mMasterJointList.push_front("mKneeRight"); + mMasterJointList.push_front("mFootRight"); + mMasterJointList.push_front("mHipLeft"); + mMasterJointList.push_front("mKneeLeft"); + mMasterJointList.push_front("mFootLeft"); } void stretch_extents(LLModel* model, LLMatrix4a& mat, LLVector4a& min, LLVector4a& max, BOOL& first_transform) @@ -1075,32 +1128,32 @@ void LLModelLoader::run() { DAE dae; domCOLLADA* dom = dae.open(mFilename); - + if (dom) { daeDatabase* db = dae.getDatabase(); - + daeInt count = db->getElementCount(NULL, COLLADA_TYPE_MESH); - + daeDocument* doc = dae.getDoc(mFilename); if (!doc) { llwarns << "can't find internal doc" << llendl; return; } - + daeElement* root = doc->getDomRoot(); if (!root) { llwarns << "document has no root" << llendl; return; } - + //get unit scale mTransform.setIdentity(); - + domAsset::domUnit* unit = daeSafeCast<domAsset::domUnit>(root->getDescendant(daeElement::matchType(domAsset::domUnit::ID()))); - + if (unit) { F32 meter = unit->getMeter(); @@ -1108,19 +1161,19 @@ void LLModelLoader::run() mTransform.mMatrix[1][1] = meter; mTransform.mMatrix[2][2] = meter; } - + //get up axis rotation LLMatrix4 rotation; - + domUpAxisType up = UPAXISTYPE_Y_UP; // default is Y_UP domAsset::domUp_axis* up_axis = daeSafeCast<domAsset::domUp_axis>(root->getDescendant(daeElement::matchType(domAsset::domUp_axis::ID()))); - + if (up_axis) { up = up_axis->getValue(); } - + if (up == UPAXISTYPE_X_UP) { rotation.initRotation(0.0f, 90.0f * DEG_TO_RAD, 0.0f); @@ -1129,20 +1182,20 @@ void LLModelLoader::run() { rotation.initRotation(90.0f * DEG_TO_RAD, 0.0f, 0.0f); } - + rotation *= mTransform; mTransform = rotation; - - + + for (daeInt idx = 0; idx < count; ++idx) { //build map of domEntities to LLModel domMesh* mesh = NULL; db->getElement((daeElement**) &mesh, idx, NULL, COLLADA_TYPE_MESH); - + if (mesh) { LLPointer<LLModel> model = LLModel::loadModelFromDomMesh(mesh); - + if (model.notNull() && validate_model(model)) { mModelList.push_back(model); @@ -1150,17 +1203,17 @@ void LLModelLoader::run() } } } - + count = db->getElementCount(NULL, COLLADA_TYPE_SKIN); for (daeInt idx = 0; idx < count; ++idx) { //add skinned meshes as instances domSkin* skin = NULL; db->getElement((daeElement**) &skin, idx, NULL, COLLADA_TYPE_SKIN); - + if (skin) { domGeometry* geom = daeSafeCast<domGeometry>(skin->getSource().getElement()); - + if (geom) { domMesh* mesh = geom->getMesh(); @@ -1172,25 +1225,25 @@ void LLModelLoader::run() LLVector3 mesh_scale_vector; LLVector3 mesh_translation_vector; model->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); - + LLMatrix4 normalized_transformation; normalized_transformation.setTranslation(mesh_translation_vector); - + LLMatrix4 mesh_scale; mesh_scale.initScale(mesh_scale_vector); mesh_scale *= normalized_transformation; normalized_transformation = mesh_scale; - + glh::matrix4f inv_mat((F32*) normalized_transformation.mMatrix); inv_mat = inv_mat.inverse(); LLMatrix4 inverse_normalized_transformation(inv_mat.m); - + domSkin::domBind_shape_matrix* bind_mat = skin->getBind_shape_matrix(); - + if (bind_mat) { //get bind shape matrix domFloat4x4& dom_value = bind_mat->getValue(); - + for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) @@ -1198,26 +1251,26 @@ void LLModelLoader::run() model->mBindShapeMatrix.mMatrix[i][j] = dom_value[i + j*4]; } } - + LLMatrix4 trans = normalized_transformation; trans *= model->mBindShapeMatrix; model->mBindShapeMatrix = trans; - + } - - + + //The joint transfom map that we'll populate below std::map<std::string,LLMatrix4> jointTransforms; jointTransforms.clear(); - + //Some collada setup for accessing the skeleton daeElement* pElement = 0; dae.getDatabase()->getElement( &pElement, 0, 0, "skeleton" ); - + //Try to get at the skeletal instance controller domInstance_controller::domSkeleton* pSkeleton = daeSafeCast<domInstance_controller::domSkeleton>( pElement ); bool missingSkeletonOrScene = false; - + //If no skeleton, do a breadth-first search to get at specific joints if ( !pSkeleton ) { @@ -1232,7 +1285,7 @@ void LLModelLoader::run() //Get the children at this level daeTArray< daeSmartRef<daeElement> > children = pScene->getChildren(); S32 childCount = children.getCount(); - + //Process any children that are joints //Not all children are joints, some code be ambient lights, cameras, geometry etc.. for (S32 i = 0; i < childCount; ++i) @@ -1246,7 +1299,7 @@ void LLModelLoader::run() } } else - //Has Skeleton + //Has Skeleton { //Get the root node of the skeleton daeElement* pSkeletonRootNode = pSkeleton->getValue().getElement(); @@ -1255,7 +1308,7 @@ void LLModelLoader::run() //Once we have the root node - start acccessing it's joint components const int jointCnt = mJointMap.size(); std::map<std::string, std::string> :: const_iterator jointIt = mJointMap.begin(); - + //Loop over all the possible joints within the .dae - using the allowed joint list in the ctor. for ( int i=0; i<jointCnt; ++i, ++jointIt ) { @@ -1263,10 +1316,10 @@ void LLModelLoader::run() char str[64]={0}; sprintf(str,"./%s",(*jointIt).second.c_str() ); //llwarns<<"Joint "<< str <<llendl; - + //Setup the resolver daeSIDResolver resolver( pSkeletonRootNode, str ); - + //Look for the joint domNode* pJoint = daeSafeCast<domNode>( resolver.getElement() ); if ( pJoint ) @@ -1274,9 +1327,9 @@ void LLModelLoader::run() //Pull out the translate id and store it in the jointTranslations map daeSIDResolver jointResolver( pJoint, "./translate" ); domTranslate* pTranslate = daeSafeCast<domTranslate>( jointResolver.getElement() ); - + LLMatrix4 workingTransform; - + //Translation via SID if ( pTranslate ) { @@ -1296,12 +1349,12 @@ void LLModelLoader::run() extractTranslationViaElement( pTranslateElement, workingTransform ); } } - + //Store the joint transform w/respect to it's name. jointTransforms[(*jointIt).second.c_str()] = workingTransform; } } - + //If anything failed in regards to extracting the skeleton, joints or translation id, //mention it if ( missingSkeletonOrScene ) @@ -1310,64 +1363,32 @@ void LLModelLoader::run() } }//got skeleton? } - - if ( !missingSkeletonOrScene ) - { - //Set the joint translations on the avatar - //The joints are reset in the dtor - const int jointCnt = mJointMap.size(); - std::map<std::string, std::string> :: const_iterator jointIt = mJointMap.begin(); - for ( int i=0; i<jointCnt; ++i, ++jointIt ) - { - std::string lookingForJoint = (*jointIt).first.c_str(); - if ( jointTransforms.find( lookingForJoint ) != jointTransforms.end() ) - { - LLMatrix4 jointTransform = jointTransforms[lookingForJoint]; - LLJoint* pJoint = gAgentAvatarp->getJoint( lookingForJoint ); - if ( pJoint ) - { - pJoint->storeCurrentXform( jointTransform.getTranslation() ); - } - else - { - //Most likely an error in the asset. - llwarns<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << llendl; - } - //Reposition the avatars pelvis (avPos+offset) - //if ( lookingForJoint == "mPelvis" ) - //{ - // const LLVector3& pos = gAgentAvatarp->getCharacterPosition(); - // gAgentAvatarp->setPelvisOffset( true, jointTransform.getTranslation() ); - // gAgentAvatarp->setPosition( pos + jointTransform.getTranslation() ); - //} - } - } - } //missingSkeletonOrScene - + + domSkin::domJoints* joints = skin->getJoints(); - + domInputLocal_Array& joint_input = joints->getInput_array(); - + for (size_t i = 0; i < joint_input.getCount(); ++i) { domInputLocal* input = joint_input.get(i); xsNMTOKEN semantic = input->getSemantic(); - + if (strcmp(semantic, COMMON_PROFILE_INPUT_JOINT) == 0) { //found joint source, fill model->mJointMap and model->mJointList daeElement* elem = input->getSource().getElement(); - + domSource* source = daeSafeCast<domSource>(elem); if (source) { - - + + domName_array* names_source = source->getName_array(); - + if (names_source) { domListOfNames &names = names_source->getValue(); - + for (size_t j = 0; j < names.getCount(); ++j) { std::string name(names.get(j)); @@ -1385,7 +1406,7 @@ void LLModelLoader::run() if (names_source) { xsIDREFS& names = names_source->getValue(); - + for (size_t j = 0; j < names.getCount(); ++j) { std::string name(names.get(j).getID()); @@ -1410,11 +1431,11 @@ void LLModelLoader::run() { domListOfFloats& transform = t->getValue(); S32 count = transform.getCount()/16; - + for (S32 k = 0; k < count; ++k) { LLMatrix4 mat; - + for (int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) @@ -1422,14 +1443,55 @@ void LLModelLoader::run() mat.mMatrix[i][j] = transform[k*16 + i + j*4]; } } - + model->mInvBindMatrix.push_back(mat); } } } } } - + + //Now that we've parsed the joint array, let's determine if we have a full rig + //(which means we have all the joints that are required for an avatar versus + //a skinned asset attached to a node in a file that contains an entire skeleton, + //but does not use the skeleton). + + if ( !model->mJointList.empty() && doesJointArrayContainACompleteRig( model->mJointList ) ) + { + mResetJoints = true; + } + + if ( !missingSkeletonOrScene ) + { + //Set the joint translations on the avatar - if it's a full mapping + //The joints are reset in the dtor + if ( mResetJoints ) + { + std::map<std::string, std::string> :: const_iterator masterJointIt = mJointMap.begin(); + std::map<std::string, std::string> :: const_iterator masterJointItEnd = mJointMap.end(); + for (;masterJointIt!=masterJointItEnd;++masterJointIt ) + { + std::string lookingForJoint = (*masterJointIt).first.c_str(); + + if ( jointTransforms.find( lookingForJoint ) != jointTransforms.end() ) + { + //llinfos<<"joint "<<lookingForJoint.c_str()<<llendl; + LLMatrix4 jointTransform = jointTransforms[lookingForJoint]; + LLJoint* pJoint = gAgentAvatarp->getJoint( lookingForJoint ); + if ( pJoint ) + { + pJoint->storeCurrentXform( jointTransform.getTranslation() ); + } + else + { + //Most likely an error in the asset. + llwarns<<"Tried to apply joint position from .dae, but it did not exist in the avatar rig." << llendl; + } + } + } + } + } //missingSkeletonOrScene + //We need to construct the alternate bind matrix (which contains the new joint positions) //in the same order as they were stored in the joint buffer. The joints associated //with the skeleton are not stored in the same order as they are in the exported joint buffer. @@ -1453,9 +1515,9 @@ void LLModelLoader::run() llwarns<<"Possibly misnamed/missing joint [" <<lookingForJoint.c_str()<<" ] "<<llendl; } } - + //grab raw position array - + domVertices* verts = mesh->getVertices(); if (verts) { @@ -1471,19 +1533,19 @@ void LLModelLoader::run() if (pos_array) { domListOfFloats& pos = pos_array->getValue(); - + for (size_t j = 0; j < pos.getCount(); j += 3) { if (pos.getCount() <= j+2) { llerrs << "WTF?" << llendl; } - + LLVector3 v(pos[j], pos[j+1], pos[j+2]); - + //transform from COLLADA space to volume space v = v * inverse_normalized_transformation; - + model->mPosition.push_back(v); } } @@ -1491,7 +1553,7 @@ void LLModelLoader::run() } } } - + //grab skin weights array domSkin::domVertex_weights* weights = skin->getVertex_weights(); if (weights) @@ -1509,44 +1571,44 @@ void LLModelLoader::run() } } } - + if (vertex_weights) { domListOfFloats& w = vertex_weights->getValue(); domListOfUInts& vcount = weights->getVcount()->getValue(); domListOfInts& v = weights->getV()->getValue(); - + U32 c_idx = 0; for (size_t vc_idx = 0; vc_idx < vcount.getCount(); ++vc_idx) { //for each vertex daeUInt count = vcount[vc_idx]; - + //create list of weights that influence this vertex LLModel::weight_list weight_list; - + for (daeUInt i = 0; i < count; ++i) { //for each weight daeInt joint_idx = v[c_idx++]; daeInt weight_idx = v[c_idx++]; - + if (joint_idx == -1) { //ignore bindings to bind_shape_matrix continue; } - + F32 weight_value = w[weight_idx]; - + weight_list.push_back(LLModel::JointWeight(joint_idx, weight_value)); } - + //sort by joint weight std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater()); - + std::vector<LLModel::JointWeight> wght; - + F32 total = 0.f; - + for (U32 i = 0; i < llmin((U32) 4, (U32) weight_list.size()); ++i) { //take up to 4 most significant weights if (weight_list[i].mWeight > 0.f) @@ -1555,7 +1617,7 @@ void LLModelLoader::run() total += weight_list[i].mWeight; } } - + F32 scale = 1.f/total; if (scale != 1.f) { //normalize weights @@ -1564,12 +1626,12 @@ void LLModelLoader::run() wght[i].mWeight *= scale; } } - + model->mSkinWeights[model->mPosition[vc_idx]] = wght; } - + //add instance to scene for this model - + LLMatrix4 transformation = mTransform; // adjust the transformation to compensate for mesh normalization @@ -1577,12 +1639,12 @@ void LLModelLoader::run() mesh_translation.setTranslation(mesh_translation_vector); mesh_translation *= transformation; transformation = mesh_translation; - + LLMatrix4 mesh_scale; mesh_scale.initScale(mesh_scale_vector); mesh_scale *= transformation; transformation = mesh_scale; - + std::vector<LLImportMaterial> materials; materials.resize(model->getNumVolumeFaces()); mScene[transformation].push_back(LLModelInstance(model, transformation, materials)); @@ -1594,24 +1656,83 @@ void LLModelLoader::run() } } } - + daeElement* scene = root->getDescendant("visual_scene"); - + if (!scene) { llwarns << "document has no visual_scene" << llendl; setLoadState( ERROR_PARSING ); return; } - setLoadState( DONE ); processElement(scene); - + doOnIdleOneTime(boost::bind(&LLModelPreview::loadModelCallback,mPreview,mLod)); } } +bool LLModelLoader::doesJointArrayContainACompleteRig( const std::vector<std::string> &jointListFromModel ) +{ + std::deque<std::string> :: const_iterator masterJointIt = mMasterJointList.begin(); + std::deque<std::string> :: const_iterator masterJointEndIt = mMasterJointList.end(); + + std::vector<std::string> :: const_iterator modelJointIt = jointListFromModel.begin(); + std::vector<std::string> :: const_iterator modelJointItEnd = jointListFromModel.end(); + + bool found = false; + for ( ;masterJointIt!=masterJointEndIt;++masterJointIt ) + { + found = false; + modelJointIt = jointListFromModel.begin(); + for ( ;modelJointIt!=modelJointItEnd; ++modelJointIt ) + { + if ( *masterJointIt == *modelJointIt ) + { + found = true; + break; + } + } + if ( !found ) + { + llinfos<<" Asset did not contain the joint (if you're u/l a fully rigged asset - it is required)." << *masterJointIt<< llendl; + break; + } + } + + return found; +} + +//called in the main thread +void LLModelLoader::loadTextures() +{ + BOOL is_paused = isPaused() ; + pause() ; //pause the loader + + for(scene::iterator iter = mScene.begin(); iter != mScene.end(); ++iter) + { + for(U32 i = 0 ; i < iter->second.size(); i++) + { + for(U32 j = 0 ; j < iter->second[i].mMaterial.size() ; j++) + { + if(!iter->second[i].mMaterial[j].mDiffuseMapFilename.empty()) + { + iter->second[i].mMaterial[j].mDiffuseMap = + LLViewerTextureManager::getFetchedTextureFromUrl("file://" + iter->second[i].mMaterial[j].mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW); + iter->second[i].mMaterial[j].mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE); + iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(); + } + } + } + } + + if(!is_paused) + { + unpause() ; + } +} + bool LLModelLoader::isNodeAJoint( domNode* pNode ) { if ( pNode->getName() == NULL) @@ -1917,14 +2038,8 @@ LLImportMaterial LLModelLoader::profileToMaterial(domProfile_COMMON* material) // we only support init_from now - embedded data will come later domImage::domInit_from* init = image->getInit_from(); if (init) - { - std::string filename = cdom::uriToNativePath(init->getValue().str()); - - mat.mDiffuseMap = LLViewerTextureManager::getFetchedTextureFromUrl("file://" + filename, TRUE, LLViewerTexture::BOOST_PREVIEW); - mat.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, this->mPreview, NULL, FALSE); - - mat.mDiffuseMap->forceToSaveRawImage(); - mat.mDiffuseMapFilename = filename; + { + mat.mDiffuseMapFilename = cdom::uriToNativePath(init->getValue().str()); mat.mDiffuseMapLabel = getElementLabel(material); } } @@ -2039,7 +2154,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) mBuildShareTolerance = 0.f; mBuildQueueMode = GLOD_QUEUE_GREEDY; mBuildBorderMode = GLOD_BORDER_UNLOCK; - mBuildOperator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE; + mBuildOperator = GLOD_OPERATOR_EDGE_COLLAPSE; mViewOption["show_textures"] = false; @@ -2386,6 +2501,7 @@ void LLModelPreview::loadModelCallback(S32 lod) return; } + mModelLoader->loadTextures() ; mModel[lod] = mModelLoader->mModelList; mScene[lod] = mModelLoader->mScene; mVertexBuffer[lod].clear(); @@ -2752,7 +2868,9 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation) lod_mode = GLOD_TRIANGLE_BUDGET; if (which_lod != -1) { - limit = mFMP->childGetValue("lod_triangle_limit").asInteger(); + //SH-632 take budget as supplied limit+1 to prevent GLOD from creating a smaller + //decimation when the given decimation is possible + limit = mFMP->childGetValue("lod_triangle_limit").asInteger(); //+1; } } else @@ -2770,11 +2888,11 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation) if (build_operator == 0) { - build_operator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE; + build_operator = GLOD_OPERATOR_EDGE_COLLAPSE; } else { - build_operator = GLOD_OPERATOR_EDGE_COLLAPSE; + build_operator = GLOD_OPERATOR_HALF_EDGE_COLLAPSE; } U32 queue_mode=0; @@ -3828,7 +3946,7 @@ BOOL LLModelPreview::render() gGL.getTexUnit(0)->bind(instance.mMaterial[i].mDiffuseMap, true); if (instance.mMaterial[i].mDiffuseMap->getDiscardLevel() > -1) { - mTextureSet.insert(instance.mMaterial[i].mDiffuseMap); + mTextureSet.insert(instance.mMaterial[i].mDiffuseMap.get()); } } } @@ -4261,11 +4379,14 @@ void LLFloaterModelPreview::DecompRequest::completed() if (sInstance) { - if (sInstance->mModelPreview) + if (mContinue) { - sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh; - sInstance->mModelPreview->mDirty = true; - LLFloaterModelPreview::sInstance->mModelPreview->refresh(); + if (sInstance->mModelPreview) + { + sInstance->mModelPreview->mPhysicsMesh[mModel] = mHullMesh; + sInstance->mModelPreview->mDirty = true; + LLFloaterModelPreview::sInstance->mModelPreview->refresh(); + } } sInstance->mCurRequest.erase(this); diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index a791f3c44c..63377bb1d6 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -97,6 +97,7 @@ public: virtual void run(); + void loadTextures() ; //called in the main thread. void processElement(daeElement* element); std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo); LLImportMaterial profileToMaterial(domProfile_COMMON* material); @@ -110,11 +111,16 @@ public: void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); + bool doesJointArrayContainACompleteRig( const std::vector<std::string> &modelJointList ); + bool checkForCompleteRig( const std::vector<std::string> &jointListFromModel ); + void setLoadState( U32 state ) { mState = state; } U32 getLoadState( void ) { return mState; } //map of avatar joints as named in COLLADA assets to internal joint names std::map<std::string, std::string> mJointMap; + std::deque<std::string> mMasterJointList; + bool mResetJoints; }; class LLFloaterModelPreview : public LLFloater @@ -188,6 +194,7 @@ protected: static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata); static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata); + static void onCancel(LLUICtrl* ctrl, void* userdata); static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata); static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata); @@ -329,7 +336,7 @@ public: std::map<LLPointer<LLModel>, std::vector<LLPointer<LLVertexBuffer> > > mPhysicsMesh; LLMeshUploadThread::instance_list mUploadData; - std::set<LLPointer<LLViewerFetchedTexture> > mTextureSet; + std::set<LLViewerFetchedTexture* > mTextureSet; //map of vertex buffers to models (one vertex buffer in vector per face in model std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1]; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0f021aba89..c50afb0e9d 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2736,12 +2736,13 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_CALLINGCARD: case DAD_LANDMARK: case DAD_SCRIPT: + case DAD_CLOTHING: case DAD_OBJECT: case DAD_NOTECARD: - case DAD_CLOTHING: case DAD_BODYPART: case DAD_ANIMATION: case DAD_GESTURE: + case DAD_MESH: accept = dragItemIntoFolder(inv_item, drop); break; case DAD_LINK: @@ -2771,7 +2772,11 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data, drop); } break; + case DAD_ROOT_CATEGORY: + case DAD_NONE: + break; default: + llwarns << "Unhandled cargo type for drag&drop " << cargo_type << llendl; break; } return accept; @@ -5415,11 +5420,6 @@ void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) menuentry_vec_t disabled_items, items = getMenuItems(); - items.erase(std::remove(items.begin(), items.end(), std::string("New Body Parts")), items.end()); - items.erase(std::remove(items.begin(), items.end(), std::string("New Clothes")), items.end()); - items.erase(std::remove(items.begin(), items.end(), std::string("New Note")), items.end()); - items.erase(std::remove(items.begin(), items.end(), std::string("New Gesture")), items.end()); - items.erase(std::remove(items.begin(), items.end(), std::string("New Script")), items.end()); items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end()); hide_context_entries(menu, items, disabled_items); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index dd2dcffc28..d2f76eceb0 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1450,17 +1450,21 @@ void LLMeshUploadThread::DecompRequest::completed() mThread->mHullMap[mBaseModel] = mHull[0]; } -void LLMeshUploadThread::run() +//called in the main thread. +void LLMeshUploadThread::preStart() { - mCurlRequest = new LLCurlRequest(); - //build map of LLModel refs to instances for callbacks for (instance_list::iterator iter = mInstanceList.begin(); iter != mInstanceList.end(); ++iter) { mInstance[iter->mModel].push_back(*iter); } +} + +void LLMeshUploadThread::run() +{ + mCurlRequest = new LLCurlRequest(); - std::set<LLPointer<LLViewerTexture> > textures; + std::set<LLViewerTexture* > textures; //populate upload queue with relevant models for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) @@ -1483,9 +1487,9 @@ void LLMeshUploadThread::run() material_iter != instance.mMaterial.end(); ++material_iter) { - if (textures.find(material_iter->mDiffuseMap) == textures.end()) + if (textures.find(material_iter->mDiffuseMap.get()) == textures.end()) { - textures.insert(material_iter->mDiffuseMap); + textures.insert(material_iter->mDiffuseMap.get()); LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel); uploadTexture(data); @@ -2148,6 +2152,7 @@ S32 LLMeshRepository::update() for (S32 i = 0; i < size; ++i) { mUploads.push_back(mUploadWaitList[i]); + mUploadWaitList[i]->preStart() ; mUploadWaitList[i]->start() ; } mUploadWaitList.clear() ; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 8c9892b28f..eccb82b661 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -431,6 +431,7 @@ public: bool finished() { return mFinished; } virtual void run(); + void preStart(); }; diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index cebfac86e7..de5439e4e0 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -527,7 +527,8 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args) if( nearby_chat->getVisible() || ( chat_msg.mSourceType == CHAT_SOURCE_AGENT - && gSavedSettings.getBOOL("UseChatBubbles") ) ) + && gSavedSettings.getBOOL("UseChatBubbles") ) + || !mChannel->getShowToasts() ) // to prevent toasts in Busy mode return;//no need in toast if chat is visible or if bubble chat is enabled // Handle irc styled messages for toast panel diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index f084002385..1a8ec4991d 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -94,10 +94,12 @@ LLNetMap::LLNetMap (const Params & p) mToolTipMsg() { mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); + setScale(gSavedSettings.getF32("MiniMapScale")); } LLNetMap::~LLNetMap() { + gSavedSettings.setF32("MiniMapScale", mScale); } void LLNetMap::setScale( F32 scale ) diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 116625b05d..a3aa3dbdff 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -506,9 +506,6 @@ void LLPanelMainInventory::onFilterSelected() return; } - BOOL recent_active = ("Recent Items" == mActivePanel->getName()); - getChildView("add_btn_panel")->setVisible( !recent_active); - setFilterSubString(mFilterSubString); LLInventoryFilter* filter = mActivePanel->getFilter(); LLFloaterInventoryFinder *finder = getFinder(); @@ -953,6 +950,11 @@ void LLPanelMainInventory::updateListCommands() void LLPanelMainInventory::onAddButtonClick() { +// Gray out the "New Folder" option when the Recent tab is active as new folders will not be displayed +// unless "Always show folders" is checked in the filter options. + bool recent_active = ("Recent Items" == mActivePanel->getName()); + mMenuAdd->getChild<LLMenuItemGL>("New Folder")->setEnabled(!recent_active); + setUploadCostIfNeeded(); showActionMenu(mMenuAdd,"add_btn"); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index cc54f21a7e..1b5800b8a5 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -222,7 +222,17 @@ static U8 sOcclusionIndices[] = b000, b110, b100, b101, b001, b011, b010, b110, }; -U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center) +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center) +{ + LLVector4a origin; + origin.load3(camera->getOrigin().mV); + + S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7; + + return cypher*8; +} + +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) { LLVector4a origin; origin.load3(camera->getOrigin().mV); @@ -231,12 +241,21 @@ U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center) return sOcclusionIndices+cypher*8; } - + + void LLSpatialGroup::buildOcclusion() { - if (!mOcclusionVerts) + if (mOcclusionVerts.isNull()) { - mOcclusionVerts = new LLVector4a[8]; + mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_DYNAMIC_DRAW_ARB); + mOcclusionVerts->allocateBuffer(8, 64, true); + + LLStrider<U16> idx; + mOcclusionVerts->getIndexStrider(idx); + for (U32 i = 0; i < 64; i++) + { + *idx++ = sOcclusionIndices[i]; + } } LLVector4a fudge; @@ -251,7 +270,12 @@ void LLSpatialGroup::buildOcclusion() r.setMin(r, r2); - LLVector4a* v = mOcclusionVerts; + LLStrider<LLVector3> pos; + + mOcclusionVerts->getVertexStrider(pos); + + LLVector4a* v = (LLVector4a*) pos.get(); + const LLVector4a& c = mBounds[0]; const LLVector4a& s = r; @@ -275,10 +299,13 @@ void LLSpatialGroup::buildOcclusion() for (S32 i = 0; i < 8; ++i) { - v[i] = s; - v[i].mul(octant[i]); - v[i].add(c); + LLVector4a p; + p.setMul(s, octant[i]); + p.add(c); + v[i] = p; } + + mOcclusionVerts->setBuffer(0); clearState(LLSpatialGroup::OCCLUSION_DIRTY); } @@ -339,7 +366,6 @@ LLSpatialGroup::~LLSpatialGroup() sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -881,12 +907,9 @@ void LLSpatialGroup::shift(const LLVector4a &offset) gPipeline.markRebuild(this, TRUE); } - if (mOcclusionVerts) + if (mOcclusionVerts.notNull()) { - for (U32 i = 0; i < 8; i++) - { - mOcclusionVerts[i].add(offset); - } + setState(OCCLUSION_DIRTY); } } @@ -1423,7 +1446,6 @@ void LLSpatialGroup::destroyGL() } } - delete [] mOcclusionVerts; mOcclusionVerts = NULL; for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) @@ -1516,31 +1538,37 @@ void LLSpatialGroup::checkOcclusion() } else if (isOcclusionState(QUERY_PENDING)) { //otherwise, if a query is pending, read it back - GLuint res = 1; - if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); - } - if (isOcclusionState(DISCARD_QUERY)) - { - res = 2; - } + GLuint available = 0; + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + if (available) + { //result is available, read it back, otherwise wait until next frame + GLuint res = 1; + if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); + } - if (res > 0) - { - assert_states_valid(this); - clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } - else - { - assert_states_valid(this); - setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); - assert_states_valid(this); - } + if (isOcclusionState(DISCARD_QUERY)) + { + res = 2; + } - clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + if (res > 0) + { + assert_states_valid(this); + clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + else + { + assert_states_valid(this); + setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + assert_states_valid(this); + } + + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); + } } else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED)) { //check occlusion has been issued for occluded node that has not had a query issued @@ -1566,54 +1594,59 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) } else { + if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY)) { - LLFastTimer t(FTM_RENDER_OCCLUSION); + { //no query pending, or previous query to be discarded + LLFastTimer t(FTM_RENDER_OCCLUSION); - if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) - { - mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); - } + if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) + { + mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); + } - if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) - { - buildOcclusion(); - } - - // Depth clamp all water to avoid it being culled as a result of being - // behind the far clip plane, and in the case of edge water to avoid - // it being culled while still visible. - bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || - mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); - if (use_depth_clamp) - { - glEnable(GL_DEPTH_CLAMP); - } - - glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery[LLViewerCamera::sCurCameraID]); - glVertexPointer(3, GL_FLOAT, 16, mOcclusionVerts); - if (camera->getOrigin().isExactlyZero()) - { //origin is invalid, draw entire box - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8); - } - else - { - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); - } - glEndQueryARB(GL_SAMPLES_PASSED_ARB); - - if (use_depth_clamp) - { - glDisable(GL_DEPTH_CLAMP); + if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY)) + { + buildOcclusion(); + } + + // Depth clamp all water to avoid it being culled as a result of being + // behind the far clip plane, and in the case of edge water to avoid + // it being culled while still visible. + bool const use_depth_clamp = gGLManager.mHasDepthClamp && + (mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER || + mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER); + if (use_depth_clamp) + { + glEnable(GL_DEPTH_CLAMP); + } +#if !LL_DARWIN + U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; + + glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]); + + mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); + + if (camera->getOrigin().isExactlyZero()) + { //origin is invalid, draw entire box + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0); + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8); + } + else + { + mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0])); + } + + glEndQueryARB(mode); +#endif + if (use_depth_clamp) + { + glDisable(GL_DEPTH_CLAMP); + } } - } - setOcclusionState(LLSpatialGroup::QUERY_PENDING); - clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); + setOcclusionState(LLSpatialGroup::QUERY_PENDING); + clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); + } } } } @@ -2607,17 +2640,17 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) gGL.color4f(0.f, 0.75f, 0.f, 0.5f); pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX); } - else if (camera && group->mOcclusionVerts) + else if (camera && group->mOcclusionVerts.notNull()) { LLVertexBuffer::unbind(); - glVertexPointer(3, GL_FLOAT, 16, group->mOcclusionVerts); - + group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); + glColor4f(1.0f, 0.f, 0.f, 0.5f); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0])); + group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glColor4f(1.0f, 1.f, 1.f, 1.0f); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0])); + group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0])); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 16ec9f780b..85fd66b297 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -59,7 +59,8 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe void pushVerts(LLFace* face, U32 mask); // get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera -U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center); +U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center); +U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center); class LLDrawInfo : public LLRefCount { @@ -393,7 +394,7 @@ public: LLSpatialPartition* mSpatialPartition; LLPointer<LLVertexBuffer> mVertexBuffer; - LLVector4a* mOcclusionVerts; + LLPointer<LLVertexBuffer> mOcclusionVerts; GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; U32 mBufferUsage; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 021715e6cf..fbd6aad18f 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -308,24 +308,24 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::LLDragAndDropDictionary:: LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() { - // DT_NONE DT_SELF DT_AVATAR DT_OBJECT DT_LAND - // |--------------|---------------------------|---------------------------|-------------------------------|--------------| + // DT_NONE DT_SELF DT_AVATAR DT_OBJECT DT_LAND + // |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------| addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand)); - addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory,&LLToolDragAndDrop::dad3dUpdateInventoryCategory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_CLOTHING, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_OBJECT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dRezAttachmentFromInv, &LLToolDragAndDrop::dad3dGiveInventoryObject, &LLToolDragAndDrop::dad3dRezObjectOnObject, &LLToolDragAndDrop::dad3dRezObjectOnLand)); + addEntry(DAD_NOTECARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearCategory, &LLToolDragAndDrop::dad3dGiveInventoryCategory, &LLToolDragAndDrop::dad3dUpdateInventoryCategory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_ROOT_CATEGORY, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_GESTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dActivateGesture, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_BODYPART, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dWearItem, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_ANIMATION, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_GESTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dActivateGesture, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL)); // TODO: animation on self could play it? edit it? // TODO: gesture on self could play it? edit it? }; diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 14839d0525..4798bb536f 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -847,17 +847,18 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, { switch( cargo_type ) { - case DAD_CALLINGCARD: - case DAD_TEXTURE: - case DAD_SOUND: - case DAD_LANDMARK: - case DAD_SCRIPT: - case DAD_CLOTHING: - case DAD_OBJECT: - case DAD_NOTECARD: - case DAD_BODYPART: - case DAD_ANIMATION: - case DAD_GESTURE: + case DAD_CALLINGCARD: + case DAD_TEXTURE: + case DAD_SOUND: + case DAD_LANDMARK: + case DAD_SCRIPT: + case DAD_CLOTHING: + case DAD_OBJECT: + case DAD_NOTECARD: + case DAD_BODYPART: + case DAD_ANIMATION: + case DAD_GESTURE: + case DAD_MESH: { LLInventoryItem *item = (LLInventoryItem *)cargo_data; if( item && allowsEmbeddedItems() ) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 10126219f8..b5eadb6d25 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -834,7 +834,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { - LLPointer<LLViewerFetchedTexture> imagep = *iter3++; + LLViewerFetchedTexture* imagep = *iter3++; bool fetching = imagep->updateFetch(); if (fetching) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 9aa86ebed0..ded3e36cf6 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4962,6 +4962,28 @@ void LLVOAvatar::resetJointPositions( void ) mHasPelvisOffset = false; } //----------------------------------------------------------------------------- +// resetSpecificJointPosition +//----------------------------------------------------------------------------- +void LLVOAvatar::resetSpecificJointPosition( const std::string& name ) +{ + LLJoint* pJoint = mRoot.findJoint( name ); + + if ( pJoint ) + { + pJoint->restoreOldXform(); + pJoint->setId( LLUUID::null ); + //If we're reseting the pelvis position make sure not to apply offset + if ( name == "mPelvis" ) + { + mHasPelvisOffset = false; + } + } + else + { + llinfos<<"Did not find "<< name.c_str()<<llendl; + } +} +//----------------------------------------------------------------------------- // resetJointPositionsToDefault //----------------------------------------------------------------------------- void LLVOAvatar::resetJointPositionsToDefault( void ) @@ -4995,8 +5017,6 @@ void LLVOAvatar::resetJointPositionsToDefault( void ) mHasPelvisOffset = false; postPelvisSetRecalc(); } - - //----------------------------------------------------------------------------- // getCharacterPosition() //----------------------------------------------------------------------------- diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 2e41940f28..ce5ce045b9 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -169,6 +169,7 @@ public: void resetJointPositions( void );
void resetJointPositionsToDefault( void );
+ void resetSpecificJointPosition( const std::string& name );
virtual const char* getAnimationPrefix() { return "avatar"; }
virtual const LLUUID& getID();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 935bd4a588..5d1020fce8 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1159,10 +1159,15 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object) const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID() ); if ( pSkinData ) { - const int bindCnt = pSkinData->mAlternateBindMatrix.size(); - if ( bindCnt > 0 ) + const int jointCnt = pSkinData->mJointNames.size(); + bool fullRig = ( jointCnt>=20 ) ? true : false; + if ( fullRig ) { - LLVOAvatar::resetJointPositionsToDefault(); + const int bindCnt = pSkinData->mAlternateBindMatrix.size(); + if ( bindCnt > 0 ) + { + LLVOAvatar::resetJointPositionsToDefault(); + } } } } diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 145ee31260..6ea88abab8 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -40,6 +40,7 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) return apr_file->write(src, n_bytes) == n_bytes ; } + //--------------------------------------------------------------------------- // LLVOCacheEntry //--------------------------------------------------------------------------- @@ -212,8 +213,8 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const if(success) { success = check_write(apr_file, (void*)mBuffer, size); + } } -} return success ; } @@ -224,7 +225,7 @@ BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const // Format string used to construct filename for the object cache static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc"; -const U32 NUM_ENTRIES_TO_PURGE = 16 ; +const U32 NUM_ENTRIES_TO_PURGE = 50; const char* object_cache_dirname = "objectcache"; const char* header_filename = "object.cache"; @@ -259,7 +260,6 @@ void LLVOCache::destroyClass() LLVOCache::LLVOCache(): mInitialized(FALSE), mReadOnly(TRUE), - mNumEntries(0), mCacheSize(1) { mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled"); @@ -286,8 +286,15 @@ void LLVOCache::setDirNames(ELLPath location) void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version) { - if(mInitialized || !mEnabled) + if(!mEnabled) + { + llwarns << "Not initializing cache: Cache is currently disabled." << llendl; + return ; + } + + if(mInitialized) { + llwarns << "Cache already initialized." << llendl; return ; } @@ -321,6 +328,7 @@ void LLVOCache::removeCache(ELLPath location) { if(mReadOnly) { + llwarns << "Not removing cache at " << location << ": Cache is currently in read-only mode." << llendl; return ; } @@ -339,6 +347,7 @@ void LLVOCache::removeCache() llassert_always(mInitialized) ; if(mReadOnly) { + llwarns << "Not clearing object cache: Cache is currently in read-only mode." << llendl; return ; } @@ -352,16 +361,8 @@ void LLVOCache::removeCache() void LLVOCache::clearCacheInMemory() { - if(!mHeaderEntryQueue.empty()) - { - for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter) - { - delete *iter ; - } - mHeaderEntryQueue.clear(); - mHandleEntryMap.clear(); - mNumEntries = 0 ; - } + std::for_each(mHandleEntryMap.begin(), mHandleEntryMap.end(), DeletePairedPointer()); + mHandleEntryMap.clear(); } void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename) @@ -379,6 +380,7 @@ void LLVOCache::removeFromCache(U64 handle) { if(mReadOnly) { + llwarns << "Not removing cache for handle " << handle << ": Cache is currently in read-only mode." << llendl; return ; } @@ -391,7 +393,6 @@ BOOL LLVOCache::checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes) { if(!check_read(apr_file, src, n_bytes)) { - delete apr_file ; removeCache() ; return FALSE ; } @@ -403,7 +404,6 @@ BOOL LLVOCache::checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes) { if(!check_write(apr_file, src, n_bytes)) { - delete apr_file ; removeCache() ; return FALSE ; } @@ -415,7 +415,8 @@ void LLVOCache::readCacheHeader() { if(!mEnabled) { - return ; + llwarns << "Not reading cache header: Cache is currently disabled." << llendl; + return; } //clear stale info. @@ -428,28 +429,29 @@ void LLVOCache::readCacheHeader() //read the meta element if(!checkRead(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo))) { - return ; + llwarns << "Error reading meta information from cache header." << llendl; + delete apr_file; + return; } HeaderEntryInfo* entry ; - mNumEntries = 0 ; - while(mNumEntries < mCacheSize) + for(U32 entry_index = 0; entry_index < mCacheSize; ++entry_index) { entry = new HeaderEntryInfo() ; if(!checkRead(apr_file, entry, sizeof(HeaderEntryInfo))) { + llwarns << "Error reading cache header entry. (entry_index=" << entry_index << ")" << llendl; delete entry ; - return ; + break; } else if(!entry->mTime) //end of the cache. { delete entry ; - return ; + break; } - entry->mIndex = mNumEntries++ ; - mHeaderEntryQueue.insert(entry) ; - mHandleEntryMap[entry->mHandle] = entry ; + entry->mIndex = entry_index; + mHandleEntryMap[entry->mHandle] = entry; } delete apr_file ; @@ -462,40 +464,57 @@ void LLVOCache::readCacheHeader() void LLVOCache::writeCacheHeader() { - if(mReadOnly || !mEnabled) + if (!mEnabled) { - return ; - } + llwarns << "Not writing cache header: Cache is currently disabled." << llendl; + return; + } + + if(mReadOnly) + { + llwarns << "Not writing cache header: Cache is currently in read-only mode." << llendl; + return; + } LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); //write the meta element if(!checkWrite(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo))) { - return ; + llwarns << "Error writing meta information to cache header." << llendl; + delete apr_file; + return; } - mNumEntries = 0 ; - for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; iter != mHeaderEntryQueue.end(); ++iter) + U32 entry_index = 0; + handle_entry_map_t::iterator iter_end = mHandleEntryMap.end(); + for(handle_entry_map_t::iterator iter = mHandleEntryMap.begin(); + iter != iter_end; + ++iter) { - (*iter)->mIndex = mNumEntries++ ; - if(!checkWrite(apr_file, (void*)*iter, sizeof(HeaderEntryInfo))) + HeaderEntryInfo* entry = iter->second; + entry->mIndex = entry_index++; + if(!checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo))) { - return ; + llwarns << "Failed to write cache header for entry " << entry->mHandle << " (entry_index = " << entry_index << ")" << llendl; + delete apr_file; + return; } } - mNumEntries = mHeaderEntryQueue.size() ; - if(mNumEntries < mCacheSize) + // Why do we need to fill the cache header with default entries? DK 2010-12-14 + // It looks like we currently rely on the file being pre-allocated so we can seek during updateEntry(). + if(entry_index < mCacheSize) { HeaderEntryInfo* entry = new HeaderEntryInfo() ; - for(U32 i = mNumEntries ; i < mCacheSize; i++) + for(; entry_index < mCacheSize; ++entry_index) { //fill the cache with the default entry. if(!checkWrite(apr_file, entry, sizeof(HeaderEntryInfo))) { + llwarns << "Failed to fill cache header with default entries (entry_index = " << entry_index << "). Switching to read-only mode." << llendl; mReadOnly = TRUE ; //disable the cache. - return ; + break; } } delete entry ; @@ -508,13 +527,16 @@ BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry) LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp); apr_file->seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ; - return checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; + BOOL result = checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ; + delete apr_file; + return result; } void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) { if(!mEnabled) { + llwarns << "Not reading cache for handle " << handle << "): Cache is currently disabled." << llendl; return ; } llassert_always(mInitialized); @@ -522,6 +544,7 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; if(iter == mHandleEntryMap.end()) //no cache { + llwarns << "No handle map entry for " << handle << llendl; return ; } @@ -532,12 +555,13 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca LLUUID cache_id ; if(!checkRead(apr_file, cache_id.mData, UUID_BYTES)) { + llwarns << "Error reading cache_id from " << filename << llendl; + delete apr_file; return ; } if(cache_id != id) { - llinfos << "Cache ID doesn't match for this region, discarding"<< llendl; - + llwarns << "Cache ID (" << cache_id << ") doesn't match id for this region (" << id << "), discarding. handle = " << handle << llendl; delete apr_file ; return ; } @@ -545,6 +569,8 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca S32 num_entries; if(!checkRead(apr_file, &num_entries, sizeof(S32))) { + llwarns << "Error reading num_entries from " << filename << llendl; + delete apr_file; return ; } @@ -553,13 +579,12 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file); if (!entry->getLocalID()) { - llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl; + llwarns << "Aborting cache file load for " << filename << ", cache file corruption! (entry number = " << i << ")" << llendl; delete entry ; break; } cache_entry_map[entry->getLocalID()] = entry; } - num_entries = cache_entry_map.size() ; delete apr_file ; return ; @@ -568,40 +593,53 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca void LLVOCache::purgeEntries() { U32 limit = mCacheSize - NUM_ENTRIES_TO_PURGE ; - while(mHeaderEntryQueue.size() > limit) + // Construct a vector of entries out of the map so we can sort by time. + std::vector<HeaderEntryInfo*> header_vector; + handle_entry_map_t::iterator iter_end = mHandleEntryMap.end(); + for (handle_entry_map_t::iterator iter = mHandleEntryMap.begin(); + iter != iter_end; + ++iter) + { + header_vector.push_back(iter->second); + } + // Sort by time, oldest first. + std::sort(header_vector.begin(), header_vector.end(), header_entry_less()); + while(header_vector.size() > limit) { - header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; - HeaderEntryInfo* entry = *iter ; + HeaderEntryInfo* entry = header_vector.front(); - removeFromCache(entry->mHandle) ; - mHandleEntryMap.erase(entry->mHandle) ; - mHeaderEntryQueue.erase(iter) ; - delete entry ; + removeFromCache(entry->mHandle); + mHandleEntryMap.erase(entry->mHandle); + header_vector.erase(header_vector.begin()); + delete entry; } writeCacheHeader() ; + // *TODO: Verify that we can avoid re-reading the cache header. DK 2010-12-14 readCacheHeader() ; - mNumEntries = mHandleEntryMap.size() ; } void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) { if(!mEnabled) { + llwarns << "Not writing cache for handle " << handle << "): Cache is currently disabled." << llendl; return ; } llassert_always(mInitialized); if(mReadOnly) { + llwarns << "Not writing cache for handle " << handle << "): Cache is currently in read-only mode." << llendl; return ; } HeaderEntryInfo* entry; handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ; + U32 num_handle_entries = mHandleEntryMap.size(); if(iter == mHandleEntryMap.end()) //new entry - { - if(mNumEntries >= mCacheSize) + { + if(num_handle_entries >= mCacheSize) { purgeEntries() ; } @@ -609,28 +647,26 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry: entry = new HeaderEntryInfo(); entry->mHandle = handle ; entry->mTime = time(NULL) ; - entry->mIndex = mNumEntries++ ; - mHeaderEntryQueue.insert(entry) ; + entry->mIndex = num_handle_entries++; mHandleEntryMap[handle] = entry ; } else { + // Update access time. entry = iter->second ; entry->mTime = time(NULL) ; - - //resort - mHeaderEntryQueue.erase(entry) ; - mHeaderEntryQueue.insert(entry) ; } //update cache header if(!updateEntry(entry)) { + llwarns << "Failed to update cache header index " << entry->mIndex << ". handle = " << handle << llendl; return ; //update failed. } if(!dirty_cache) { + llwarns << "Skipping write to cache for handle " << handle << ": cache not dirty" << llendl; return ; //nothing changed, no need to update. } @@ -641,12 +677,16 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry: if(!checkWrite(apr_file, (void*)id.mData, UUID_BYTES)) { + llwarns << "Error writing id to " << filename << llendl; + delete apr_file; return ; } S32 num_entries = cache_entry_map.size() ; if(!checkWrite(apr_file, &num_entries, sizeof(S32))) { + llwarns << "Error writing num_entries to " << filename << llendl; + delete apr_file; return ; } @@ -654,10 +694,10 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry: { if(!iter->second->writeToFile(apr_file)) { + llwarns << "Aborting cache file write for " << filename << ", error writing to file!" << llendl; //failed - delete apr_file ; removeCache() ; - return ; + break; } } diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index ed2bc8bafe..014112718e 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -95,10 +95,13 @@ private: { bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const { - return lhs->mTime < rhs->mTime; // older entry in front of queue (set) + if (lhs->mTime == rhs->mTime) + { + return lhs->mHandle < rhs->mHandle; + } + return lhs->mTime < rhs->mTime; // older entry in front } }; - typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t; typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t; private: LLVOCache() ; @@ -134,11 +137,9 @@ private: BOOL mReadOnly ; HeaderMetaInfo mMetaInfo; U32 mCacheSize; - U32 mNumEntries; std::string mHeaderFileName ; std::string mObjectCacheDirName; LLVolatileAPRPool* mLocalAPRFilePoolp ; - header_entry_queue_t mHeaderEntryQueue; handle_entry_map_t mHandleEntryMap; static LLVOCache* sInstance ; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 471df30bfe..366213073e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4068,39 +4068,44 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) {
LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId );
-
+
if ( pSkinData )
{
const int bindCnt = pSkinData->mAlternateBindMatrix.size();
if ( bindCnt > 0 )
{
const int jointCnt = pSkinData->mJointNames.size();
- for ( int i=0; i<jointCnt; ++i )
+ bool fullRig = (jointCnt>=20) ? true : false;
+ if ( fullRig )
{
- std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
- LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
- if ( pJoint && pJoint->getId() != currentId )
- {
- pJoint->setId( currentId );
- const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
- //If joint is a pelvis then handle by setting avPos+offset
- if ( lookingForJoint == "mPelvis" )
- {
- //Apply av pos + offset
- if ( !pAvatarVO->hasPelvisOffset() )
- {
- pAvatarVO->setPelvisOffset( true, jointPos );
- //Trigger to rebuild viewer AV
- pelvisGotSet = true;
- }
+ for ( int i=0; i<jointCnt; ++i )
+ {
+ std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
+ //llinfos<<"joint name "<<lookingForJoint.c_str()<<llendl;
+ LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
+ if ( pJoint && pJoint->getId() != currentId )
+ {
+ pJoint->setId( currentId );
+ const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
+ //If joint is a pelvis then handle by setting avPos+offset
+ if ( lookingForJoint == "mPelvis" )
+ {
+ //Apply av pos + offset
+ if ( !pAvatarVO->hasPelvisOffset() )
+ {
+ pAvatarVO->setPelvisOffset( true, jointPos );
+ //Trigger to rebuild viewer AV
+ pelvisGotSet = true;
+ }
+ }
+ else
+ {
+ //Straight set for ALL joints except pelvis
+ pJoint->storeCurrentXform( jointPos );
+ }
}
- else
- {
- //Straight set for ALL joints except pelvis
- pJoint->storeCurrentXform( jointPos );
- }
}
- }
+ }
}
}
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5e1f56ac97..24327bf535 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4136,11 +4136,12 @@ void LLPipeline::renderDebug() gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); gGL.end(); - } - + } } - /*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + /*gGL.flush(); + glLineWidth(16-i*2); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4155,7 +4156,9 @@ void LLPipeline::renderDebug() } } } - }*/ + } + gGL.flush(); + glLineWidth(1.f);*/ } } @@ -7084,6 +7087,8 @@ void LLPipeline::renderDeferredLighting() std::list<LLVector4> light_colors; + LLVertexBuffer::unbind(); + F32 v[24]; glVertexPointer(3, GL_FLOAT, 0, v); @@ -7173,7 +7178,7 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center)); stop_glerror(); } } @@ -7239,7 +7244,7 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center)); } gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); unbindDeferredShader(gDeferredSpotLightProgram); @@ -7650,11 +7655,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLCamera camera = camera_in; camera.setFar(camera.getFar()*0.87654321f); LLPipeline::sReflectionRender = TRUE; - S32 occlusion = LLPipeline::sUseOcclusion; - - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - - LLPipeline::sUseOcclusion = llmin(occlusion, 1); gPipeline.pushRenderTypeMask(); @@ -7693,19 +7693,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glClearColor(0,0,0,0); mWaterRef.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0; gGL.setColorMask(true, true); mWaterRef.clear(); gGL.setColorMask(true, false); mWaterRef.getViewport(gGLViewport); - + stop_glerror(); glPushMatrix(); mat.set_scale(glh::vec3f(1,1,-1)); mat.set_translate(glh::vec3f(0,0,height*2.f)); - + glh::matrix4f current = glh_get_current_modelview(); mat = current * mat; @@ -7725,22 +7726,24 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glCullFace(GL_FRONT); static LLCullResult ref_result; - + if (LLDrawPoolWater::sNeedsDistortionUpdate) { //initial sky pass (no user clip plane) { //mask out everything but the sky gPipeline.pushRenderTypeMask(); gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); + static LLCullResult result; updateCull(camera, result); stateSort(camera, result); + andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); renderGeom(camera, TRUE); gPipeline.popRenderTypeMask(); @@ -7749,23 +7752,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.pushRenderTypeMask(); clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_GROUND, - LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::END_RENDER_TYPES); - S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); + S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); if (detail > 0) { //mask out selected geometry based on reflection detail if (detail < 4) { clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); - if (detail < 3) - { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); - if (detail < 2) + if (detail < 3) { + clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + if (detail < 2) + { clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); } } @@ -7776,16 +7779,16 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) updateCull(camera, ref_result, 1); stateSort(camera, ref_result); } - - if (LLDrawPoolWater::sNeedsDistortionUpdate) - { - if (gSavedSettings.getS32("RenderReflectionDetail") > 0) + + if (LLDrawPoolWater::sNeedsDistortionUpdate) { - gPipeline.grabReferences(ref_result); - LLGLUserClipPlane clip_plane(plane, mat, projection); - renderGeom(camera); - } - } + if (gSavedSettings.getS32("RenderReflectionDetail") > 0) + { + gPipeline.grabReferences(ref_result); + LLGLUserClipPlane clip_plane(plane, mat, projection); + renderGeom(camera); + } + } gPipeline.popRenderTypeMask(); } @@ -7823,6 +7826,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLColor4& col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); mWaterDis.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; mWaterDis.getViewport(gGLViewport); if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) @@ -7861,7 +7865,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; LLPlane npnorm(-pnorm, -pd); LLViewerCamera::getInstance()->setUserClipPlane(npnorm); - LLPipeline::sUseOcclusion = occlusion; LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -7871,6 +7874,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); } + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; } } @@ -7993,6 +7998,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera //glCullFace(GL_FRONT); + LLVertexBuffer::unbind(); + { LLFastTimer ftm(FTM_SHADOW_SIMPLE); LLGLDisable test(GL_ALPHA_TEST); diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index e34636db57..f23cb60121 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -169,12 +169,12 @@ Queue Mode: </text> <combo_box follows="top|left" name="build_operator" top_pad="5" left="45" width="100" height="20"> - <combo_item name="half_edge_collapse"> - Half Edge Collapse - </combo_item> <combo_item name="edge_collapse"> Edge Collapse </combo_item> + <combo_item name="half_edge_collapse"> + Half Edge Collapse + </combo_item> </combo_box> <combo_box follows="top|left" name="queue_mode" left_pad="5" width="100" height="20"> @@ -205,7 +205,7 @@ Lock </combo_item> </combo_box> - <spinner follows="left|top" name="share_tolerance" left_pad="5" width="100" height="20"/> + <spinner follows="left|top" name="share_tolerance" left_pad="5" width="100" decimal_digits="5" initial_value="0.00001" height="20"/> <text left="10" top_pad="35" follows="top|left" width="240" height="15"> Generate Normals @@ -295,6 +295,7 @@ <check_box name="Close Holes (Slow)" follows="top|left" top_pad="10" height="15" label="Close Holes (slow)"/> <button left="200" bottom_delta="0" width="90" follows="top|left" label="Analyze" name="Decompose" height="20"/> + <button left="200" bottom_delta="0" width="90" follows="top|left" label="Cancel" name="decompose_cancel" visble="false" height="20"/> </panel> @@ -324,6 +325,7 @@ <slider name="Detail Scale" label="Detail Scale:" label_width="120" width="270" follows="top|left" top_pad="10" height="20"/> <slider name="Retain%" label="Retain:" label_width="120" width="270" follows="top|left" bottom_delta="0" left_delta="0" visible="false" height="20"/> <button left="190" width="90" follows="top|left" label="Simplify" name="Simplify" height="20"/> + <button left="190" bottom_delta="0" width="90" follows="top|left" label="Cancel" name="simplify_cancel" height="20"/> </panel> diff --git a/indra/newview/skins/default/xui/en/inspect_object.xml b/indra/newview/skins/default/xui/en/inspect_object.xml index eb2e7ea788..8d14c974b4 100644 --- a/indra/newview/skins/default/xui/en/inspect_object.xml +++ b/indra/newview/skins/default/xui/en/inspect_object.xml @@ -76,13 +76,24 @@ L$30,000 </text> <!-- Overlapping buttons for all default actions. Show "Buy" if for sale, "Sit" if can sit, etc. --> + <icon + name="secure_browsing" + image_name="Lock" + left="0" + visible="false" + width="18" + height="18" + top="103" + tool_tip="Secure Browsing" + follows="left|top" /> <text follows="all" font="SansSerifSmall" height="13" name="object_media_url" - width="220" - top_pad="0" + width="207" + left_pad="2" + top_delta="0" max_length = "50" use_ellipses="true"> http://www.superdupertest.com @@ -135,16 +146,6 @@ L$30,000 name="open_btn" top_delta="0" width="80" /> - <icon - name="secure_browsing" - image_name="Lock" - left_delta="80" - visible="false" - width="18" - height="18" - top_delta="0" - tool_tip="Secure Browsing" - follows="left|top" /> <!-- non-overlapping buttons here --> <button @@ -153,7 +154,7 @@ L$30,000 label="More" layout="topleft" name="more_info_btn" - left_delta="10" + left_pad="10" top_delta="0" tab_stop="false" width="80" /> diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml index 8fe89d3934..ea263d05ce 100644 --- a/indra/newview/skins/default/xui/en/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml @@ -8,7 +8,7 @@ top="724" visible="false" width="128"> - <menu_item_call + <menu_item_call label="Zoom Close" name="Zoom Close"> <menu_item_call.on_click @@ -29,7 +29,14 @@ function="Minimap.Zoom" parameter="far" /> </menu_item_call> - <menu_item_separator /> + <menu_item_call + label="Zoom Default" + name="Zoom Default"> + <menu_item_call.on_click + function="Minimap.Zoom" + parameter="default" /> + </menu_item_call> + <menu_item_separator /> <menu_item_check label="Rotate Map" name="Rotate Map"> diff --git a/indra/newview/skins/default/xui/en/panel_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml index 15a3191bdf..cd834b61ce 100644 --- a/indra/newview/skins/default/xui/en/panel_group_invite.xml +++ b/indra/newview/skins/default/xui/en/panel_group_invite.xml @@ -94,7 +94,7 @@ left_pad="2" name="cancel_button" top_delta="0" - width="70" /> + width="65" /> <string name="GroupInvitation"> Group Invitation diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index 1270a21710..61d6cbb2d0 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -117,7 +117,7 @@ name="map_button" top_delta="-4" left_pad="0" - width="60" + width="57" enabled="false" /> <text type="string" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index da366f30ae..f0ce8b849a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -296,6 +296,7 @@ <check_box name="media_auto_play_btn" control_name="ParcelMediaAutoPlayEnable" + enabled_control="AudioStreamingMedia" value="true" follows="left|bottom|right" height="15" diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp index b976ac5ea9..acc6e814bc 100644 --- a/indra/newview/tests/llworldmap_test.cpp +++ b/indra/newview/tests/llworldmap_test.cpp @@ -25,13 +25,16 @@ * $/LicenseInfo$ */ -// Precompiled header: almost always required for newview cpp files -#include "../llviewerprecompiledheaders.h" -// Class to test -#include "../llworldmap.h" // Dependencies -#include "../llviewerimagelist.h" +#include "linden_common.h" +#include "llapr.h" +#include "llsingleton.h" +#include "lltrans.h" +#include "lluistring.h" +#include "../llviewertexture.h" #include "../llworldmapmessage.h" +// Class to test +#include "../llworldmap.h" // Tut header #include "../test/lltut.h" @@ -44,34 +47,29 @@ // * A simulator for a class can be implemented here. Please comment and document thoroughly. // Stub image calls -LLViewerImageList::LLViewerImageList() { } -LLViewerImageList::~LLViewerImageList() { } -LLViewerImageList gImageList; -LLViewerImage* LLViewerImageList::getImage(const LLUUID &image_id, - BOOL usemipmaps, - BOOL level_immediate, - LLGLint internal_format, - LLGLenum primary_format, - LLHost request_from_host) -{ return NULL; } -void LLViewerImage::setBoostLevel(S32 level) { } -void LLImageGL::setAddressMode(LLTexUnit::eTextureAddressMode mode) { } +void LLViewerTexture::setBoostLevel(S32 ) { } +void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { } +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, BOOL, LLViewerTexture::EBoostLevel, S8, + LLGLint, LLGLenum, LLHost ) { return NULL; } // Stub related map calls LLWorldMapMessage::LLWorldMapMessage() { } LLWorldMapMessage::~LLWorldMapMessage() { } void LLWorldMapMessage::sendItemRequest(U32 type, U64 handle) { } void LLWorldMapMessage::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent) { } + LLWorldMipmap::LLWorldMipmap() { } LLWorldMipmap::~LLWorldMipmap() { } void LLWorldMipmap::reset() { } void LLWorldMipmap::dropBoostLevels() { } void LLWorldMipmap::equalizeBoostLevels() { } -LLPointer<LLViewerImage> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 grid_y, S32 level, bool load) -{ return NULL; } +LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32 grid_y, S32 level, bool load) { return NULL; } // Stub other stuff -BOOL gPacificDaylightTime; +std::string LLTrans::getString(const std::string &, const LLStringUtil::format_map_t& ) { return std::string("test_trans"); } +void LLUIString::updateResult() const { } +void LLUIString::setArg(const std::string& , const std::string& ) { } +void LLUIString::assign(const std::string& ) { } // End Stubbing // ------------------------------------------------------------------------------------------- @@ -237,7 +235,7 @@ namespace tut // Test 9 : setLandForSaleImage() / getLandForSaleImage() LLUUID id; mSim->setLandForSaleImage(id); - LLPointer<LLViewerImage> image = mSim->getLandForSaleImage(); + LLPointer<LLViewerFetchedTexture> image = mSim->getLandForSaleImage(); ensure("LLSimInfo::getLandForSaleImage() test failed", image.isNull()); // Test 10 : isPG() mSim->setAccess(SIM_ACCESS_PG); @@ -370,7 +368,7 @@ namespace tut } // Test 7 : getObjectsTile() try { - LLPointer<LLViewerImage> image = mWorld->getObjectsTile((U32)(X_WORLD_TEST/REGION_WIDTH_METERS), (U32)(Y_WORLD_TEST/REGION_WIDTH_METERS), 1); + LLPointer<LLViewerFetchedTexture> image = mWorld->getObjectsTile((U32)(X_WORLD_TEST/REGION_WIDTH_METERS), (U32)(Y_WORLD_TEST/REGION_WIDTH_METERS), 1); ensure("LLWorldMap::getObjectsTile() failed", image.isNull()); } catch (...) { fail("LLWorldMap::getObjectsTile() test failed with exception"); diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp index 54887ae219..4c0959d1a9 100644 --- a/indra/newview/tests/llworldmipmap_test.cpp +++ b/indra/newview/tests/llworldmipmap_test.cpp @@ -25,12 +25,12 @@ * $/LicenseInfo$ */ -// Precompiled header: almost always required for newview cpp files -#include "../llviewerprecompiledheaders.h" +// Dependencies +#include "linden_common.h" +#include "../llviewertexture.h" +#include "../llviewercontrol.h" // Class to test #include "../llworldmipmap.h" -// Dependencies -#include "../llviewerimagelist.h" // Tut header #include "../test/lltut.h" @@ -42,19 +42,14 @@ // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code) // * A simulator for a class can be implemented here. Please comment and document thoroughly. -LLViewerImageList::LLViewerImageList() { } -LLViewerImageList::~LLViewerImageList() { } - -LLViewerImageList gImageList; +void LLViewerTexture::setBoostLevel(S32 ) { } +LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, BOOL, LLViewerTexture::EBoostLevel, S8, + LLGLint, LLGLenum, const LLUUID& ) { return NULL; } -LLViewerImage* LLViewerImageList::getImageFromUrl(const std::string& url, - BOOL usemipmaps, - BOOL level_immediate, - LLGLint internal_format, - LLGLenum primary_format, - const LLUUID& force_id) -{ return NULL; } -void LLViewerImage::setBoostLevel(S32 level) { } +LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) { } +LLControlGroup::~LLControlGroup() { } +std::string LLControlGroup::getString(const std::string& ) { return std::string("test_url"); } +LLControlGroup gSavedSettings("test_settings"); // End Stubbing // ------------------------------------------------------------------------------------------- |