diff --git a/LICENSES/apr_suite.txt b/LICENSES/apr_suite.txt deleted file mode 100644 index 17e9556a2..000000000 --- a/LICENSES/apr_suite.txt +++ /dev/null @@ -1,14 +0,0 @@ -Copyright 2000-2004 The Apache Software Foundation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - diff --git a/LICENSES/freetype.txt b/LICENSES/freetype.txt deleted file mode 100644 index 225e1fafc..000000000 --- a/LICENSES/freetype.txt +++ /dev/null @@ -1,3 +0,0 @@ -Portions of this software are copyright (c) 2003 The FreeType -Project (www.freetype.org). All rights reserved. - diff --git a/LICENSES/jsoncpp.txt b/LICENSES/jsoncpp.txt deleted file mode 100644 index 228ae58d6..000000000 --- a/LICENSES/jsoncpp.txt +++ /dev/null @@ -1,2 +0,0 @@ -The json-cpp library and this documentation are in Public Domain. -Retrieved from http://jsoncpp.sourceforge.net/ on 2009-09-04. diff --git a/LICENSES/ndofdev.txt b/LICENSES/ndofdev.txt deleted file mode 100644 index e789ea9c6..000000000 --- a/LICENSES/ndofdev.txt +++ /dev/null @@ -1,23 +0,0 @@ -* Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com) -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * The name of its contributors may not be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY Jan Ciger ''AS IS'' AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL Jan Ciger BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSES/openSSL.txt b/LICENSES/openSSL.txt deleted file mode 100644 index efe806415..000000000 --- a/LICENSES/openSSL.txt +++ /dev/null @@ -1,116 +0,0 @@ -Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -All rights reserved. - -This package is an SSL implementation written -by Eric Young (eay@cryptsoft.com). -The implementation was written so as to conform with Netscapes SSL. - -This library is free for commercial and non-commercial use as long as -the following conditions are aheared to. The following conditions -apply to all code found in this distribution, be it the RC4, RSA, -lhash, DES, etc., code; not just the SSL code. The SSL documentation -included with this distribution is covered by the same copyright terms -except that the holder is Tim Hudson (tjh@cryptsoft.com). - -Copyright remains Eric Young's, and as such any Copyright notices in -the code are not to be removed. -If this package is used in a product, Eric Young should be given attribution -as the author of the parts of the library used. -This can be in the form of a textual message at program startup or -in documentation (online or textual) provided with the package. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. All advertising materials mentioning features or use of this software - must display the following acknowledgement: - "This product includes cryptographic software written by - Eric Young (eay@cryptsoft.com)" - The word 'cryptographic' can be left out if the rouines from the library - being used are not cryptographic related :-). -4. If you include any Windows specific code (or a derivative thereof) from - the apps directory (application code) you must include an acknowledgement: - "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - -THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -The licence and distribution terms for any publically available version or -derivative of this code cannot be changed. i.e. this code cannot simply be -copied and put under another distribution licence -[including the GNU Public Licence.] - -**************** -* SSLeay -**************** - -Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) -All rights reserved. - -This package is an SSL implementation written -by Eric Young (eay@cryptsoft.com). -The implementation was written so as to conform with Netscapes SSL. - -This library is free for commercial and non-commercial use as long as -the following conditions are aheared to. The following conditions -apply to all code found in this distribution, be it the RC4, RSA, -lhash, DES, etc., code; not just the SSL code. The SSL documentation -included with this distribution is covered by the same copyright terms -except that the holder is Tim Hudson (tjh@cryptsoft.com). - -Copyright remains Eric Young's, and as such any Copyright notices in -the code are not to be removed. -If this package is used in a product, Eric Young should be given attribution -as the author of the parts of the library used. -This can be in the form of a textual message at program startup or -in documentation (online or textual) provided with the package. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. All advertising materials mentioning features or use of this software - must display the following acknowledgement: - "This product includes cryptographic software written by - Eric Young (eay@cryptsoft.com)" - The word 'cryptographic' can be left out if the rouines from the library - being used are not cryptographic related :-). -4. If you include any Windows specific code (or a derivative thereof) from - the apps directory (application code) you must include an acknowledgement: - "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - -THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -The licence and distribution terms for any publically available version or -derivative of this code cannot be changed. i.e. this code cannot simply be -copied and put under another distribution licence -[including the GNU Public Licence.] - diff --git a/LICENSES/xmlrpc-epi.txt b/LICENSES/xmlrpc-epi.txt deleted file mode 100644 index 5614abc09..000000000 --- a/LICENSES/xmlrpc-epi.txt +++ /dev/null @@ -1,10 +0,0 @@ -Copyright 2000 Epinions, Inc. - -Subject to the following 3 conditions, Epinions, Inc. permits you, free of charge, to (a) use, copy, distribute, modify, perform and display this software and associated documentation files (the "Software"), and (b) permit others to whom the Software is furnished to do so as well. - -1) The above copyright notice and this permission notice shall be included without modification in all copies or substantial portions of the Software. - -2) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY OR CONDITION OF ANY KIND, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF ACCURACY, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. - -3) IN NO EVENT SHALL EPINIONS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE (HOWEVER ARISING, INCLUDING NEGLIGENCE), EVEN IF EPINIONS, INC. IS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. - diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index e5e3e5635..9aad06080 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -10,6 +10,8 @@ include(Variables) set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1") set(CMAKE_CXX_FLAGS_RELEASE "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG") +set(CMAKE_C_FLAGS_RELEASE + "${CMAKE_CXX_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_RELEASESSE2 "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=1 -DNDEBUG") #llimage now requires this (?) @@ -65,7 +67,7 @@ if (WINDOWS) /Oy- ) - if(MSVC80 OR MSVC90 OR MSVC100) + if(MSVC80 OR MSVC90 OR MSVC10) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0" CACHE STRING "C++ compiler release options" FORCE) @@ -78,7 +80,7 @@ if (WINDOWS) add_definitions( /Zc:wchar_t- ) - endif (MSVC80 OR MSVC90 OR MSVC100) + endif (MSVC80 OR MSVC90 OR MSVC10) # Are we using the crummy Visual Studio KDU build workaround? if (NOT VS_DISABLE_FATAL_WARNINGS) @@ -97,7 +99,7 @@ if (WINDOWS) elseif (MSVC90) set(MSVC_DIR 9.0) set(MSVC_SUFFIX 90) - elseif (MSVC100) + elseif (MSVC10) set(MSVC_DIR 10.0) set(MSVC_SUFFIX 100) endif (MSVC71) @@ -207,6 +209,7 @@ if (LINUX) set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_RELEASE "-O3 ${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_C_FLAGS_RELEASE "-O3 ${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_RELEASESSE2 "-O3 ${CMAKE_CXX_FLAGS_RELEASESSE2}") set(CMAKE_C_FLAGS_RELEASESSE2 "-O3 ${CMAKE_C_FLAGS_RELEASESSE2}") endif (LINUX) diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 9942a08a5..1379d3a41 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -17,7 +17,7 @@ else (STANDALONE) set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) if (WINDOWS) - set(BOOST_VERSION 1_39) + set(BOOST_VERSION 1_45) # SNOW-788 # 00-Common.cmake alreay sets MSVC_SUFFIX to be correct for the VS we are using eg VC71, VC80, VC90 etc diff --git a/indra/cmake/OpenGL.cmake b/indra/cmake/OpenGL.cmake index 6a2b6811a..3dcd396c5 100644 --- a/indra/cmake/OpenGL.cmake +++ b/indra/cmake/OpenGL.cmake @@ -4,6 +4,7 @@ include(Prebuilt) if (NOT STANDALONE) use_prebuilt_binary(GL) # possible glh_linear should have its own .cmake file instead - use_prebuilt_binary(glh_linear) + #use_prebuilt_binary(glh_linear) + # actually... not any longer, it's now in git -SG set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include) endif (NOT STANDALONE) diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 9aa4b857e..780ed9830 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -426,7 +426,16 @@ protected: template class LLSingleton { + static bool &needsInit() + { + static bool needs_init = true; + return needs_init; + } public: + static bool instanceExists() + { + return !needsInit(); + } virtual ~LLSingleton() {} #ifdef LL_MSVC7 // workaround for VC7 compiler bug @@ -445,7 +454,7 @@ public: #endif { static T instance; - static bool needs_init = true; + bool &needs_init = needsInit(); if (needs_init) { needs_init = false; diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index 369b06b48..44ea80a36 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -51,7 +51,7 @@ public: void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));} void skip(const U32 index) { mBytep += mSkip*index;} - + U32 getSkip() const { return mSkip; } Object* get() { return mObjectp; } Object* operator->() { return mObjectp; } Object& operator *() { return *mObjectp; } diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 8461d5d86..4c1b7ec89 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -196,6 +196,13 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), } mImpl = j2cimpl_create_func(); + + // Clear data size table + for( S32 i = 0; i <= MAX_DISCARD_LEVEL; i++) + { // Array size is MAX_DISCARD_LEVEL+1 + mDataSizes[i] = 0; + } + } // virtual @@ -371,9 +378,44 @@ S32 LLImageJ2C::calcHeaderSize() return calcHeaderSizeJ2C(); } +// calcDataSize() returns how many bytes to read +// to load discard_level (including header and higher discard levels) S32 LLImageJ2C::calcDataSize(S32 discard_level) { - return calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), discard_level, mRate); + discard_level = llclamp(discard_level, 0, MAX_DISCARD_LEVEL); + + if ( mAreaUsedForDataSizeCalcs != (getHeight() * getWidth()) + || mDataSizes[0] == 0) + { + mAreaUsedForDataSizeCalcs = getHeight() * getWidth(); + + S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard + while ( level >= 0 ) + { + mDataSizes[level] = calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); + level--; + } + + /* This is technically a more correct way to calculate the size required + for each discard level, since they should include the size needed for + lower levels. Unfortunately, this doesn't work well and will lead to + download stalls. The true correct way is to parse the header. This will + all go away with http textures at some point. + + // Calculate the size for each discard level. Lower levels (higher quality) + // contain the cumulative size of higher levels + S32 total_size = calcHeaderSizeJ2C(); + + S32 level = MAX_DISCARD_LEVEL; // Start at the highest discard + while ( level >= 0 ) + { // Add in this discard level and all before it + total_size += calcDataSizeJ2C(getWidth(), getHeight(), getComponents(), level, mRate); + mDataSizes[level] = total_size; + level--; + } + */ + } + return mDataSizes[discard_level]; } S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes) diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index 23f6ef5fd..56782fbf0 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -87,6 +87,8 @@ protected: void updateRawDiscardLevel(); S32 mMaxBytes; // Maximum number of bytes of data to use... + S32 mDataSizes[MAX_DISCARD_LEVEL+1]; // Size of data required to reach a given level + U32 mAreaUsedForDataSizeCalcs; // Height * width used to calculate mDataSizes S8 mRawDiscardLevel; F32 mRate; BOOL mReversible; diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 455cd48ff..23f67919f 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -151,13 +151,8 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod /* open a byte stream */ cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); - /* decode the stream and fill the image structure, also fill in an additional - structure to get the decoding result. This structure is a bit unusual in that - it is not received through opj, but still has some dynamically allocated fields - that need to be cleared up at the end by calling a destroy function. */ - opj_codestream_info_t cinfo; - memset(&cinfo, 0, sizeof(opj_codestream_info_t)); - image = opj_decode_with_info(dinfo, cio, &cinfo); + /* decode the stream and fill the image structure */ + image = opj_decode(dinfo, cio); /* close the byte stream */ opj_cio_close(cio); @@ -171,70 +166,45 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod // The image decode failed if the return was NULL or the component // count was zero. The latter is just a sanity check before we // dereference the array. - if(!image) + if(!image || !image->numcomps) { - LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image - no image" << LL_ENDL; - return TRUE; // done - } - - S32 img_components = image->numcomps; - - if( !img_components ) // < 1 ||img_components > 4 ) - { - LL_DEBUGS("Openjpeg") << "ERROR -> decodeImpl: failed to decode image wrong number of components: " << img_components << LL_ENDL; + llwarns << "ERROR -> decodeImpl: failed to decode image!" << llendl; if (image) { - opj_destroy_cstr_info(&cinfo); opj_image_destroy(image); } + base.decodeFailed(); return TRUE; // done } // sometimes we get bad data out of the cache - check to see if the decode succeeded - int decompdifference = 0; - if (cinfo.numdecompos) // sanity + for (S32 i = 0; i < image->numcomps; i++) { - for (int comp = 0; comp < image->numcomps; comp++) - { /* get maximum decomposition level difference, first field is from the COD header and the second - is what is actually met in the codestream, NB: if everything was ok, this calculation will - return what was set in the cp_reduce value! */ - decompdifference = llmax(decompdifference, cinfo.numdecompos[comp] - image->comps[comp].resno_decoded); - } - if (decompdifference < 0) // sanity + if (image->comps[i].factor != base.getRawDiscardLevel()) { - decompdifference = 0; + // if we didn't get the discard level we're expecting, fail + opj_image_destroy(image); + base.decodeFailed(); + return TRUE; } } - - /* if OpenJPEG failed to decode all requested decomposition levels - the difference will be greater than this level */ - if (decompdifference > base.getRawDiscardLevel()) + if(image->numcomps <= first_channel) { - llwarns << "not enough data for requested discard level, setting mDecoding to FALSE, difference: " << (decompdifference - base.getRawDiscardLevel()) << llendl; - opj_destroy_cstr_info(&cinfo); - opj_image_destroy(image); - base.mDecoding = FALSE; - return TRUE; - } - - if(img_components <= first_channel) - { - // sanity - LL_DEBUGS("Openjpeg") << "trying to decode more channels than are present in image: numcomps: " << img_components << " first_channel: " << first_channel << LL_ENDL; + llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl; if (image) { - opj_destroy_cstr_info(&cinfo); opj_image_destroy(image); } - + + base.decodeFailed(); return TRUE; } // Copy image data into our raw image format (instead of the separate channel format - + S32 img_components = image->numcomps; S32 channels = img_components - first_channel; if( channels > max_channel_count ) channels = max_channel_count; @@ -274,19 +244,15 @@ BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod else // Some rare OpenJPEG versions have this bug. { llwarns << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << llendl; - opj_destroy_cstr_info(&cinfo); opj_image_destroy(image); - + + base.decodeFailed(); return TRUE; // done } } - /* free opj data structures */ - if (image) - { - opj_destroy_cstr_info(&cinfo); - opj_image_destroy(image); - } + /* free image data structure */ + opj_image_destroy(image); return TRUE; // done } @@ -349,7 +315,7 @@ BOOL LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, con OPJ_COLOR_SPACE color_space = CLRSPC_SRGB; opj_image_cmptparm_t cmptparm[MAX_COMPS]; opj_image_t * image = NULL; - S32 numcomps = llmin((S32)raw_image.getComponents(),(S32)MAX_COMPS); + S32 numcomps = llmin((S32)raw_image.getComponents(), MAX_COMPS); S32 width = raw_image.getWidth(); S32 height = raw_image.getHeight(); diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index 9046f9c35..a1b5c7908 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -1908,7 +1908,12 @@ BOOL LLDataPackerAsciiFile::getValueStr(const char *name, char *out_value, S32 v if (mFP) { fpos_t last_pos; - fgetpos(mFP, &last_pos); + if (0 != fgetpos(mFP, &last_pos)) // 0==success for fgetpos + { + llwarns << "Data packer failed to fgetpos" << llendl; + return FALSE; + } + if (fgets(buffer, DP_BUFSIZE, mFP) == NULL) { buffer[0] = '\0'; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index e58df16bb..4d0a076e7 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -599,3 +599,8 @@ bool LLHTTPClient::hasPump() { return theClientPump != NULL; } + +LLPumpIO &LLHTTPClient::getPump() +{ + return *theClientPump; +} diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index 3d0646e5f..44c685e38 100644 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -156,6 +156,8 @@ public: ///< must be called before any of the above calls are made static bool hasPump(); ///< for testing + static LLPumpIO &getPump(); + ///< Hippo special }; #endif // LL_LLHTTPCLIENT_H diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 1263ac83c..d708398b2 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -59,11 +59,13 @@ BOOL gDebugGL = FALSE; BOOL gClothRipple = FALSE; BOOL gNoRender = FALSE; +BOOL gGLActive = FALSE; LLMatrix4 gGLObliqueProjectionInverse; #define LL_GL_NAME_POOLING 0 LLGLNamePool::pool_list_t LLGLNamePool::sInstances; +std::list LLGLUpdate::sGLQ; #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS // ATI prototypes @@ -1054,7 +1056,7 @@ void clear_glerror() // // Static members -std::map LLGLState::sStateMap; +boost::unordered_map LLGLState::sStateMap; GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default @@ -1102,7 +1104,7 @@ void LLGLState::resetTextureStates() void LLGLState::dumpStates() { LL_INFOS("RenderState") << "GL States:" << LL_ENDL; - for (std::map::iterator iter = sStateMap.begin(); + for (boost::unordered_map::iterator iter = sStateMap.begin(); iter != sStateMap.end(); ++iter) { LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"TRUE":"FALSE") << LL_ENDL; @@ -1128,7 +1130,7 @@ void LLGLState::checkStates(const std::string& msg) LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL; } - for (std::map::iterator iter = sStateMap.begin(); + for (boost::unordered_map::iterator iter = sStateMap.begin(); iter != sStateMap.end(); ++iter) { LLGLenum state = iter->first; @@ -1767,6 +1769,8 @@ LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, G : mPrevDepthEnabled(sDepthEnabled), mPrevDepthFunc(sDepthFunc), mPrevWriteEnabled(sWriteEnabled) { stop_glerror(); + + checkState(); if (!depth_enabled) { // always disable depth writes if depth testing is disabled @@ -1798,6 +1802,7 @@ LLGLDepthTest::LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled, G LLGLDepthTest::~LLGLDepthTest() { + checkState(); if (sDepthEnabled != mPrevDepthEnabled ) { gGL.flush(); @@ -1819,6 +1824,26 @@ LLGLDepthTest::~LLGLDepthTest() } } +void LLGLDepthTest::checkState() +{ + if (gDebugGL) + { + GLint func = 0; + GLboolean mask = FALSE; + + glGetIntegerv(GL_DEPTH_FUNC, &func); + glGetBooleanv(GL_DEPTH_WRITEMASK, &mask); + + if (glIsEnabled(GL_DEPTH_TEST) != sDepthEnabled || + sWriteEnabled != mask || + sDepthFunc != func) + { + { + LL_GL_ERRS << "Unexpected depth testing state." << LL_ENDL; + } + } + } +} LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P) { for (U32 i = 0; i < 4; i++) diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 27116e088..da4bde75f 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -36,6 +36,7 @@ // This file contains various stuff for handling gl extensions and other gl related stuff. #include +#include #include #include "llerror.h" @@ -233,7 +234,7 @@ public: static void checkClientArrays(const std::string& msg = "", U32 data_mask = 0x0001); protected: - static std::map sStateMap; + static boost::unordered_map sStateMap; public: enum { CURRENT_STATE = -2 }; @@ -361,6 +362,35 @@ protected: virtual void releaseName(GLuint name) = 0; }; +/* + Interface for objects that need periodic GL updates applied to them. + Used to synchronize GL updates with GL thread. +*/ +class LLGLUpdate +{ +public: + + static std::list sGLQ; + + BOOL mInQ; + LLGLUpdate() + : mInQ(FALSE) + { + } + virtual ~LLGLUpdate() + { + if (mInQ) + { + std::list::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this); + if (iter != sGLQ.end()) + { + sGLQ.erase(iter); + } + } + } + virtual void updateGL() = 0; +}; + extern LLMatrix4 gGLObliqueProjectionInverse; #include "llglstates.h" @@ -379,4 +409,6 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor extern BOOL gClothRipple; extern BOOL gNoRender; +extern BOOL gGLActive; + #endif // LL_LLGL_H diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h index 4a51cac43..f3fb499f7 100644 --- a/indra/llrender/llglstates.h +++ b/indra/llrender/llglstates.h @@ -1,285 +1,281 @@ -/** - * @file llglstates.h - * @brief LLGL states definitions - * - * $LicenseInfo:firstyear=2001&license=viewergpl$ - * - * Copyright (c) 2001-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -//THIS HEADER SHOULD ONLY BE INCLUDED FROM llgl.h -#ifndef LL_LLGLSTATES_H -#define LL_LLGLSTATES_H - -#include "llimagegl.h" - -//---------------------------------------------------------------------------- - -class LLGLDepthTest -{ - // Enabled by default -public: - LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled = GL_TRUE, GLenum depth_func = GL_LEQUAL); - - ~LLGLDepthTest(); - - GLboolean mPrevDepthEnabled; - GLenum mPrevDepthFunc; - GLboolean mPrevWriteEnabled; -private: - static GLboolean sDepthEnabled; // defaults to GL_FALSE - static GLenum sDepthFunc; // defaults to GL_LESS - static GLboolean sWriteEnabled; // defaults to GL_TRUE -}; - -//---------------------------------------------------------------------------- - -class LLGLSDefault -{ -protected: - LLGLEnable mColorMaterial; - LLGLDisable mAlphaTest, mBlend, mCullFace, mDither, mFog, - mLineSmooth, mLineStipple, mNormalize, mPolygonSmooth, - mTextureGenQ, mTextureGenR, mTextureGenS, mTextureGenT, - mGLMultisample; -public: - LLGLSDefault() - : - // Enable - mColorMaterial(GL_COLOR_MATERIAL), - // Disable - mAlphaTest(GL_ALPHA_TEST), - mBlend(GL_BLEND), - mCullFace(GL_CULL_FACE), - mDither(GL_DITHER), - mFog(GL_FOG), - mLineSmooth(GL_LINE_SMOOTH), - mLineStipple(GL_LINE_STIPPLE), - mNormalize(GL_NORMALIZE), - mPolygonSmooth(GL_POLYGON_SMOOTH), - mTextureGenQ(GL_TEXTURE_GEN_Q), - mTextureGenR(GL_TEXTURE_GEN_R), - mTextureGenS(GL_TEXTURE_GEN_S), - mTextureGenT(GL_TEXTURE_GEN_T), - mGLMultisample(GL_MULTISAMPLE_ARB) - { } -}; - -class LLGLSObjectSelect -{ -protected: - LLGLDisable mBlend, mFog, mAlphaTest; - LLGLEnable mCullFace; -public: - LLGLSObjectSelect() - : mBlend(GL_BLEND), mFog(GL_FOG), - mAlphaTest(GL_ALPHA_TEST), - mCullFace(GL_CULL_FACE) - { } -}; - -class LLGLSObjectSelectAlpha -{ -protected: - LLGLEnable mAlphaTest; -public: - LLGLSObjectSelectAlpha() - : mAlphaTest(GL_ALPHA_TEST) - {} -}; - -//---------------------------------------------------------------------------- - -class LLGLSUIDefault -{ -protected: - LLGLEnable mBlend, mAlphaTest; - LLGLDisable mCullFace; - LLGLDepthTest mDepthTest; -public: - LLGLSUIDefault() - : mBlend(GL_BLEND), mAlphaTest(GL_ALPHA_TEST), - mCullFace(GL_CULL_FACE), - mDepthTest(GL_FALSE, GL_TRUE, GL_LEQUAL) - {} -}; - -class LLGLSNoAlphaTest // : public LLGLSUIDefault -{ -protected: - LLGLDisable mAlphaTest; -public: - LLGLSNoAlphaTest() - : mAlphaTest(GL_ALPHA_TEST) - {} -}; - -//---------------------------------------------------------------------------- - -class LLGLSFog -{ -protected: - LLGLEnable mFog; -public: - LLGLSFog() - : mFog(GL_FOG) - {} -}; - -class LLGLSNoFog -{ -protected: - LLGLDisable mFog; -public: - LLGLSNoFog() - : mFog(GL_FOG) - {} -}; - -//---------------------------------------------------------------------------- - -class LLGLSPipeline -{ -protected: - LLGLEnable mCullFace; - LLGLDepthTest mDepthTest; -public: - LLGLSPipeline() - : mCullFace(GL_CULL_FACE), - mDepthTest(GL_TRUE, GL_TRUE, GL_LEQUAL) - { } -}; - -class LLGLSPipelineAlpha // : public LLGLSPipeline -{ -protected: - LLGLEnable mBlend, mAlphaTest; -public: - LLGLSPipelineAlpha() - : mBlend(GL_BLEND), - mAlphaTest(GL_ALPHA_TEST) - { } -}; - -class LLGLSPipelineEmbossBump -{ -protected: - LLGLDisable mFog; -public: - LLGLSPipelineEmbossBump() - : mFog(GL_FOG) - { } -}; - -class LLGLSPipelineSelection -{ -protected: - LLGLDisable mCullFace; -public: - LLGLSPipelineSelection() - : mCullFace(GL_CULL_FACE) - {} -}; - -class LLGLSPipelineAvatar -{ -protected: - LLGLEnable mNormalize; -public: - LLGLSPipelineAvatar() - : mNormalize(GL_NORMALIZE) - {} -}; - -class LLGLSPipelineSkyBox -{ -protected: - LLGLDisable mAlphaTest, mCullFace, mFog; -public: - LLGLSPipelineSkyBox() - : mAlphaTest(GL_ALPHA_TEST), mCullFace(GL_CULL_FACE), mFog(GL_FOG) - { } -}; - -class LLGLSTracker -{ -protected: - LLGLEnable mCullFace, mBlend, mAlphaTest; -public: - LLGLSTracker() : - mCullFace(GL_CULL_FACE), - mBlend(GL_BLEND), - mAlphaTest(GL_ALPHA_TEST) - - { } -}; - -//---------------------------------------------------------------------------- - -class LLGLSSpecular -{ -public: - LLGLSSpecular(const LLColor4& color, F32 shininess) - { - if (shininess > 0.0f) - { - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color.mV); - S32 shiny = (S32)(shininess*128.f); - shiny = llclamp(shiny,0,128); - glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, shiny); - } - } - ~LLGLSSpecular() - { - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV); - glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0); - } -}; - -//---------------------------------------------------------------------------- - - -class LLGLSBlendFunc : public LLGLSPipeline { -protected: - GLint mSavedSrc, mSavedDst; - LLGLEnable mBlend; - -public: - LLGLSBlendFunc(GLenum srcFunc, GLenum dstFunc) : - mBlend(GL_BLEND) - { - glGetIntegerv(GL_BLEND_SRC, &mSavedSrc); - glGetIntegerv(GL_BLEND_DST, &mSavedDst); - glBlendFunc(srcFunc, dstFunc); - } - - ~LLGLSBlendFunc(void) { - glBlendFunc(mSavedSrc, mSavedDst); - } -}; - - -#endif +/** + * @file llglstates.h + * @brief LLGL states definitions + * + * $LicenseInfo:firstyear=2001&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$ + */ + +//THIS HEADER SHOULD ONLY BE INCLUDED FROM llgl.h +#ifndef LL_LLGLSTATES_H +#define LL_LLGLSTATES_H + +#include "llimagegl.h" + +//---------------------------------------------------------------------------- + +class LLGLDepthTest +{ + // Enabled by default +public: + LLGLDepthTest(GLboolean depth_enabled, GLboolean write_enabled = GL_TRUE, GLenum depth_func = GL_LEQUAL); + + ~LLGLDepthTest(); + + void checkState(); + + GLboolean mPrevDepthEnabled; + GLenum mPrevDepthFunc; + GLboolean mPrevWriteEnabled; +private: + static GLboolean sDepthEnabled; // defaults to GL_FALSE + static GLenum sDepthFunc; // defaults to GL_LESS + static GLboolean sWriteEnabled; // defaults to GL_TRUE +}; + +//---------------------------------------------------------------------------- + +class LLGLSDefault +{ +protected: + LLGLEnable mColorMaterial; + LLGLDisable mAlphaTest, mBlend, mCullFace, mDither, mFog, + mLineSmooth, mLineStipple, mNormalize, mPolygonSmooth, + mTextureGenQ, mTextureGenR, mTextureGenS, mTextureGenT, + mGLMultisample; +public: + LLGLSDefault() + : + // Enable + mColorMaterial(GL_COLOR_MATERIAL), + // Disable + mAlphaTest(GL_ALPHA_TEST), + mBlend(GL_BLEND), + mCullFace(GL_CULL_FACE), + mDither(GL_DITHER), + mFog(GL_FOG), + mLineSmooth(GL_LINE_SMOOTH), + mLineStipple(GL_LINE_STIPPLE), + mNormalize(GL_NORMALIZE), + mPolygonSmooth(GL_POLYGON_SMOOTH), + mTextureGenQ(GL_TEXTURE_GEN_Q), + mTextureGenR(GL_TEXTURE_GEN_R), + mTextureGenS(GL_TEXTURE_GEN_S), + mTextureGenT(GL_TEXTURE_GEN_T), + mGLMultisample(GL_MULTISAMPLE_ARB) + { } +}; + +class LLGLSObjectSelect +{ +protected: + LLGLDisable mBlend, mFog, mAlphaTest; + LLGLEnable mCullFace; +public: + LLGLSObjectSelect() + : mBlend(GL_BLEND), mFog(GL_FOG), + mAlphaTest(GL_ALPHA_TEST), + mCullFace(GL_CULL_FACE) + { } +}; + +class LLGLSObjectSelectAlpha +{ +protected: + LLGLEnable mAlphaTest; +public: + LLGLSObjectSelectAlpha() + : mAlphaTest(GL_ALPHA_TEST) + {} +}; + +//---------------------------------------------------------------------------- + +class LLGLSUIDefault +{ +protected: + LLGLEnable mBlend, mAlphaTest; + LLGLDisable mCullFace; + LLGLDepthTest mDepthTest; +public: + LLGLSUIDefault() + : mBlend(GL_BLEND), mAlphaTest(GL_ALPHA_TEST), + mCullFace(GL_CULL_FACE), + mDepthTest(GL_FALSE, GL_TRUE, GL_LEQUAL) + {} +}; + +class LLGLSNoAlphaTest // : public LLGLSUIDefault +{ +protected: + LLGLDisable mAlphaTest; +public: + LLGLSNoAlphaTest() + : mAlphaTest(GL_ALPHA_TEST) + {} +}; + +//---------------------------------------------------------------------------- + +class LLGLSFog +{ +protected: + LLGLEnable mFog; +public: + LLGLSFog() + : mFog(GL_FOG) + {} +}; + +class LLGLSNoFog +{ +protected: + LLGLDisable mFog; +public: + LLGLSNoFog() + : mFog(GL_FOG) + {} +}; + +//---------------------------------------------------------------------------- + +class LLGLSPipeline +{ +protected: + LLGLEnable mCullFace; + LLGLDepthTest mDepthTest; +public: + LLGLSPipeline() + : mCullFace(GL_CULL_FACE), + mDepthTest(GL_TRUE, GL_TRUE, GL_LEQUAL) + { } +}; + +class LLGLSPipelineAlpha // : public LLGLSPipeline +{ +protected: + LLGLEnable mBlend, mAlphaTest; +public: + LLGLSPipelineAlpha() + : mBlend(GL_BLEND), + mAlphaTest(GL_ALPHA_TEST) + { } +}; + +class LLGLSPipelineEmbossBump +{ +protected: + LLGLDisable mFog; +public: + LLGLSPipelineEmbossBump() + : mFog(GL_FOG) + { } +}; + +class LLGLSPipelineSelection +{ +protected: + LLGLDisable mCullFace; +public: + LLGLSPipelineSelection() + : mCullFace(GL_CULL_FACE) + {} +}; + +class LLGLSPipelineAvatar +{ +protected: + LLGLEnable mNormalize; +public: + LLGLSPipelineAvatar() + : mNormalize(GL_NORMALIZE) + {} +}; + +class LLGLSPipelineSkyBox +{ +protected: + LLGLDisable mAlphaTest, mCullFace, mFog; +public: + LLGLSPipelineSkyBox() + : mAlphaTest(GL_ALPHA_TEST), mCullFace(GL_CULL_FACE), mFog(GL_FOG) + { } +}; + +class LLGLSTracker +{ +protected: + LLGLEnable mCullFace, mBlend, mAlphaTest; +public: + LLGLSTracker() : + mCullFace(GL_CULL_FACE), + mBlend(GL_BLEND), + mAlphaTest(GL_ALPHA_TEST) + + { } +}; + +//---------------------------------------------------------------------------- + +class LLGLSSpecular +{ +public: + LLGLSSpecular(const LLColor4& color, F32 shininess) + { + if (shininess > 0.0f) + { + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color.mV); + S32 shiny = (S32)(shininess*128.f); + shiny = llclamp(shiny,0,128); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, shiny); + } + } + ~LLGLSSpecular() + { + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, LLColor4(0.f,0.f,0.f,0.f).mV); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0); + } +}; + +//---------------------------------------------------------------------------- + + +class LLGLSBlendFunc : public LLGLSPipeline { +protected: + GLint mSavedSrc, mSavedDst; + LLGLEnable mBlend; + +public: + LLGLSBlendFunc(GLenum srcFunc, GLenum dstFunc) : + mBlend(GL_BLEND) + { + glGetIntegerv(GL_BLEND_SRC, &mSavedSrc); + glGetIntegerv(GL_BLEND_DST, &mSavedDst); + glBlendFunc(srcFunc, dstFunc); + } + + ~LLGLSBlendFunc(void) { + glBlendFunc(mSavedSrc, mSavedDst); + } +}; + + +#endif diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ffa25b425..60c3582d8 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -352,8 +352,21 @@ void LLImageGL::restoreGL() } } +//static +void LLImageGL::dirtyTexOptions() +{ + for (std::set::iterator iter = sImageList.begin(); + iter != sImageList.end(); iter++) + { + LLImageGL* glimage = *iter; + glimage->mTexOptionsDirty = true; + stop_glerror(); + } + +} //---------------------------------------------------------------------------- +//for server side use only. //static BOOL LLImageGL::create(LLPointer& dest, BOOL usemipmaps) { @@ -361,12 +374,14 @@ BOOL LLImageGL::create(LLPointer& dest, BOOL usemipmaps) return TRUE; } +//for server side use only. BOOL LLImageGL::create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps) { dest = new LLImageGL(width, height, components, usemipmaps); return TRUE; } +//for server side use only. BOOL LLImageGL::create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps) { dest = new LLImageGL(imageraw, usemipmaps); diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 478d74cb1..6cb9dd314 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -68,6 +68,7 @@ public: // Save off / restore GL textures static void destroyGL(BOOL save_state = TRUE); static void restoreGL(); + static void dirtyTexOptions(); // Sometimes called externally for textures not using LLImageGL (should go away...) static S32 updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) ; @@ -137,6 +138,7 @@ public: BOOL getBoundRecently() const; BOOL isJustBound() const; LLGLenum getPrimaryFormat() const { return mFormatPrimary; } + LLGLenum getFormatType() const { return mFormatType; } BOOL getHasGLTexture() const { return mTexName != 0; } LLGLuint getTexName() const { return mTexName; } diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 756603a32..8d927ada5 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -56,6 +56,7 @@ U32 LLVertexBuffer::sSetCount = 0; S32 LLVertexBuffer::sCount = 0; S32 LLVertexBuffer::sGLCount = 0; S32 LLVertexBuffer::sMappedCount = 0; +BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ; BOOL LLVertexBuffer::sEnableVBOs = TRUE; U32 LLVertexBuffer::sGLRenderBuffer = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; @@ -287,9 +288,21 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const } //static -void LLVertexBuffer::initClass(bool use_vbo) +void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { - sEnableVBOs = use_vbo; + sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ; + if(sEnableVBOs) + { + //llassert_always(glBindBufferARB) ; //double check the extention for VBO is loaded. + + llinfos << "VBO is enabled." << llendl ; + } + else + { + llinfos << "VBO is disabled." << llendl ; + } + + sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ; LLGLNamePool::registerPool(&sDynamicVBOPool); LLGLNamePool::registerPool(&sDynamicIBOPool); LLGLNamePool::registerPool(&sStreamVBOPool); @@ -346,7 +359,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mGLBuffer(0), mGLIndices(0), mMappedData(NULL), - mMappedIndexData(NULL), mLocked(FALSE), + mMappedIndexData(NULL), + mVertexLocked(FALSE), + mIndexLocked(FALSE), mFinal(FALSE), mFilthy(FALSE), mEmpty(TRUE), @@ -544,6 +559,8 @@ void LLVertexBuffer::destroyGLBuffer() { if (useVBOs()) { + freeClientBuffer() ; + if (mMappedData || mMappedIndexData) { llerrs << "Vertex buffer destroyed while mapped!" << llendl; @@ -571,6 +588,8 @@ void LLVertexBuffer::destroyGLIndices() { if (useVBOs()) { + freeClientBuffer() ; + if (mMappedData || mMappedIndexData) { llerrs << "Vertex buffer destroyed while mapped." << llendl; @@ -768,6 +787,7 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) if (mResized && useVBOs()) { + freeClientBuffer() ; setBuffer(0); } } @@ -782,104 +802,228 @@ BOOL LLVertexBuffer::useVBOs() const } //---------------------------------------------------------------------------- +void LLVertexBuffer::freeClientBuffer() +{ + if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData)) + { + delete[] mMappedData ; + delete[] mMappedIndexData ; + mMappedData = NULL ; + mMappedIndexData = NULL ; + } +} + +void LLVertexBuffer::allocateClientVertexBuffer() +{ + if(!mMappedData) + { + U32 size = getSize() ; + mMappedData = new U8[size]; + memset((void*)mMappedData, 0, size); + } +} + +void LLVertexBuffer::allocateClientIndexBuffer() +{ + if(!mMappedIndexData) + { + U32 size = getIndicesSize(); + mMappedIndexData = new U8[size]; + memset((void*)mMappedIndexData, 0, size); + } +} // Map for data access -volatile U8* LLVertexBuffer::mapBuffer(S32 access) +volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mFinal) { - llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; + llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl; } if (!useVBOs() && !mMappedData && !mMappedIndexData) { - llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; + llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl; } - if (!mLocked && useVBOs()) + if (!mVertexLocked && useVBOs()) { - setBuffer(0); - mLocked = TRUE; - stop_glerror(); - mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - stop_glerror(); - mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - stop_glerror(); + { + setBuffer(0, type); + mVertexLocked = TRUE; + stop_glerror(); + if(sDisableVBOMapping) + { + allocateClientVertexBuffer() ; + } + else + { + mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + stop_glerror(); + } + if (!mMappedData) { - //-------------------- - //print out more debug info before crash - llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; - GLint size ; - glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; - llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; - //-------------------- - - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) + if(!sDisableVBOMapping) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + //-------------------- + //print out more debug info before crash + llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; + GLint size ; + glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; + llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; + //-------------------- + + GLint buff; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLBuffer) + { + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + } + + + llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; } - - - llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; - } - - if (!mMappedIndexData) - { - GLint buff; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLIndices) + else { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; + llerrs << "memory allocation for vertex data failed." << llendl ; } - - llerrs << "glMapBuffer returned NULL (no index data)" << llendl; } - sMappedCount++; } return mMappedData; } -void LLVertexBuffer::unmapBuffer() +volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - if (mMappedData || mMappedIndexData) + if (mFinal) { - if (useVBOs() && mLocked) + llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl; + } + if (!useVBOs() && !mMappedData && !mMappedIndexData) + { + llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl; + } + + if (!mIndexLocked && useVBOs()) + { + { + + setBuffer(0, TYPE_INDEX); + mIndexLocked = TRUE; + stop_glerror(); + + if(sDisableVBOMapping) + { + allocateClientIndexBuffer() ; + } + else + { + mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + } + stop_glerror(); + } + + if (!mMappedIndexData) + { + + if(!sDisableVBOMapping) + { + GLint buff; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLIndices) + { + llerrs << "Invalid GL index buffer bound: " << buff << llendl; + } + + llerrs << "glMapBuffer returned NULL (no index data)" << llendl; + } + else + { + llerrs << "memory allocation for Index data failed. " << llendl ; + } + } + + sMappedCount++; + } + + return mMappedIndexData ; +} + +void LLVertexBuffer::unmapBuffer(S32 type) +{ + LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + if (!useVBOs()) + { + return ; //nothing to unmap + } + + bool updated_all = false ; + if (mMappedData && mVertexLocked && type != TYPE_INDEX) + { + updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating + + if(sDisableVBOMapping) + { + stop_glerror(); + glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), (void*)mMappedData); + stop_glerror(); + } + else { stop_glerror(); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); stop_glerror(); + + mMappedData = NULL; + } + + mVertexLocked = FALSE ; + sMappedCount--; + } + + if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) + { + if(sDisableVBOMapping) + { + stop_glerror(); + glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), (void*)mMappedIndexData); + stop_glerror(); + } + else + { + stop_glerror(); glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); stop_glerror(); - /*if (!sMapped) - { - llerrs << "Redundantly unmapped VBO!" << llendl; - } - sMapped = FALSE;*/ - sMappedCount--; + mMappedIndexData = NULL ; + } - if (mUsage == GL_STATIC_DRAW_ARB) - { //static draw buffers can only be mapped a single time - //throw out client data (we won't be using it again) - mEmpty = TRUE; - mFinal = TRUE; - } - else - { - mEmpty = FALSE; - } + mIndexLocked = FALSE ; + sMappedCount--; + } - mMappedIndexData = NULL; - mMappedData = NULL; - - mLocked = FALSE; + if(updated_all) + { + if(mUsage == GL_STATIC_DRAW_ARB) + { + //static draw buffers can only be mapped a single time + //throw out client data (we won't be using it again) + mEmpty = TRUE; + mFinal = TRUE; + + if(sDisableVBOMapping) + { + freeClientBuffer() ; + } + } + else + { + mEmpty = FALSE; } } } @@ -893,15 +1037,16 @@ template struct VertexBufferStrider strider_t& strider, S32 index) { - if (vbo.mapBuffer() == NULL) - { - llwarns << "mapBuffer failed!" << llendl; - return FALSE; - } - if (type == LLVertexBuffer::TYPE_INDEX) { S32 stride = sizeof(T); + + if (vbo.mapIndexBuffer() == NULL) + { + llwarns << "mapIndexBuffer failed!" << llendl; + return FALSE; + } + strider = (T*)(vbo.getMappedIndices() + index*stride); strider.setStride(0); return TRUE; @@ -909,6 +1054,13 @@ template struct VertexBufferStrider else if (vbo.hasDataType(type)) { S32 stride = vbo.getStride(); + + if (vbo.mapVertexBuffer(type) == NULL) + { + llwarns << "mapVertexBuffer failed!" << llendl; + return FALSE; + } + strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride); strider.setStride(stride); return TRUE; @@ -989,7 +1141,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride) //---------------------------------------------------------------------------- // Set for rendering -void LLVertexBuffer::setBuffer(U32 data_mask) +void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) { LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); //set up pointers if the data mask is different ... @@ -1023,6 +1175,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) sIBOActive = TRUE; } + BOOL error = FALSE; if (gDebugGL) { GLint buff; @@ -1085,7 +1238,11 @@ void LLVertexBuffer::setBuffer(U32 data_mask) } } - unmapBuffer(); + if (error) + { + llerrs << "LLVertexBuffer::mapBuffer failed" << llendl; + } + unmapBuffer(type); } else { diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 4cd8087c3..c7984e615 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -88,7 +88,7 @@ public: static BOOL sUseStreamDraw; static BOOL sOmitBlank; - static void initClass(bool use_vbo); + static void initClass(bool use_vbo, bool no_vbo_mapping); static void cleanupClass(); static void setupClientArrays(U32 data_mask); static void clientCopy(F64 max_time = 0.005); //copy data from client to GL @@ -147,15 +147,20 @@ protected: void updateNumVerts(S32 nverts); void updateNumIndices(S32 nindices); virtual BOOL useVBOs() const; - void unmapBuffer(); + void unmapBuffer(S32 type); + void freeClientBuffer() ; + void allocateClientVertexBuffer() ; + void allocateClientIndexBuffer() ; public: LLVertexBuffer(U32 typemask, S32 usage); // map for data access - volatile U8* mapBuffer(S32 access = -1); + volatile U8* mapVertexBuffer(S32 type = -1, S32 access = -1); + volatile U8* mapIndexBuffer(S32 access = -1); + // set for rendering - virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 + virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0 // allocate buffer void allocateBuffer(S32 nverts, S32 nindices, bool create); virtual void resizeBuffer(S32 newnverts, S32 newnindices); @@ -178,7 +183,7 @@ public: bool getClothWeightStrider(LLStrider& strider, S32 index=0); BOOL isEmpty() const { return mEmpty; } - BOOL isLocked() const { return mLocked; } + BOOL isLocked() const { return mVertexLocked || mIndexLocked; } S32 getNumVerts() const { return mNumVerts; } S32 getNumIndices() const { return mNumIndices; } S32 getRequestedVerts() const { return mRequestedNumVerts; } @@ -217,13 +222,14 @@ protected: U32 mGLIndices; // GL IBO handle volatile U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) volatile U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) - BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory + BOOL mVertexLocked; // if TRUE, vertex buffer is being or has been written to in client memory + BOOL mIndexLocked; // if TRUE, index buffer is being or has been written to in client memory BOOL mFinal; // if TRUE, buffer can not be mapped again BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags) - BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. - S32 mOffsets[TYPE_MAX]; + BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded. BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded) + S32 mOffsets[TYPE_MAX]; class DirtyRegion { @@ -248,13 +254,14 @@ public: static std::vector sDeleteList; typedef std::list buffer_list_t; + static BOOL sDisableVBOMapping; //disable glMapBufferARB static BOOL sEnableVBOs; + static BOOL sVBOActive; + static BOOL sIBOActive; static S32 sTypeOffsets[TYPE_MAX]; static U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLRenderBuffer; - static U32 sGLRenderIndices; - static BOOL sVBOActive; - static BOOL sIBOActive; + static U32 sGLRenderIndices; static U32 sLastMask; static U32 sAllocatedBytes; static U32 sBindCount; diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp index 141b08c39..68fd08921 100644 --- a/indra/llui/llresmgr.cpp +++ b/indra/llui/llresmgr.cpp @@ -460,7 +460,7 @@ LLLocale::LLLocale(const std::string& locale_string) char* new_locale_string = setlocale( LC_ALL, locale_string.c_str()); if ( new_locale_string == NULL) { - llwarns << "Failed to set locale " << locale_string << llendl; + llwarns << "Failed to set locale " << locale_string.c_str() << llendl; setlocale(LC_ALL, SYSTEM_LOCALE.c_str()); } //else diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 07eb39bd6..75dfde1ff 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -225,6 +225,16 @@ bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNo } +bool LLUICtrlFactory::getLayeredXMLNodeFromBuffer(const std::string &buffer, LLXMLNodePtr& root) +{ + if (!LLXMLNode::parseBuffer(buffer.data(), buffer.size(), root, 0)) { + llwarns << "Error reading UI description from buffer." << llendl; + return false; + } + return true; +} + + //----------------------------------------------------------------------------- // buildFloater() //----------------------------------------------------------------------------- @@ -238,6 +248,23 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen return; } + buildFloaterInternal(floaterp, root, filename, factory_map, open); +} + +void LLUICtrlFactory::buildFloaterFromBuffer(LLFloater *floaterp, const std::string &buffer, + const LLCallbackMap::map_t *factory_map, BOOL open) /* Flawfinder: ignore */ +{ + LLXMLNodePtr root; + + if (!LLUICtrlFactory::getLayeredXMLNodeFromBuffer(buffer, root)) + return; + + buildFloaterInternal(floaterp, root, "(buffer)", factory_map, open); +} + +void LLUICtrlFactory::buildFloaterInternal(LLFloater *floaterp, LLXMLNodePtr &root, const std::string &filename, + const LLCallbackMap::map_t *factory_map, BOOL open) /* Flawfinder: ignore */ +{ // root must be called floater if( !(root->hasName("floater") || root->hasName("multi_floater") ) ) { @@ -294,13 +321,31 @@ S32 LLUICtrlFactory::saveToXML(LLView* viewp, const std::string& filename) BOOL LLUICtrlFactory::buildPanel(LLPanel* panelp, const std::string& filename, const LLCallbackMap::map_t* factory_map) { - BOOL didPost = FALSE; LLXMLNodePtr root; if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) { - return didPost; + return FALSE; } + + return buildPanelInternal(panelp, root, filename, factory_map); + } + +BOOL LLUICtrlFactory::buildPanelFromBuffer(LLPanel *panelp, const std::string &buffer, + const LLCallbackMap::map_t* factory_map) +{ + LLXMLNodePtr root; + + if (!LLUICtrlFactory::getLayeredXMLNodeFromBuffer(buffer, root)) + return FALSE; + + return buildPanelInternal(panelp, root, "(buffer)", factory_map); +} + +BOOL LLUICtrlFactory::buildPanelInternal(LLPanel* panelp, LLXMLNodePtr &root, const std::string &filename, + const LLCallbackMap::map_t* factory_map) +{ + BOOL didPost = FALSE; // root must be called panel if( !root->hasName("panel" ) ) diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 5e7c24efc..ef3a97be5 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -53,8 +53,12 @@ public: void buildFloater(LLFloater* floaterp, const std::string &filename, const LLCallbackMap::map_t* factory_map = NULL, BOOL open = TRUE); + void buildFloaterFromBuffer(LLFloater *floaterp, const std::string &buffer, + const LLCallbackMap::map_t *factory_map = NULL, BOOL open = TRUE); BOOL buildPanel(LLPanel* panelp, const std::string &filename, const LLCallbackMap::map_t* factory_map = NULL); + BOOL buildPanelFromBuffer(LLPanel *panelp, const std::string &buffer, + const LLCallbackMap::map_t* factory_map = NULL); void removePanel(LLPanel* panelp) { mBuiltPanels.erase(panelp->getHandle()); } void removeFloater(LLFloater* floaterp) { mBuiltFloaters.erase(floaterp->getHandle()); } @@ -77,6 +81,7 @@ public: virtual LLView* createWidget(LLPanel *parent, LLXMLNodePtr node); static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root); + static bool getLayeredXMLNodeFromBuffer(const std::string &buffer, LLXMLNodePtr& root); static const std::vector& getXUIPaths(); @@ -94,6 +99,11 @@ private: static std::vector sXUIPaths; LLPanel* mDummyPanel; + + void buildFloaterInternal(LLFloater *floaterp, LLXMLNodePtr &root, const std::string &filename, + const LLCallbackMap::map_t *factory_map, BOOL open); + BOOL buildPanelInternal(LLPanel* panelp, LLXMLNodePtr &root, const std::string &filename, + const LLCallbackMap::map_t* factory_map = NULL); }; diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 800b13573..a33da9dea 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -677,7 +677,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML U32 length = ftell(fp); fseek(fp, 0, SEEK_SET); - U8* buffer = new U8[length+1]; + char *buffer = new char[length+1]; size_t nread = fread(buffer, 1, length, fp); buffer[nread] = 0; fclose(fp); @@ -689,7 +689,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML // static bool LLXMLNode::parseBuffer( - U8* buffer, + const char *buffer, U32 length, LLXMLNodePtr& node, LLXMLNode* defaults) @@ -708,7 +708,7 @@ bool LLXMLNode::parseBuffer( XML_SetUserData(my_parser, (void *)file_node_ptr); // Do the parsing - if (XML_Parse(my_parser, (const char *)buffer, length, TRUE) != XML_STATUS_OK) + if (XML_Parse(my_parser, buffer, length, TRUE) != XML_STATUS_OK) { llwarns << "Error parsing xml error code: " << XML_ErrorString(XML_GetErrorCode(my_parser)) diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index d4e127b05..bce2ff733 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -141,7 +141,7 @@ public: LLXMLNodePtr& node, LLXMLNode* defaults_tree); static bool parseBuffer( - U8* buffer, + const char *buffer, U32 length, LLXMLNodePtr& node, LLXMLNode* defaults); diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index bc2690def..463d7fc61 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -50,6 +50,7 @@ LLStdStringTable LLXmlTree::sAttributeKeys(1024); LLXmlTree::LLXmlTree() : mRoot( NULL ), + mParser(0), mNodeNames(512) { } @@ -83,6 +84,39 @@ BOOL LLXmlTree::parseFile(const std::string &path, BOOL keep_contents) return success; } +bool LLXmlTree::parseBufferStart(bool keep_contents) +{ + if (mRoot) delete mRoot; + mRoot = NULL; + + if (mParser) delete mParser; + mParser = new LLXmlTreeParser(this); + mParser->parseBufferStart(keep_contents); + return (mParser != 0); +} + +bool LLXmlTree::parseBuffer(const char *buf, int len) +{ + bool success = mParser->parseBuffer(buf, len); + if (!success) { + S32 line_number = mParser->getCurrentLineNumber(); + const char* error = mParser->getErrorString(); + llwarns << "LLXmlTree parse failed in line " << line_number << ": " << error << llendl; + delete mParser; + mParser = 0; + } + return success; +} + +bool LLXmlTree::parseBufferFinalize() +{ + bool success = mParser->parseBufferFinalize(&mRoot); + delete mParser; + mParser = 0; + return success; +} + + void LLXmlTree::dump() { if( mRoot ) @@ -102,6 +136,25 @@ void LLXmlTree::dumpNode( LLXmlTreeNode* node, const std::string& prefix ) } } +void LLXmlTree::write(std::string &buffer) const +{ + if (mRoot) writeNode(mRoot, buffer, ""); +} + +void LLXmlTree::writeNode(LLXmlTreeNode *node, std::string &buffer, const std::string &indent) const +{ + if (!node->getFirstChild()) { + node->writeNoChild(buffer, indent); + } else { + node->writeStart(buffer, indent); + std::string newIndent = indent + " "; + for (LLXmlTreeNode *child=node->getFirstChild(); child; child=node->getNextChild()) + writeNode(child, buffer, newIndent); + node->writeEnd(buffer, indent); + } +} + + ////////////////////////////////////////////////////////////// // LLXmlTreeNode @@ -139,6 +192,43 @@ void LLXmlTreeNode::dump( const std::string& prefix ) llcont << llendl; } +void LLXmlTreeNode::writeNoChild(std::string &buffer, const std::string &indent) const +{ + if (!mContents.empty()) { + writeStart(buffer, indent); + writeEnd(buffer, indent); + } else { + buffer += indent + '<' + mName; + writeAttributes(buffer); + buffer += "/>\n"; + } +} + +void LLXmlTreeNode::writeStart(std::string &buffer, const std::string &indent) const +{ + buffer += indent + '<' + mName; + writeAttributes(buffer); + buffer += ">\n"; +} + +void LLXmlTreeNode::writeEnd(std::string &buffer, const std::string &indent) const +{ + if (!mContents.empty()) { + buffer += indent + " " + mContents + '\n'; + } + buffer += indent + "\n"; +} + +void LLXmlTreeNode::writeAttributes(std::string &buffer) const +{ + attribute_map_t::const_iterator it, end = mAttributes.end(); + for (it=mAttributes.begin(); it!=end; ++it) { + LLStdStringHandle key = it->first; + const std::string *value = it->second; + buffer += ' ' + *key + "=\"" + *value + '"'; + } +} + BOOL LLXmlTreeNode::hasAttribute(const std::string& name) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); @@ -528,7 +618,7 @@ BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, B BOOL success = LLXmlParser::parseFile(path); - *root = mRoot; + if (root) *root = mRoot; mRoot = NULL; if( success ) @@ -540,6 +630,31 @@ BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, B return success; } +void LLXmlTreeParser::parseBufferStart(BOOL keep_contents) +{ + llassert(!mRoot); + llassert(!mCurrent); + mKeepContents = keep_contents; +} + +bool LLXmlTreeParser::parseBuffer(const char *buf, int len) +{ + return (LLXmlParser::parse(buf, len, false) != 0); +} + +bool LLXmlTreeParser::parseBufferFinalize(LLXmlTreeNode** root) +{ + bool success = (LLXmlParser::parse(0, 0, true) != 0); + + if (root) *root = mRoot; + mRoot = NULL; + + llassert(!success || !mCurrent); + mCurrent = NULL; + + return success; +} + const std::string& LLXmlTreeParser::tabs() { diff --git a/indra/llxml/llxmltree.h b/indra/llxml/llxmltree.h index 1a020f213..2ac75046e 100644 --- a/indra/llxml/llxmltree.h +++ b/indra/llxml/llxmltree.h @@ -63,11 +63,18 @@ public: virtual BOOL parseFile(const std::string &path, BOOL keep_contents = TRUE); + bool parseBufferStart(bool keep_contents = true); + bool parseBuffer(const char *buf, int len); + bool parseBufferFinalize(); + LLXmlTreeNode* getRoot() { return mRoot; } void dump(); void dumpNode( LLXmlTreeNode* node, const std::string& prefix ); + void write(std::string &buffer) const; + void writeNode(LLXmlTreeNode *node, std::string &buffer, const std::string &indent) const; + static LLStdStringHandle addAttributeString( const std::string& name) { return sAttributeKeys.addString( name ); @@ -79,6 +86,7 @@ public: protected: LLXmlTreeNode* mRoot; + LLXmlTreeParser *mParser; // local LLStdStringTable mNodeNames; @@ -175,6 +183,11 @@ private: void dump( const std::string& prefix ); + void writeNoChild(std::string &buffer, const std::string &indent) const; + void writeStart(std::string &buffer, const std::string &indent) const; + void writeEnd(std::string &buffer, const std::string &indent) const; + void writeAttributes(std::string &buffer) const; + protected: typedef std::map attribute_map_t; attribute_map_t mAttributes; @@ -207,6 +220,10 @@ public: BOOL parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents ); + void parseBufferStart(BOOL keep_contents); + bool parseBuffer(const char *buf, int len); + bool parseBufferFinalize(LLXmlTreeNode** root); + protected: const std::string& tabs(); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 329e79d44..bb4bb62d7 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -65,31 +65,32 @@ include_directories( set(viewer_SOURCE_FILES floaterlocalassetbrowse.cpp - aoremotectrl.cpp - floaterao.cpp + aoremotectrl.cpp + floaterao.cpp floatervoicelicense.cpp cofmgr.cpp - ascentdaycyclemanager.cpp - ascentfloatercontactgroups.cpp + ascentdaycyclemanager.cpp + ascentfloatercontactgroups.cpp ascentprefssys.cpp - ascentprefsvan.cpp - ascentuploadbrowser.cpp - dhparam.cpp - dsaparam.cpp - emerald.cpp - emeraldboobutils.cpp + ascentprefsvan.cpp + ascentuploadbrowser.cpp + dhparam.cpp + dsaparam.cpp + emerald.cpp + emeraldboobutils.cpp dofloaterhex.cpp dohexeditor.cpp - floatersculptpreview.cpp - hbfloatergrouptitles.cpp + floatersculptpreview.cpp + hbfloatergrouptitles.cpp hgfloatertexteditor.cpp - hippogridmanager.cpp - hippolimits.cpp - hipporestrequest.cpp - hippopanelgrids.cpp + hippogridmanager.cpp + hippofloaterxml.cpp + hippolimits.cpp + hipporestrequest.cpp + hippopanelgrids.cpp jcfloaterareasearch.cpp - chatbar_as_cmdline.cpp - qtoolalign.cpp + chatbar_as_cmdline.cpp + qtoolalign.cpp llagent.cpp llagentaccess.cpp llagentdata.cpp @@ -160,9 +161,9 @@ set(viewer_SOURCE_FILES llfloateravatarpicker.cpp llfloateravatartextures.cpp llfloaterbeacons.cpp - llfloaterblacklist.cpp - llviewerdisplayname.cpp - llfloaterdisplayname.cpp + llfloaterblacklist.cpp + llviewerdisplayname.cpp + llfloaterdisplayname.cpp llfloaterbuildoptions.cpp llfloaterbulkpermission.cpp llfloaterbump.cpp @@ -184,7 +185,7 @@ set(viewer_SOURCE_FILES llfloaterevent.cpp llfloaterexport.cpp llfloaterexploreanimations.cpp - llfloaterexploresounds.cpp + llfloaterexploresounds.cpp llfloaterfriends.cpp llfloaterfonttest.cpp llfloatergesture.cpp @@ -500,8 +501,8 @@ set(viewer_SOURCE_FILES llxmlrpctransaction.cpp noise.cpp pipeline.cpp - scriptcounter.cpp - wlfPanel_AdvSettings.cpp + scriptcounter.cpp + wlfPanel_AdvSettings.cpp rlvhandler.cpp rlvhelper.cpp rlvcommon.cpp @@ -537,28 +538,29 @@ set(viewer_HEADER_FILES floaterlocalassetbrowse.h aoremotectrl.h - floaterao.h + floaterao.h floatervoicelicense.h - cofmgr.h - ascentdaycyclemanager.h - ascentfloatercontactgroups.h - ascentprefssys.h - ascentprefsvan.h - ascentuploadbrowser.h - emerald.h - emeraldboobutils.h + cofmgr.h + ascentdaycyclemanager.h + ascentfloatercontactgroups.h + ascentprefssys.h + ascentprefsvan.h + ascentuploadbrowser.h + emerald.h + emeraldboobutils.h dofloaterhex.h dohexeditor.h - floatersculptpreview.h - hbfloatergrouptitles.h + floatersculptpreview.h + hbfloatergrouptitles.h hgfloatertexteditor.h - hippogridmanager.h - hippolimits.h - hipporestrequest.h - hippopanelgrids.h + hippogridmanager.h + hippofloaterxml.h + hippolimits.h + hipporestrequest.h + hippopanelgrids.h jcfloaterareasearch.h - chatbar_as_cmdline.h - qtoolalign.h + chatbar_as_cmdline.h + qtoolalign.h llagent.h llagentaccess.h llagentdata.h @@ -654,7 +656,7 @@ set(viewer_HEADER_FILES llfloaterenvsettings.h llfloaterexport.h llfloaterexploreanimations.h - llfloaterexploresounds.h + llfloaterexploresounds.h llfloaterevent.h llfloaterfonttest.h llfloaterfriends.h @@ -977,10 +979,10 @@ set(viewer_HEADER_FILES noise.h pipeline.h randgauss.h - scriptcounter.h + scriptcounter.h VertexCache.h VorbisFramework.h - wlfPanel_AdvSettings.h + wlfPanel_AdvSettings.h rlvdefines.h rlvhandler.h rlvhelper.h @@ -990,7 +992,7 @@ set(viewer_HEADER_FILES rlvextensions.h rlvfloaterbehaviour.h rlvviewer2.h - shcommandhandler.h + shcommandhandler.h ) source_group("CMake Rules" FILES ViewerInstall.cmake) diff --git a/indra/newview/app_settings/client_definitions.xml b/indra/newview/app_settings/client_tags_sg1.xml similarity index 65% rename from indra/newview/app_settings/client_definitions.xml rename to indra/newview/app_settings/client_tags_sg1.xml index d989c59ae..2bca70a9d 100644 --- a/indra/newview/app_settings/client_definitions.xml +++ b/indra/newview/app_settings/client_tags_sg1.xml @@ -1 +1 @@ -841ef25b-3b90-caf9-ea3d-5649e755db65nameCombat Cubedcolor0.494117647058820.59215686274510.682352941176471adcbe893-7643-fd12-f61c-0b39717e2e32nametyk3ncolor0.99215686274510.59215686274510.58431372549021ccb509cf-cc69-e569-38f1-5086c687afd1nameRubycolor0.862745098039220.294117647058820.388235294117651d3eb4a5f-aec5-4bcb-b007-cce9efe89d37namerivlifecolor0.329411764705880.427450980392160.121568627450981c252d89d-6f7c-7d90-f430-d140d2e3fbbenameVLifecolor0.99215686274510.345098039215690.18431372549021eviltrue1c29480c-c608-df87-28bb-964fb64c5366nameGeminicolor0.862745098039220.760784313725490.3882352941176512c9c1e0b-e5d1-263e-16b1-7fc6d169f3d6namePhoxSLcolor0.494117647058820.843137254901960.682352941176471eviltrue0f6723d2-5b23-6b58-08ab-308112b33786nameCryoLifecolor0.329411764705880.109803921568630.788235294117651eviltrue58a8b7ec-1455-7162-5d96-d3c3ead2ed71nameCombat Cubedcolor0.494117647058820.59215686274510.682352941176471f5a48821-9a98-d09e-8d6a-50cc08ba9a47nameNeilLifecolor0.996078431372550.894117647058820.121568627450981eviltrue734fed29-4c51-63e5-1648-6589949d7585nameExplicitcolor0.60.427450980392160.80784313725491ccda2b3b-e72c-a112-e126-fee238b67218nameEmeraldcolor0.329411764705880.894117647058820.1215686274509812a9a406c-f448-68f2-4e38-878f8c46c190nameMeerkatcolor0.99215686274510.79215686274510.533333333333331b6820989-bf42-ff59-ddde-fd3fd3a74fe4nameMeerkatcolor0.99215686274510.79215686274510.5333333333333313ab7e2fa-9572-ef36-1a30-d855dbea4f92nameCombat Cubedcolor0.494117647058820.59215686274510.6823529411764719422e9d7-7b11-83e4-6262-4a8db4716a3bnameBetaLifecolor0.996078431372550.227450980392160.7882352941176514da16427-d81e-e816-f346-aaf4741b8056nameiLifecolor0.996078431372550.894117647058820.788235294117651ffce04ff-5303-4909-a044-d37af7ab0b0enameCorgicolor0.99215686274510.59215686274510.180392156862751eviltruec5b570ca-bb7e-3c81-afd1-f62646b20014nameKung Fucolor0.996078431372550.894117647058820.788235294117651cc7a030f-282f-c165-44d2-b5ee572e72bfnameImprudencecolor0.80784313725490.466666666666670.8196078431372514e8dcf80-336b-b1d8-ef3e-08dacf015a0fnameSapphirecolor0.329411764705880.227450980392160.1215686274509815aa5c70d-d787-571b-0495-4fc1bdef1500nameLGG Proxycolor0.996078431372550.227450980392160.1215686274509810bcd5f5d-a4ce-9ea4-f9e8-15132653b3d8nameMoyMixcolor0.99215686274510.560784313725490.6549019607843118183e823-c443-2142-6eb6-2ab763d4f81cnameDay Oh proxycolor0.494117647058820.345098039215690.6823529411764713da8a69a-58ca-023f-2161-57f2ab3b5702nameOperatorcolor00.7372549019607811eviltrueed63fbd0-589e-fe1d-a3d0-16905efaa96bnamePhoenixcolor0.662745098039220.227450980392160.12549019607843181b3e921-ee31-aa57-ff9b-ec1f28e41da1nameInfinitycolor0.729411764705880.627450980392160.3882352941176515262d71a-88f7-ef40-3b15-00ea148ab4b5nameGemini.Botcolor0.862745098039220.760784313725490.38823529411765177662f23-c77a-9b4d-5558-26b757b2144cnamePSLcolor0.79215686274510.443137254901960.580392156862751e734563e-1c31-2a35-3ed5-8552c807439fnameCombat Cubedcolor0.494117647058820.59215686274510.682352941176471f3fd74a6-fee7-4b2f-93ae-ddcb5991da04namePSLcolor0.79215686274510.443137254901960.580392156862751f5feab57-bde5-2074-97af-517290213eaanameOnyxcolor0.360784313725490.360784313725490.360784313725491eviltruee52d21f7-3c8b-819f-a3db-65c432295dacnameCryoLifecolor0.329411764705880.109803921568630.788235294117651eviltrue7c4d47a3-0c51-04d1-fa47-e4f3ac12f59bnameKung Fucolor0.996078431372550.894117647058820.78823529411765192fc8bff-c604-815a-a716-60be97ed53d1nameBananacolor10.60.101960784313731b32f01bc-f9b3-4535-b1f3-99dc38f022dbnameMeta7color11118873757c-092a-98fb-1afd-ecd347566fcdnameAscentcolor0.3764705882352911128b4da3f-5f9b-f44e-1387-6a115ab482c5nameDiamondcolor0.81568627450980.79215686274510.682352941176471c1936b62-6db5-1bc2-cfb6-54b040db74b4nameShenaniganscolor0.78431372549020.78431372549020.4705882352941217d65a82d-df53-1e5d-65ea-f82c98fa9d16nameBSDcolor0.631372549019610.125490196078430.937254901960781287aaa37-2f88-275a-edf4-7ea6bb82fb8dnamelolcatcolor0.698039215686270.133333333333330.133333333333331806a8249-e235-f051-ac4c-0a58b570f1c1nameLunacolor0.439215686274510.7215686274509811d64bf2e9-651f-0b6e-9e8f-4311d42287e3namePie_Viewercolor0.498039215686270.247058823529411129705410-bcdf-bfd5-e811-5fca794dfbc1nameHippoMeowcolor0.20.9568627450980411e8dd2ab3-e074-710c-bac9-e80790990bffnameCombat Cubedcolor0.494117647058820.59215686274510.682352941176471b8c99aa0-6e82-0a84-3fc9-f73dc89471c2nameProlapsedPussyLifecolor0.6666666666666700.61ffb65745-2120-e248-33e0-13dd9166b3banameTWHcolor10.129411764705880.129411764705881eviltrueb33b69ae-6b6c-b395-0175-ce76a871173bnameNicholascolor0.40.2666666666666711af8c86bd-c377-c331-7476-58abeb7af8fcnameThe Sorcerercolor0.541176470588240.168627450980390.886274509803921049af712-22c9-b2c4-50c7-90a9f1d1e5efnameGNRcolor0.901960784313730.901960784313730.9019607843137319ee02f6b-c244-75d4-1737-da8afb9d8d52nameHackedcolor0.933333333333330.9333333333333311ed943d3f-7a29-8339-11b9-cd0c06a1241bname/yiff/color0.478431372549020.478431372549020.4784313725490214ca51a79-41c0-91ec-7c58-a5195951bda2nameHorny Thelcolor10.27058823529412018cc85294-c3d9-8f9f-e507-c324ef49786enameIncognitoLifecolor000191144252-196e-bac9-3737-92752eee612dnameCaninecolor0.870588235294120.85882352941176119995490f-b248-46f2-91ed-910289676f99name$color0.254901960784310.254901960784310.254901960784311745ac6b7-5b03-450d-6b01-577da127d7d2nameZidonukecolor000.588235294117651d2fd7988-786f-40bc-54cb-c2ad557a639dnameFirestormcolor0.94117647058824001bb7fba3a-e7e0-14d6-b1ae-ce43f67745abnameApple Lifecolor010.0039215686274511c3e958f3-cfb5-9e8b-edb7-d12d5c0623d5nameWinkycolor0.262745098039220.431372549019610.93333333333333154d93609-1392-2a93-255c-a9dd429ecca5nameEmergencecolor0.815686274509800157f9da7c-0323-c412-58be-80b0441b887enameNeon Glowcolor0.282352941176470.254901960784310.909803921568631481a055f-36b5-af82-ac49-24709f013e50nameNanocolor0.705882352941180.8470588235294101f25263b7-6167-4f34-a4ef-af65213b2e39nameSingularitycolor0.705882352941180.78431372549020.78431372549021734bae36-a197-b087-ee2d-a098d58fed55nameMoreland Grovecolor10.498039215686270.4980392156862716c622b79-b49d-b5da-e4d1-2f45ecec6106nameVolt Viewercolor1101f8551a21-c960-5132-366a-f55ea63d97c3nameHackercolor0.643137254901960.643137254901960.6431372549019614e6c4027-9bbd-2dc5-2c00-c55a08fd49d1nameDOWN SYNDROMEcolor0.0823529411764710.0745098039215690.07450980392156912b459a3b-5420-21a1-7dda-eccf02de6c37nameSuncolor0.254901960784310.368627450980390.525490196078431af22a7af-a3f9-b4e4-79de-3d9f4653f9e3nameFoxy!color0.745098039215690.235294117647060.1960784313725514b84e182-f0cc-d8da-94c8-25b59c4e4b99nameDeus Ex Machinacolor0.980392156862750.549019607843140101f13da6-fd61-82be-5a8b-68f2d165d8cdnameSmilodoncolor10.50196078431373014b6f6b75-bf77-d1ff-0000-000000000000nameKokuacolor0.749019607843140.466666666666670.807843137254919a4d13d4-b36b-ff89-715b-9b53091c1473nameSuperLifecolor0.882352941176470.8823529411764701bdef8fc2-df54-fa80-757a-f7f346bbcf77nameKoreDEVcolor0.545098039215690.270588235294120.0745098039215691d0770263-aec5-6a26-f987-37c14e8f6523nameHXO-Lifecolor000.8823529411764711a1d86b2-edda-aa01-6e23-5b0cc7c2fe35nameS3aiancolor0.0470588235294120.0039215686274510.8823529411764713386a955-641c-1113-18e7-d4a5165a62bdnameStreetLifecolor0.545098039215690.545098039215690.51372549019608114ae222f-cf97-fcff-6b90-21593d824dbdnameFuckLifecolor0.039215686274510.0156862745098040.078431372549021b2848bed-38b3-3d6b-6ebe-7b4cb7d4994anameKoreDEV-Ghostcolor0.039215686274510.196078431372550.078431372549021ae4e92fb-023d-23ba-d060-3403f953ab1anamePhoenixcolor0.996078431372550.560784313725490.6549019607843115d9581af-d615-bc16-2667-2f04f8eeefe4namePhoenixcolor0.329411764705880.894117647058820.1215686274509815f0e7c32-38c3-9214-01f0-fb16a5b40128namePhoenixcolor110.18431372549021e35f7d40-6071-4b29-9727-5647bdafb5d5namePhoenixcolor1111e71b780e-1a57-400d-4649-959f69ec7d51namePhoenixcolor0.996078431372550.227450980392160.1215686274509815bb6e4a6-8e24-7c92-be2e-91419bb0ebcbnamePhoenixcolor0.349019607843140.3490196078431411e4117c3f-cc02-d537-665d-c31b8c11bb18nameEmeraldcolor10118cf0577c-22d3-6a73-523c-15c0a90d6c27namePhoenixcolor0.729411764705880.360784313725490.654901960784311ddf41cfa-f5c5-0dee-3ed9-f3fb0adb1eadnamePhoenixcolor1011dd0ccfa2-8124-b165-176d-f3dc08f4189enamePhoenixcolor0.50196078431373011c1c189f5-6dab-fc03-ea5a-f9f68f90b018namePhoenixcolor0.996078431372550.396078431372550.121568627450981bf33bd15-7020-cce1-3725-48923440b7eenameEmeraldcolor0.980392156862750.690196078431370.3411764705882411e0948ab-706a-b309-434c-a694436a79benameEmeraldcolor1111072343d0-1ce9-0952-4106-5312af4a789anameEmeraldcolor0.996078431372550.560784313725490.6549019607843111da8eb54-a70f-bd4a-77e5-c7b815c3b2a2nameEmeraldcolor0.996078431372550.227450980392160.1215686274509814eb67510-0924-ebb1-50ca-8af5694cd267nameEmeraldcolor0.349019607843140.3490196078431411e741e2bf-cf8c-191c-97f2-b2709a843dfcnameEmeraldcolor0.996078431372550.396078431372550.1215686274509818078ffb3-840c-d037-caf3-5cd02c2e7040nameEmeraldcolor110.18431372549021602243f4-8fb1-ac00-d5bc-7ab50c4433b7nameEmeraldcolor0.501960784313730110ae2f973-98c1-a4e8-9f4b-9db2044ab079nameEmeraldcolor0.729411764705880.360784313725490.654901960784311isCompletetrue \ No newline at end of file +841ef25b-3b90-caf9-ea3d-5649e755db65nameCombat Cubedcolor0.494117647058820.59215686274510.682352941176471adcbe893-7643-fd12-f61c-0b39717e2e32nametyk3ncolor0.99215686274510.59215686274510.58431372549021ccb509cf-cc69-e569-38f1-5086c687afd1nameRubycolor0.862745098039220.294117647058820.388235294117651d3eb4a5f-aec5-4bcb-b007-cce9efe89d37namerivlifecolor0.329411764705880.427450980392160.121568627450981c252d89d-6f7c-7d90-f430-d140d2e3fbbenameVLifecolor0.99215686274510.345098039215690.18431372549021eviltrue1c29480c-c608-df87-28bb-964fb64c5366nameGeminicolor0.862745098039220.760784313725490.3882352941176512c9c1e0b-e5d1-263e-16b1-7fc6d169f3d6namePhoxSLcolor0.494117647058820.843137254901960.682352941176471eviltrue0f6723d2-5b23-6b58-08ab-308112b33786nameCryoLifecolor0.329411764705880.109803921568630.788235294117651eviltrue58a8b7ec-1455-7162-5d96-d3c3ead2ed71nameCombat Cubedcolor0.494117647058820.59215686274510.682352941176471f5a48821-9a98-d09e-8d6a-50cc08ba9a47nameNeilLifecolor0.996078431372550.894117647058820.121568627450981eviltrue734fed29-4c51-63e5-1648-6589949d7585nameExplicitcolor0.60.427450980392160.80784313725491ccda2b3b-e72c-a112-e126-fee238b67218nameEmeraldcolor0.329411764705880.894117647058820.1215686274509812a9a406c-f448-68f2-4e38-878f8c46c190nameMeerkatcolor0.99215686274510.79215686274510.533333333333331b6820989-bf42-ff59-ddde-fd3fd3a74fe4nameMeerkatcolor0.99215686274510.79215686274510.5333333333333313ab7e2fa-9572-ef36-1a30-d855dbea4f92nameCombat Cubedcolor0.494117647058820.59215686274510.6823529411764719422e9d7-7b11-83e4-6262-4a8db4716a3bnameBetaLifecolor0.996078431372550.227450980392160.7882352941176514da16427-d81e-e816-f346-aaf4741b8056nameiLifecolor0.996078431372550.894117647058820.788235294117651ffce04ff-5303-4909-a044-d37af7ab0b0enameCorgicolor0.99215686274510.59215686274510.180392156862751eviltruec5b570ca-bb7e-3c81-afd1-f62646b20014nameKung Fucolor0.996078431372550.894117647058820.788235294117651cc7a030f-282f-c165-44d2-b5ee572e72bfnameImprudencecolor0.80784313725490.466666666666670.8196078431372514e8dcf80-336b-b1d8-ef3e-08dacf015a0fnameSapphirecolor0.329411764705880.227450980392160.1215686274509815aa5c70d-d787-571b-0495-4fc1bdef1500nameLGG Proxycolor0.996078431372550.227450980392160.1215686274509810bcd5f5d-a4ce-9ea4-f9e8-15132653b3d8nameMoyMixcolor0.99215686274510.560784313725490.6549019607843118183e823-c443-2142-6eb6-2ab763d4f81cnameDay Oh proxycolor0.494117647058820.345098039215690.6823529411764713da8a69a-58ca-023f-2161-57f2ab3b5702nameOperatorcolor00.7372549019607811eviltrueed63fbd0-589e-fe1d-a3d0-16905efaa96bnamePhoenixcolor0.662745098039220.227450980392160.12549019607843181b3e921-ee31-aa57-ff9b-ec1f28e41da1nameInfinitycolor0.729411764705880.627450980392160.3882352941176515262d71a-88f7-ef40-3b15-00ea148ab4b5nameGemini.Botcolor0.862745098039220.760784313725490.38823529411765177662f23-c77a-9b4d-5558-26b757b2144cnamePSLcolor0.79215686274510.443137254901960.580392156862751e734563e-1c31-2a35-3ed5-8552c807439fnameCombat Cubedcolor0.494117647058820.59215686274510.682352941176471f3fd74a6-fee7-4b2f-93ae-ddcb5991da04namePSLcolor0.79215686274510.443137254901960.580392156862751f5feab57-bde5-2074-97af-517290213eaanameOnyxcolor0.360784313725490.360784313725490.360784313725491eviltruee52d21f7-3c8b-819f-a3db-65c432295dacnameCryoLifecolor0.329411764705880.109803921568630.788235294117651eviltrue7c4d47a3-0c51-04d1-fa47-e4f3ac12f59bnameKung Fucolor0.996078431372550.894117647058820.78823529411765192fc8bff-c604-815a-a716-60be97ed53d1nameBananacolor10.60.101960784313731b32f01bc-f9b3-4535-b1f3-99dc38f022dbnameMeta7color11118873757c-092a-98fb-1afd-ecd347566fcdnameAscentcolor0.3764705882352911128b4da3f-5f9b-f44e-1387-6a115ab482c5nameDiamondcolor0.81568627450980.79215686274510.682352941176471c1936b62-6db5-1bc2-cfb6-54b040db74b4nameShenaniganscolor0.78431372549020.78431372549020.4705882352941217d65a82d-df53-1e5d-65ea-f82c98fa9d16nameBSDcolor0.631372549019610.125490196078430.937254901960781287aaa37-2f88-275a-edf4-7ea6bb82fb8dnamelolcatcolor0.698039215686270.133333333333330.133333333333331806a8249-e235-f051-ac4c-0a58b570f1c1nameLunacolor0.439215686274510.7215686274509811d64bf2e9-651f-0b6e-9e8f-4311d42287e3namePie_Viewercolor0.498039215686270.247058823529411129705410-bcdf-bfd5-e811-5fca794dfbc1nameHippoMeowcolor0.20.9568627450980411e8dd2ab3-e074-710c-bac9-e80790990bffnameCombat Cubedcolor0.494117647058820.59215686274510.682352941176471b8c99aa0-6e82-0a84-3fc9-f73dc89471c2nameProlapsedPussyLifecolor0.6666666666666700.61ffb65745-2120-e248-33e0-13dd9166b3banameTWHcolor10.129411764705880.129411764705881eviltrueb33b69ae-6b6c-b395-0175-ce76a871173bnameNicholascolor0.40.2666666666666711af8c86bd-c377-c331-7476-58abeb7af8fcnameThe Sorcerercolor0.541176470588240.168627450980390.886274509803921049af712-22c9-b2c4-50c7-90a9f1d1e5efnameGNRcolor0.901960784313730.901960784313730.9019607843137319ee02f6b-c244-75d4-1737-da8afb9d8d52nameHackedcolor0.933333333333330.9333333333333311ed943d3f-7a29-8339-11b9-cd0c06a1241bname/yiff/color0.478431372549020.478431372549020.4784313725490214ca51a79-41c0-91ec-7c58-a5195951bda2nameHorny Thelcolor10.27058823529412018cc85294-c3d9-8f9f-e507-c324ef49786enameIncognitoLifecolor000191144252-196e-bac9-3737-92752eee612dnameCaninecolor0.870588235294120.85882352941176119995490f-b248-46f2-91ed-910289676f99name$color0.254901960784310.254901960784310.254901960784311745ac6b7-5b03-450d-6b01-577da127d7d2nameZidonukecolor000.588235294117651d2fd7988-786f-40bc-54cb-c2ad557a639dnameFirestormcolor0.94117647058824001bb7fba3a-e7e0-14d6-b1ae-ce43f67745abnameApple Lifecolor010.0039215686274511c3e958f3-cfb5-9e8b-edb7-d12d5c0623d5nameWinkycolor0.262745098039220.431372549019610.93333333333333154d93609-1392-2a93-255c-a9dd429ecca5nameEmergencecolor0.815686274509800157f9da7c-0323-c412-58be-80b0441b887enameNeon Glowcolor0.282352941176470.254901960784310.909803921568631481a055f-36b5-af82-ac49-24709f013e50nameNanocolor0.705882352941180.8470588235294101f25263b7-6167-4f34-a4ef-af65213b2e39nameSingularitycolor0.705882352941180.78431372549020.78431372549021734bae36-a197-b087-ee2d-a098d58fed55nameMoreland Grovecolor10.498039215686270.4980392156862716c622b79-b49d-b5da-e4d1-2f45ecec6106nameVolt Viewercolor1101f8551a21-c960-5132-366a-f55ea63d97c3nameHackercolor0.643137254901960.643137254901960.6431372549019614e6c4027-9bbd-2dc5-2c00-c55a08fd49d1nameDOWN SYNDROMEcolor0.0823529411764710.0745098039215690.07450980392156912b459a3b-5420-21a1-7dda-eccf02de6c37nameSuncolor0.254901960784310.368627450980390.525490196078431af22a7af-a3f9-b4e4-79de-3d9f4653f9e3nameFoxy!color0.745098039215690.235294117647060.1960784313725514b84e182-f0cc-d8da-94c8-25b59c4e4b99nameDeus Ex Machinacolor0.980392156862750.549019607843140101f13da6-fd61-82be-5a8b-68f2d165d8cdnameSmilodoncolor10.50196078431373014b6f6b75-bf77-d1ff-0000-000000000000nameKokuacolor0.749019607843140.466666666666670.807843137254919a4d13d4-b36b-ff89-715b-9b53091c1473nameSuperLifecolor0.882352941176470.8823529411764701bdef8fc2-df54-fa80-757a-f7f346bbcf77nameKoreDEVcolor0.545098039215690.270588235294120.0745098039215691d0770263-aec5-6a26-f987-37c14e8f6523nameHXO-Lifecolor000.882352941176471eviltrue1a1d86b2-edda-aa01-6e23-5b0cc7c2fe35nameS3aiancolor0.0470588235294120.0039215686274510.8823529411764713386a955-641c-1113-18e7-d4a5165a62bdnameStreetLifecolor0.545098039215690.545098039215690.51372549019608114ae222f-cf97-fcff-6b90-21593d824dbdnameFuckLifecolor0.039215686274510.0156862745098040.078431372549021b2848bed-38b3-3d6b-6ebe-7b4cb7d4994anameKoreDEV-Ghostcolor0.039215686274510.196078431372550.078431372549021c58fca06-33b3-827d-d81c-a886a631affcnameWhalecolor10.6117647058823501a1057672-e67b-7b40-118c-4e6898457dcbnameTeeLifecolor0.3529411764705900.0039215686274511f709044d-3f7e-3d94-6c40-17e9d456d35anameGod Proxycolor00.86666666666667010b6bc011-15c7-721d-f4c9-cdbaf3448dbanameMoonBotcolor0.588235294117650.156862745098040.901960784313731f40db76a-f6fc-449f-a6e8-47e1484fa294nameJoinOurHomoMafiacolor10.313725490196080.6588235294117612d02f0a7-48a0-46b3-944f-6a0a7523aaf6nameHomoLifecolor0.858823529411760.0352941176470590.4313725490196113f23c201-e73a-4b86-b294-5fef9919dc23nameShottacolor00.5019607843137311c1d1a634-7d1f-70ac-513e-471c3a81d01bnamec1Tanzanitecolor0.545098039215690.0352941176470590.964705882352941397554b9-3e2f-4255-5fde-76f93e71295bnameGenesiscolor0.749019607843140.749019607843140.749019607843141e5a99018-4886-d48d-4793-54514f3c5a7bnameMarzWorldcolor0.827450980392160.827450980392160.827450980392161869e0c1a-a2d9-4b92-bd70-5044d6bd2284nameBluebirdcolor0.0196078431372550.588235294117650.984313725490218cdf6c66-2f8f-1aa9-f8ee-0493acf90328nameNexuscolor0.40784313725490.133333333333330.5450980392156911fb9ce5c-bb36-a0c1-72b5-e4f3406c6d56nameLucidcolor0.678431372549020.988235294117650.9725490196078416043a54c-b320-523a-ed15-a8fdd2ebc923nameBlunixcolor0.047058823529412011611300d4-9188-102f-9530-68c7f52dc17anameC1501color0.980392156862750.380392156862750.576470588235291e46e7c2b-1de3-5347-db43-42ee4e1f5bf2nameVoscolor0.705882352941180.705882352941180.705882352941181697e702f-29e2-2a31-8dcd-b53f5c25a27cnameMilkshakecolor0.745098039215690.631372549019610.525490196078431ae4e92fb-023d-23ba-d060-3403f953ab1anamePhoenixcolor0.996078431372550.560784313725490.6549019607843115d9581af-d615-bc16-2667-2f04f8eeefe4namePhoenixcolor0.329411764705880.894117647058820.1215686274509815f0e7c32-38c3-9214-01f0-fb16a5b40128namePhoenixcolor110.18431372549021e35f7d40-6071-4b29-9727-5647bdafb5d5namePhoenixcolor1111e71b780e-1a57-400d-4649-959f69ec7d51namePhoenixcolor0.996078431372550.227450980392160.1215686274509815bb6e4a6-8e24-7c92-be2e-91419bb0ebcbnamePhoenixcolor0.349019607843140.3490196078431411e4117c3f-cc02-d537-665d-c31b8c11bb18nameEmeraldcolor10118cf0577c-22d3-6a73-523c-15c0a90d6c27namePhoenixcolor0.729411764705880.360784313725490.654901960784311ddf41cfa-f5c5-0dee-3ed9-f3fb0adb1eadnamePhoenixcolor1011dd0ccfa2-8124-b165-176d-f3dc08f4189enamePhoenixcolor0.50196078431373011c1c189f5-6dab-fc03-ea5a-f9f68f90b018namePhoenixcolor0.996078431372550.396078431372550.121568627450981bf33bd15-7020-cce1-3725-48923440b7eenameEmeraldcolor0.980392156862750.690196078431370.3411764705882411e0948ab-706a-b309-434c-a694436a79benameEmeraldcolor1111072343d0-1ce9-0952-4106-5312af4a789anameEmeraldcolor0.996078431372550.560784313725490.6549019607843111da8eb54-a70f-bd4a-77e5-c7b815c3b2a2nameEmeraldcolor0.996078431372550.227450980392160.1215686274509814eb67510-0924-ebb1-50ca-8af5694cd267nameEmeraldcolor0.349019607843140.3490196078431411e741e2bf-cf8c-191c-97f2-b2709a843dfcnameEmeraldcolor0.996078431372550.396078431372550.1215686274509818078ffb3-840c-d037-caf3-5cd02c2e7040nameEmeraldcolor110.18431372549021602243f4-8fb1-ac00-d5bc-7ab50c4433b7nameEmeraldcolor0.501960784313730110ae2f973-98c1-a4e8-9f4b-9db2044ab079nameEmeraldcolor0.729411764705880.360784313725490.654901960784311isCompletetrue \ No newline at end of file diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ca1deb3e7..2057d827c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9832,6 +9832,17 @@ Value 1 + RenderVBOMappingDisable + + Comment + Disable VBO glMapBufferARB + Persist + 1 + Type + Boolean + Value + 1 + RenderVolumeLODFactor Comment @@ -12789,6 +12800,17 @@ Value 1 + SkipReflectOcclusionUpdates + + Comment + Enable optimization that prevents occlusion updates for refelction pass + Persist + 1 + Type + Boolean + Value + 1 + UseOutfitFolders Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index a91e9fa15..7c8d238d2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -71,14 +71,14 @@ void main() color.rgb = scaleSoftClip(color.rgb); - if (samp_pos.z != 0.0) + /*if (samp_pos.z != 0.0) { float dist_factor = alpha_soften; float a = gl_Color.a; a *= a; dist_factor *= 1.0/(1.0-a); color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); - } + }*/ //gl_FragColor = gl_Color; gl_FragColor = color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index b496bd674..9f130ee42 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -37,8 +37,8 @@ void main() calcAtmospherics(pos.xyz); //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); - vec4 col; - col.a = gl_Color.a; + + vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a); // Add windlight lights col.rgb = atmosAmbient(vec3(0.)); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 58aa5a9cb..b5daef03e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -12,7 +12,14 @@ varying vec4 vary_position; void main() { - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 diff = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy); + + if (diff.a < 0.2) + { + discard; + } + + gl_FragData[0] = vec4(diff.rgb, 0.0); gl_FragData[1] = vec4(0,0,0,0); gl_FragData[2] = vec4(normalize(vary_normal), 0.0); gl_FragData[3] = vary_position; diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index 20a3f3df5..4e3e635f1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -13,7 +13,8 @@ varying vec4 vary_position; void main() { - gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005); gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy); gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, vary_position.z); gl_FragData[3] = vary_position; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 3689d1284..c8248b294 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -77,6 +77,12 @@ void main() //attenuate point light contribution by SSAO component out_col *= texture2DRect(lightMap, frag.xy).g; + + + if (dot(out_col, out_col) <= 0.0) + { + discard; + } gl_FragColor.rgb = out_col; gl_FragColor.a = 0.0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 52bad1f34..68f376d69 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -69,6 +69,11 @@ void main() //attenuate point light contribution by SSAO component col *= texture2DRect(lightMap, frag.xy).g; + if (dot(col, col) <= 0.0) + { + discard; + } + gl_FragColor.rgb = col; gl_FragColor.a = 0.0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index bc2c9816d..ea70eabf5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -13,7 +13,7 @@ varying vec4 vary_position; void main() { vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); - gl_FragData[0] = gl_Color*col; + gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005); gl_FragData[1] = vec4(0,0,0,0); gl_FragData[2] = vec4(normalize(vary_normal), 0.0); gl_FragData[3] = vary_position; diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 0a1f019e3..83959101e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -5,6 +5,7 @@ * $License$ */ +#extension GL_ARB_texture_rectangle : enable vec3 scaleSoftClip(vec3 inColor); vec3 atmosTransport(vec3 inColor); @@ -32,6 +33,7 @@ uniform vec3 normScale; uniform float fresnelScale; uniform float fresnelOffset; uniform float blurMultiplier; +uniform mat4 norm_mat; //region space to screen space //bigWave is (refCoord.w, view.w); @@ -88,7 +90,7 @@ void main() refcol *= df1 * 0.333; vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; - wavef.z *= max(-viewVec.z, 0.1); +// wavef.z *= max(-viewVec.z, 0.1); wavef = normalize(wavef); float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; @@ -101,10 +103,10 @@ void main() refcol = mix(baseCol*df2, refcol, dweight); //get specular component - float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); +// float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); //harden specular - spec = pow(spec, 128.0); +// spec = pow(spec, 128.0); //figure out distortion vector (ripply) vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); @@ -118,13 +120,13 @@ void main() float shadow = 1.0; vec4 pos = vary_position; - vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + //vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; - if (pos.z > -shadow_clip.w) - { +// if (pos.z > -shadow_clip.w) +// { vec4 spos = pos; - if (pos.z < -shadow_clip.z) +/* if (pos.z < -shadow_clip.z) { vec4 lpos = (shadow_matrix[3]*spos); shadow = shadow2DProj(shadowMap3, lpos).x; @@ -144,14 +146,19 @@ void main() vec4 lpos = (shadow_matrix[0]*spos); shadow = shadow2DProj(shadowMap0, lpos).x; } - } + }*/ - spec *= shadow; - color.rgb += spec * specular; +// spec *= shadow; +// color.rgb += spec * specular; - color.rgb = atmosTransport(color.rgb); - color.rgb = scaleSoftClip(color.rgb); - color.a = spec * sunAngle2; +// color.rgb = atmosTransport(color.rgb); +// color.rgb = scaleSoftClip(color.rgb); +// color.a = spec * sunAngle2; - gl_FragColor = color; +// gl_FragColor = color; + vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz; + + gl_FragData[0] = vec4(color.rgb, 0.5); // diffuse + gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec + gl_FragData[2] = vec4(screenspacewavef, 0.0); // normalxyz, displace } diff --git a/indra/newview/hippofloaterxml.cpp b/indra/newview/hippofloaterxml.cpp new file mode 100755 index 000000000..477f0d7bb --- /dev/null +++ b/indra/newview/hippofloaterxml.cpp @@ -0,0 +1,381 @@ +/** + * @file hippofloaterxml.cpp + * @author Mana Janus + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" + +#include "hippofloaterxml.h" + +#include +#include +#include +#include +#include + +#include "llviewerwindow.h" + + +#define CHANNEL 427169570 + + +// ******************************************************************** +// floater implementation class + +class HippoFloaterXmlImpl : public LLFloater +{ + public: + HippoFloaterXmlImpl(const std::string &name, const std::string &xml); + virtual ~HippoFloaterXmlImpl(); + + BOOL postBuild(); + void onClose(bool quitting); + + static bool execute(LLUICtrl *ctrl, + const std::string &cmds, std::string::size_type &offset, + std::string &response); + + private: + std::string mName; + bool mIsNotifyOnClose; +}; + + +// ******************************************************************** +// global floater data + +typedef std::map FloaterMap; +static FloaterMap gInstances; + + +// ******************************************************************** +// floater XML descriptions + +class XmlData +{ + public: + explicit XmlData(int numParts) : + mData(numParts), mNumParts(numParts), mPartsReceived(0) + { + } + + int getNumParts() const { return mNumParts; } + bool isComplete() const { return (mPartsReceived >= mNumParts); } + + void add(int index, const std::string &data) + { + --index; // 1 <= index <= mNumParts + if ((index >= 0) && (index < mNumParts)) { + if (mData[index].empty()) mPartsReceived++; + mData[index] = data; + } + } + + void get(std::string &xml) const + { + xml = ""; + for (int i=0; i mData; + int mNumParts; + int mPartsReceived; +}; + +typedef std::map XmlDataMap; +static XmlDataMap gXmlData; + +XmlData *XmlData::getInstance(const std::string &floaterName, int numParts) +{ + XmlDataMap::iterator it = gXmlData.find(floaterName); + if (it == gXmlData.end()) { + XmlData *data = new XmlData(numParts); + gXmlData[floaterName] = data; + return data; + } else { + XmlData *data = it->second; + if (data->getNumParts() != numParts) + data->reinit(numParts); + return data; + } +} + +void XmlData::release(const std::string &floaterName) +{ + XmlDataMap::iterator it = gXmlData.find(floaterName); + if (it != gXmlData.end()) { + delete gXmlData[floaterName]; + gXmlData.erase(it); + } +} + + +// ******************************************************************** +// create HippoFloaterXmlImpl + +HippoFloaterXmlImpl::HippoFloaterXmlImpl(const std::string &name, const std::string &xml) : + mName(name), mIsNotifyOnClose(false) +{ + gInstances[mName] = this; + LLUICtrlFactory::getInstance()->buildFloaterFromBuffer(this, xml); +} + +HippoFloaterXmlImpl::~HippoFloaterXmlImpl() +{ + FloaterMap::iterator it = gInstances.find(mName); + if (it != gInstances.end()) + gInstances.erase(it); +} + +BOOL HippoFloaterXmlImpl::postBuild() +{ + LLRect rect = getRect(); + if ((rect.mLeft == 0) && (rect.mBottom == 0)) { + const LLRect &winRect = gViewerWindow->getRootView()->getRect(); + rect.setCenterAndSize((winRect.getWidth()+1)>>1, (winRect.getHeight()+1)>>1, + rect.getWidth(), rect.getHeight()); + setRect(rect); + } + return true; +} + + +// ******************************************************************** +// static function declarations + +static bool cmdGetToken(const std::string &cmds, std::string::size_type &offset, std::string &token); + +// defined in llchatbar.cpp, but not declared in any header +void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel); + + +// ******************************************************************** +// execute commands static + +void HippoFloaterXml::execute(const std::string &cmds) +{ + std::string::size_type offset = 0; + + std::string floaterName; + if (!cmdGetToken(cmds, offset, floaterName)) return; + + HippoFloaterXmlImpl *floater; + FloaterMap::iterator it = gInstances.find(floaterName); + if (it != gInstances.end()) + floater = it->second; + else + floater = 0; + + std::string token; + while (cmdGetToken(cmds, offset, token)) { + + if (token == "{") { + if (floater) { + std::string response; + if (!floater->execute(floater, cmds, offset, response)) + break; + if (!response.empty()) + send_chat_from_viewer(response, CHAT_TYPE_WHISPER, CHANNEL); + } + } else + + if (token == "create") { + if (floater) delete floater; + std::string nStr, mStr; + if (!cmdGetToken(cmds, offset, nStr)) break; + if (!cmdGetToken(cmds, offset, mStr)) break; + if (mStr != "/") break; + if (!cmdGetToken(cmds, offset, mStr)) break; + int n = strtol(nStr.c_str(), 0, 10); + int m = strtol(mStr.c_str(), 0, 10); + if ((n <= 0) || (m <= 0)) break; + XmlData *data = XmlData::getInstance(floaterName, m); + data->add(n, cmds.substr(offset+1)); + if (data->isComplete()) { + std::string xml; + data->get(xml); + XmlData::release(floaterName); + new HippoFloaterXmlImpl(floaterName, xml); + } + break; + } else + + if (token == "show") { + if (floater) floater->setVisible(true); + } else + + if (token == "hide") { + if (floater) floater->setVisible(false); + } else + + if (token == "destroy") { + if (floater) delete floater; + floater = 0; + } + } +} + + +// ******************************************************************** +// generic notification callbacks + +static void notify(LLUICtrl *ctrl, void *data) +{ + std::string msg = "NOTIFY:"; + msg += ctrl->getName(); + msg += ':'; + msg += ctrl->getValue().asString(); + send_chat_from_viewer(msg, CHAT_TYPE_WHISPER, CHANNEL); +} + +static void notify(void *data) +{ + notify(static_cast(data), 0); +} + +void HippoFloaterXmlImpl::onClose(bool quitting) +{ + if (mIsNotifyOnClose) + send_chat_from_viewer("NOTIFY:" + mName + ":closed", + CHAT_TYPE_WHISPER, CHANNEL); + LLFloater::onClose(quitting); +} + + +// ******************************************************************** +// execute commands on instance + +bool HippoFloaterXmlImpl::execute(LLUICtrl *ctrl, + const std::string &cmds, std::string::size_type &offset, + std::string &response) +{ + std::string token; + + while (cmdGetToken(cmds, offset, token)) { + + if (token == "}") { + return true; + } else { + std::string key = token; + if (key == "getValue") { + response += "VALUE:" + ctrl->getName() + ':' + ctrl->getValue().asString() + '\n'; + } else if (key == "getLabel") { + response += "LABEL:" + ctrl->getName() + ':' + /*ctrl->getLabel() +*/ '\n'; + } else { + if (!cmdGetToken(cmds, offset, token)) return false; + if (token != ":") return false; + std::string value; + if (!cmdGetToken(cmds, offset, value)) return false; + if (key == "node") { + LLUICtrl *child = ctrl->getChild(value); + if (!child) return false; + if (!cmdGetToken(cmds, offset, token)) return false; + if (token != "{") return false; + if (!execute(child, cmds, offset, response)) + return false; + } else if (key == "setValue") { + ctrl->setValue(value); + } else if (key == "setLabel") { + /*ctrl->setLabel(value);*/ + } else if (key == "setVisible") { + ctrl->setVisible(value != "0"); + } else if (key == "notify") { + bool set = (value != "0"); + if (HippoFloaterXmlImpl *floater = dynamic_cast(ctrl)) { + floater->mIsNotifyOnClose = set; + } else if (LLButton *button = dynamic_cast(ctrl)) { + if (set) + button->setClickedCallback(notify, ctrl); + else + button->setClickedCallback(0, 0); + } else { + if (set) + ctrl->setCommitCallback(notify); + else + ctrl->setCommitCallback(0); + } + } + } + } + } + return false; +} + + +// ******************************************************************** +// parsing tools + +static bool cmdGetToken(const std::string &cmds, std::string::size_type &offset, std::string &token) +{ + token = ""; + std::string::size_type size = cmds.size(); + char ch; + while ((offset < size) && isspace(cmds[offset])) offset++; + if (offset >= size) return false; + ch = cmds[offset]; + if (ch == '\'') { + ch = cmds[++offset]; + while ((offset < size) && (ch != '\'')) { + if (ch == '&') ch = cmds[++offset]; + token += ch; + ch = cmds[++offset]; + } + offset++; + } else if (isdigit(ch)) { + while ((offset < size) && isdigit(ch)) { + token += ch; + ch = cmds[++offset]; + } + } else if (isalpha(ch)) { + while ((offset < size) && (isalnum(ch) || (ch == '_'))) { + token += ch; + ch = cmds[++offset]; + } + } else { + token += ch; + offset++; + } + return (token != ""); +} + diff --git a/indra/newview/hippofloaterxml.h b/indra/newview/hippofloaterxml.h new file mode 100755 index 000000000..4fabe7473 --- /dev/null +++ b/indra/newview/hippofloaterxml.h @@ -0,0 +1,48 @@ +/** + * @file hippofloaterxml.h + * @author Mana Janus + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#ifndef HIPPO_FLOATERXML_H +#define HIPPO_FLOATERXML_H + + +#include + + +class HippoFloaterXml +{ + public: + // execute commands + static void execute(const std::string &cmds); +}; + + +#endif diff --git a/indra/newview/hipporestrequest.cpp b/indra/newview/hipporestrequest.cpp index 6ff9d0030..52adf6c39 100644 --- a/indra/newview/hipporestrequest.cpp +++ b/indra/newview/hipporestrequest.cpp @@ -1,3 +1,4 @@ + #include "llviewerprecompiledheaders.h" #include "hipporestrequest.h" @@ -8,7 +9,303 @@ #include #include +#include #include +#include +#include +#include + + +// ******************************************************************** + + +class HippoRestComplete : public LLURLRequestComplete +{ + public: + HippoRestComplete(HippoRestHandler *handler) : + mHandler(handler), + mStatus(499), + mReason("Request completed w/o status") + { + } + + ~HippoRestComplete() + { + delete mHandler; + } + + // Called once for each header received, prior to httpStatus + void header(const std::string& header, const std::string& value) + { + mHandler->addHeader(header, value); + } + + // Always called on request completion, prior to complete + void httpStatus(U32 status, const std::string& reason) + { + LLURLRequestComplete::httpStatus(status, reason); + mStatus = status; + mReason = reason; + } + + void complete(const LLChannelDescriptors &channels, const buffer_ptr_t &buffer) + { + mHandler->handle(mStatus, mReason, channels, buffer); + } + + private: + HippoRestHandler *mHandler; + int mStatus; + std::string mReason; +}; + + +// ******************************************************************** + + +static std::string gEmptyString; + +void HippoRestHandler::addHeader(const std::string &header, const std::string &content) +{ + mHeaders[header] = content; +} + +bool HippoRestHandler::hasHeader(const std::string &header) const +{ + return (mHeaders.find(header) != mHeaders.end()); +} + +const std::string &HippoRestHandler::getHeader(const std::string &header) const +{ + std::map::const_iterator it; + it = mHeaders.find(header); + if (it != mHeaders.end()) { + return it->second; + } else { + return gEmptyString; + } +} + + +// ******************************************************************** + + +void HippoRestHandlerRaw::handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body) +{ + if (status == 200) { + std::string data; + LLBufferArray *buffer = body.get(); + LLBufferArray::segment_iterator_t it, end = buffer->endSegment(); + for (it=buffer->beginSegment(); it!=end; ++it) + if (it->isOnChannel(channels.in())) + data.append((char*)it->data(), it->size()); + result(data); + } else { + llwarns << "Rest request error " << status << ": " << reason << llendl; + } +} + +void HippoRestHandlerXml::handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body) +{ + if (status == 200) { + LLXmlTree *tree = new LLXmlTree(); + bool success = tree->parseBufferStart(); + LLBufferArray *buffer = body.get(); + LLBufferArray::segment_iterator_t it, end = buffer->endSegment(); + for (it=buffer->beginSegment(); success && (it!=end); ++it) + if (it->isOnChannel(channels.in())) + success = success && tree->parseBuffer((char*)it->data(), it->size()); + success = success && tree->parseBufferFinalize(); + if (success) result(tree); + delete tree; + } else { + llwarns << "Rest request error " << status << ": " << reason << llendl; + } +} + + +// ******************************************************************** + + +class BodyData : public LLIOPipe +{ + public: + virtual ~BodyData() { } + virtual const char *getContentMimeType() const = 0; +}; + +class BodyDataRaw : public BodyData +{ + public: + explicit BodyDataRaw(const std::string &data) : + mData(data) + { + } + virtual ~BodyDataRaw() { } + + const char *getContentMimeType() const { return "application/octet-stream"; } + + EStatus process_impl(const LLChannelDescriptors &channels, + buffer_ptr_t &buffer, bool &eos, + LLSD &context, LLPumpIO *pump) + { + LLBufferStream ostream(channels, buffer.get()); + ostream.write(mData.data(), mData.size()); + eos = true; + return STATUS_DONE; + } + + private: + std::string mData; +}; + +class BodyDataXml : public BodyData +{ + public: + explicit BodyDataXml(const LLXmlTree *tree) : + mTree(tree) + { + } + + virtual ~BodyDataXml() + { + if (mTree) delete mTree; + } + + const char *getContentMimeType() const { return "application/xml"; } + + EStatus process_impl(const LLChannelDescriptors &channels, + buffer_ptr_t &buffer, bool &eos, + LLSD &context, LLPumpIO *pump) + { + std::string data; + mTree->write(data); + LLBufferStream ostream(channels, buffer.get()); + ostream.write(data.data(), data.size()); + eos = true; + return STATUS_DONE; + } + + private: + const LLXmlTree *mTree; +}; + + +// ******************************************************************** + + +static void request(const std::string &url, + LLURLRequest::ERequestAction method, + BodyData *body, + HippoRestHandler *handler, float timeout); + + +// static +void HippoRestRequest::get(const std::string &url, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_GET, 0, handler, timeout); +} + +// static +void HippoRestRequest::put(const std::string &url, const std::string &body, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_PUT, new BodyDataRaw(body), handler, timeout); +} + +// static +void HippoRestRequest::put(const std::string &url, const LLXmlTree *body, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_PUT, new BodyDataXml(body), handler, timeout); +} + +// static +void HippoRestRequest::post(const std::string &url, const std::string &body, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_POST, new BodyDataRaw(body), handler, timeout); +} + +// static +void HippoRestRequest::post(const std::string &url, const LLXmlTree *body, + HippoRestHandler *handler, float timeout) +{ + request(url, LLURLRequest::HTTP_POST, new BodyDataXml(body), handler, timeout); +} + + +// ******************************************************************** + + +static void request(const std::string &url, + LLURLRequest::ERequestAction method, + BodyData *body, + HippoRestHandler *handler, float timeout) +{ + if (!LLHTTPClient::hasPump()) + { + // !!! responder->completed(U32_MAX, "No pump", LLSD()); + return; + } + LLPumpIO::chain_t chain; + + LLURLRequest *req = new LLURLRequest(method, url); + req->checkRootCertificate(true); + + /* + // Insert custom headers if the caller sent any + if (headers.isMap()) + { + LLSD::map_const_iterator iter = headers.beginMap(); + LLSD::map_const_iterator end = headers.endMap(); + + for (; iter != end; ++iter) + { + std::ostringstream header; + //if the header is "Pragma" with no value + //the caller intends to force libcurl to drop + //the Pragma header it so gratuitously inserts + //Before inserting the header, force libcurl + //to not use the proxy (read: llurlrequest.cpp) + static const std::string PRAGMA("Pragma"); + if ((iter->first == PRAGMA) && (iter->second.asString().empty())) + { + req->useProxy(false); + } + header << iter->first << ": " << iter->second.asString() ; + lldebugs << "header = " << header.str() << llendl; + req->addHeader(header.str().c_str()); + } + } + */ + + if ((method != LLURLRequest::HTTP_PUT) && (method != LLURLRequest::HTTP_POST)) { + std::string accept = "Accept: "; + accept += handler->getAcceptMimeType(); + req->addHeader(accept.c_str()); + } + + req->setCallback(new HippoRestComplete(handler)); + + if ((method == LLURLRequest::HTTP_PUT) || (method == LLURLRequest::HTTP_POST)) { + std::string content = "Content-Type: "; + content += body->getContentMimeType(); + req->addHeader(content.c_str()); + chain.push_back(LLIOPipe::ptr_t(body)); + } + + chain.push_back(LLIOPipe::ptr_t(req)); + LLHTTPClient::getPump().addChain(chain, timeout); +} + + +// ******************************************************************** static size_t curlWrite(void *ptr, size_t size, size_t nmemb, void *userData) diff --git a/indra/newview/hipporestrequest.h b/indra/newview/hipporestrequest.h index 2592902d5..727dbf733 100644 --- a/indra/newview/hipporestrequest.h +++ b/indra/newview/hipporestrequest.h @@ -2,14 +2,102 @@ #define __HIPPO_REST_REQUEST_H__ +#include #include +#include + +class LLBufferArray; +class LLChannelDescriptors; +class LLXmlTree; + + +#define HIPPO_REST_TIMEOUT 60.f + + +// ******************************************************************** + + +class HippoRestHandler +{ + public: + virtual ~HippoRestHandler() { } + + virtual const char *getAcceptMimeType() const = 0; + + bool hasHeader(const std::string &header) const; + const std::string &getHeader(const std::string &header) const; + + private: + // These functions are called by the request engine + void addHeader(const std::string &header, const std::string &content); + virtual void handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body) = 0; + + std::map mHeaders; + + friend class HippoRestComplete; +}; + + +class HippoRestHandlerRaw : public HippoRestHandler +{ + public: + virtual ~HippoRestHandlerRaw() { } + + const char *getAcceptMimeType() const { return "application/octet-stream"; } + + private: + // This function must be implemented to receive the content + // it is executed on (status == 200) only + virtual void result(const std::string &content) = 0; + + // This function is called by the request engine + void handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body); +}; + + +class HippoRestHandlerXml : public HippoRestHandler +{ + public: + virtual ~HippoRestHandlerXml() { } + + const char *getAcceptMimeType() const { return "application/xml"; } + + private: + // This function must be implemented to receive the content + virtual void result(LLXmlTree *content) = 0; + + // This function is called by the request engine + void handle(int status, const std::string &reason, + const LLChannelDescriptors &channels, + const boost::shared_ptr &body); +}; + + +// ******************************************************************** + class HippoRestRequest { public: + // asynchronous interface + static void get(const std::string &url, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + static void put(const std::string &url, const std::string &body, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + static void put(const std::string &url, const LLXmlTree *body, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + static void post(const std::string &url, const std::string &body, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + static void post(const std::string &url, const LLXmlTree *body, + HippoRestHandler *handler, float timeout=HIPPO_REST_TIMEOUT); + + // synchronous interface static int getBlocking(const std::string &url, std::string *result); - }; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 1cc324c2c..82c3638aa 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -226,6 +226,8 @@ const F64 CHAT_AGE_FAST_RATE = 3.0; // The agent instance. LLAgent gAgent; +std::string gAuthString; + // LLUUID gReSitTargetID; LLVector3 gReSitOffset; diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 71363c28c..01fe68876 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -1039,6 +1039,8 @@ private: }; extern LLAgent gAgent; +extern std::string gAuthString; + // extern LLUUID gReSitTargetID; extern LLVector3 gReSitOffset; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a75e4162c..a05106be7 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -75,6 +75,7 @@ #include "llfirstuse.h" #include "llrender.h" #include "llfont.h" +#include "llimagej2c.h" #include "llweb.h" #include "llsecondlifeurls.h" @@ -179,6 +180,7 @@ #include "llinventoryview.h" #include "llcommandlineparser.h" +#include "llprogressview.h" // [RLVa:KB] #include "rlvhandler.h" @@ -733,6 +735,7 @@ bool LLAppViewer::init() // // Initialize the window // + gGLActive = TRUE; initWindow(); // call all self-registered classes @@ -874,7 +877,8 @@ bool LLAppViewer::mainLoop() { LLFastTimer t(LLFastTimer::FTM_FRAME); pingMainloopTimeout("Main:MiscNativeWindowEvents"); - + + if (gViewerWindow) { LLFastTimer t2(LLFastTimer::FTM_MESSAGES); gViewerWindow->mWindow->processMiscNativeEvents(); @@ -882,6 +886,7 @@ bool LLAppViewer::mainLoop() pingMainloopTimeout("Main:GatherInput"); + if (gViewerWindow) { LLFastTimer t2(LLFastTimer::FTM_MESSAGES); if (!restoreErrorTrap()) @@ -957,11 +962,12 @@ bool LLAppViewer::mainLoop() if (!LLApp::isExiting()) { pingMainloopTimeout("Main:Display"); + gGLActive = TRUE; display(); pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots - + gGLActive = FALSE; #if LL_LCD_COMPILE // update LCD Screen pingMainloopTimeout("Main:LCD"); @@ -988,7 +994,7 @@ bool LLAppViewer::mainLoop() // yield cooperatively when not running as foreground window if ( gNoRender - || !gViewerWindow->mWindow->getVisible() + || (gViewerWindow && !gViewerWindow->mWindow->getVisible()) || !gFocusMgr.getAppHasFocus()) { // Sleep if we're not rendering, or the window is minimized. @@ -1140,11 +1146,14 @@ bool LLAppViewer::cleanup() llinfos << "Cleaning Up" << llendflush; // Must clean up texture references before viewer window is destroyed. - LLHUDManager::getInstance()->updateEffects(); - LLHUDObject::updateAll(); - LLHUDManager::getInstance()->cleanupEffects(); - LLHUDObject::cleanupHUDObjects(); - llinfos << "HUD Objects cleaned up" << llendflush; + if(LLHUDManager::instanceExists()) + { + LLHUDManager::getInstance()->updateEffects(); + LLHUDObject::updateAll(); + LLHUDManager::getInstance()->cleanupEffects(); + LLHUDObject::cleanupHUDObjects(); + llinfos << "HUD Objects cleaned up" << llendflush; + } LLKeyframeDataCache::clear(); @@ -1156,8 +1165,10 @@ bool LLAppViewer::cleanup() // Note: this is where gWorldMap used to be deleted. // Note: this is where gHUDManager used to be deleted. - LLHUDManager::getInstance()->shutdownClass(); - + if(LLHUDManager::instanceExists()) + { + LLHUDManager::getInstance()->shutdownClass(); + } delete gAssetStorage; gAssetStorage = NULL; @@ -1246,21 +1257,25 @@ bool LLAppViewer::cleanup() llinfos << "Shutting down." << llendflush; // Destroy the UI - gViewerWindow->shutdownViews(); + if( gViewerWindow) + gViewerWindow->shutdownViews(); // Clean up selection managers after UI is destroyed, as UI may be observing them. // Clean up before GL is shut down because we might be holding on to objects with texture references LLSelectMgr::cleanupGlobals(); // Shut down OpenGL - gViewerWindow->shutdownGL(); + if( gViewerWindow) + { + gViewerWindow->shutdownGL(); - // Destroy window, and make sure we're not fullscreen - // This may generate window reshape and activation events. - // Therefore must do this before destroying the message system. - delete gViewerWindow; - gViewerWindow = NULL; - llinfos << "ViewerWindow deleted" << llendflush; + // Destroy window, and make sure we're not fullscreen + // This may generate window reshape and activation events. + // Therefore must do this before destroying the message system. + delete gViewerWindow; + gViewerWindow = NULL; + llinfos << "ViewerWindow deleted" << llendflush; + } // viewer UI relies on keyboard so keep it aound until viewer UI isa gone delete gKeyboard; @@ -1368,6 +1383,9 @@ bool LLAppViewer::cleanup() writeDebugInfo(); + // Stop the plugin read thread if it's running. + LLPluginProcessParent::setUseReadThread(false); + // Let threads finish LLTimer idleTimer; idleTimer.reset(); @@ -1393,8 +1411,8 @@ bool LLAppViewer::cleanup() // Delete workers first // shotdown all worker threads before deleting them in case of co-dependencies - sTextureCache->shutdown(); sTextureFetch->shutdown(); + sTextureCache->shutdown(); sImageDecodeThread->shutdown(); sTextureFetch->shutDownTextureCacheThread(); sTextureFetch->shutDownImageDecodeThread(); @@ -1423,7 +1441,10 @@ bool LLAppViewer::cleanup() #ifndef LL_RELEASE_FOR_DOWNLOAD llinfos << "Auditing VFS" << llendl; - gVFS->audit(); + if(gVFS) + { + gVFS->audit(); + } #endif // For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up. @@ -2133,9 +2154,7 @@ bool LLAppViewer::initConfiguration() void LLAppViewer::checkForCrash(void) { - // screw sending crash reports -#if LL_SEND_CRASH_REPORTS && 0 - // +#if LL_SEND_CRASH_REPORTS //*NOTE:Mani The current state of the crash handler has the MacOSX // sending all crash reports as freezes, in order to let // the MacOSX CrashRepoter generate stacks before spawning the @@ -2524,7 +2543,7 @@ void LLAppViewer::handleViewerCrash() gMessageSystem->stopLogging(); } - LLWorld::getInstance()->getInfo(gDebugInfo); + if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo); // Close the debug file pApp->writeDebugInfo(); @@ -2691,6 +2710,13 @@ void LLAppViewer::requestQuit() if( (LLStartUp::getStartupState() < STATE_STARTED) || !region ) { + // If we have a region, make some attempt to send a logout request first. + // This prevents the halfway-logged-in avatar from hanging around inworld for a couple minutes. + if(region) + { + sendLogoutRequest(); + } + // Quit immediately forceQuit(); return; @@ -2730,6 +2756,11 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q void LLAppViewer::userQuit() { + if (gDisconnected || gViewerWindow->getProgressView()->getVisible()) + { + requestQuit(); + } + else LLNotifications::instance().add("ConfirmQuit"); } @@ -3310,10 +3341,13 @@ void LLAppViewer::idle() if (LLStartUp::getStartupState() < STATE_STARTED) { // Skip rest if idle startup returns false (essentially, no world yet) + gGLActive = TRUE; if (!idle_startup()) { + gGLActive = FALSE; return; } + gGLActive = FALSE; } @@ -3640,6 +3674,7 @@ void LLAppViewer::idle() // forcibly quit if it has taken too long if (mQuitRequested) { + gGLActive = TRUE; idleShutdown(); } diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 2ae30f9da..bc1ccfc10 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -384,8 +384,6 @@ void LLDrawable::makeActive() mParent->makeActive(); } - gPipeline.setActive(this, TRUE); - //all child objects must also be active llassert_always(mVObjp); @@ -432,7 +430,6 @@ void LLDrawable::makeStatic(BOOL warning_enabled) if (isState(ACTIVE)) { clearState(ACTIVE); - gPipeline.setActive(this, FALSE); if (mParent.notNull() && mParent->isActive() && warning_enabled) { @@ -676,6 +673,11 @@ BOOL LLDrawable::updateMoveDamped() void LLDrawable::updateDistance(LLCamera& camera, bool force_update) { + if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) + { + llerrs << "WTF?" << llendl; + } + //switch LOD with the spatial group to avoid artifacts //LLSpatialGroup* sg = getSpatialGroup(); @@ -953,11 +955,31 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() return retval; } +const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one. +//static +S32 LLDrawable::getMinVisFrameRange() +{ + return MIN_VIS_FRAME_RANGE ; +} + BOOL LLDrawable::isRecentlyVisible() const { //currently visible or visible in the previous frame. - return isVisible() || (mVisible == sCurVisible - 1) ; + BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ; + + if(!vis) + { + LLSpatialGroup* group = getSpatialGroup(); + if (group && group->isRecentlyVisible()) + { + mVisible = sCurVisible; + vis = TRUE ; + } + } + + return vis ; } + BOOL LLDrawable::isVisible() const { if (mVisible == sCurVisible) @@ -1007,8 +1029,8 @@ BOOL LLDrawable::isVisible() const // Spatial Partition Bridging Drawable //======================================= -LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask) -: LLSpatialPartition(data_mask, FALSE) +LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) +: LLSpatialPartition(data_mask, render_by_group, FALSE) { mDrawable = root; root->setSpatialBridge(this); @@ -1019,8 +1041,16 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask) mPartitionType = LLViewerRegion::PARTITION_VOLUME; mOctree->balance(); + + llassert(mDrawable); + llassert(mDrawable->getRegion()); + LLSpatialPartition *part = mDrawable->getRegion()->getSpatialPartition(mPartitionType); + llassert(part); - mDrawable->getRegion()->getSpatialPartition(mPartitionType)->put(this); + if (part) + { + part->put(this); + } } LLSpatialBridge::~LLSpatialBridge() @@ -1334,8 +1364,16 @@ void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL imm BOOL LLSpatialBridge::updateMove() { + llassert_always(mDrawable); + llassert_always(mDrawable->mVObjp); + llassert_always(mDrawable->getRegion()); + LLSpatialPartition* part = mDrawable->getRegion()->getSpatialPartition(mPartitionType); + llassert_always(part); mOctree->balance(); - mDrawable->getRegion()->getSpatialPartition(mPartitionType)->move(this, getSpatialGroup(), TRUE); + if (part) + { + part->move(this, getSpatialGroup(), TRUE); + } return TRUE; } @@ -1439,9 +1477,8 @@ void LLDrawable::updateFaceSize(S32 idx) } LLBridgePartition::LLBridgePartition() -: LLSpatialPartition(0, TRUE) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; mLODPeriod = 16; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 2d693b6d2..47bbcf1c1 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -281,6 +281,7 @@ public: S32 mQuietCount; static S32 getCurrentFrame() { return sCurVisible; } + static S32 getMinVisFrameRange(); void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; } LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 342173159..243c51eb9 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -482,7 +482,8 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) { if (params.mTexture.notNull()) { - gGL.getTexUnit(0)->bind(params.mTexture.get(), TRUE); + params.mTexture->addTextureStats(params.mVSize); + gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; if (params.mTextureMatrix) { glMatrixMode(GL_TEXTURE); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 4b552acd5..d3a326c93 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -61,7 +61,9 @@ static BOOL deferred_render = FALSE; LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : LLRenderPass(type), current_shader(NULL), target_shader(NULL), - simple_shader(NULL), fullbright_shader(NULL) + simple_shader(NULL), fullbright_shader(NULL), + mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF), + mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF) { } @@ -88,22 +90,23 @@ void LLDrawPoolAlpha::beginDeferredPass(S32 pass) void LLDrawPoolAlpha::endDeferredPass(S32 pass) { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.4f); + +} + +void LLDrawPoolAlpha::renderDeferred(S32 pass) +{ + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); { LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); gDeferredTreeProgram.bind(); LLGLEnable test(GL_ALPHA_TEST); //render alpha masked objects LLRenderPass::renderTexture(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask()); + gDeferredTreeProgram.unbind(); } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } -void LLDrawPoolAlpha::renderDeferred(S32 pass) -{ - -} - S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { @@ -178,8 +181,15 @@ void LLDrawPoolAlpha::render(S32 pass) LLGLSPipelineAlpha gls_pipeline_alpha; + gGL.setColorMask(true, true); if (LLPipeline::sFastAlpha && !deferred_render) { + mColorSFactor = LLRender::BF_ONE; // } + mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow + mAlphaSFactor = LLRender::BF_ZERO; + mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f); if (mVertexShaderLevel > 0) { @@ -203,8 +213,17 @@ void LLDrawPoolAlpha::render(S32 pass) } LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE); + + mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend + mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression + mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + renderAlpha(getVertexDataMask()); + gGL.setColorMask(true, false); + if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); @@ -280,9 +299,18 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; + llassert(group); + llassert(group->mSpatialPartition); + if (group->mSpatialPartition->mRenderByGroup && - !group->isDead()) + !group->isDead()) { + bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. + // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress. + group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && + group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD && + group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; + LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) @@ -291,88 +319,115 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) LLRenderPass::applyModelMatrix(params); - if (params.mTexture.notNull()) { - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(params.mTexture.get()); - - if (params.mTextureMatrix) + if (params.mFullbright) { - glMatrixMode(GL_TEXTURE); - glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; + // Turn off lighting if it hasn't already been so. + if (light_enabled || !initialized_lighting) + { + initialized_lighting = TRUE; + if (use_shaders) + { + target_shader = fullbright_shader; + } + else + { + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + } + light_enabled = FALSE; + } } - } - - if (params.mFullbright) - { - // Turn off lighting if it hasn't already been so. - if (light_enabled || !initialized_lighting) + // Turn on lighting if it isn't already. + else if (!light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { - target_shader = fullbright_shader; + target_shader = simple_shader; } else { - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + gPipeline.enableLightsDynamic(); } - light_enabled = FALSE; + light_enabled = TRUE; } - } - // Turn on lighting if it isn't already. - else if (!light_enabled || !initialized_lighting) - { - initialized_lighting = TRUE; - if (use_shaders) - { - target_shader = simple_shader; - } - else - { - gPipeline.enableLightsDynamic(); - } - light_enabled = TRUE; - } - // If we need shaders, and we're not ALREADY using the proper shader, then bind it - // (this way we won't rebind shaders unnecessarily). - if(use_shaders && (current_shader != target_shader)) - { - llassert(target_shader != NULL); - if (deferred_render && current_shader != NULL) + // If we need shaders, and we're not ALREADY using the proper shader, then bind it + // (this way we won't rebind shaders unnecessarily). + if(use_shaders && (current_shader != target_shader)) { - gPipeline.unbindDeferredShader(*current_shader); + llassert(target_shader != NULL); + if (deferred_render && current_shader != NULL) + { + gPipeline.unbindDeferredShader(*current_shader); + } + current_shader = target_shader; + if (deferred_render) + { + gPipeline.bindDeferredShader(*current_shader); + } + else + { + current_shader->bind(); + } } - current_shader = target_shader; - if (deferred_render) + else if (!use_shaders && current_shader != NULL) { - gPipeline.bindDeferredShader(*current_shader); + + if (deferred_render) + { + gPipeline.unbindDeferredShader(*current_shader); + } + LLGLSLShader::bindNoShader(); + current_shader = NULL; } - else - { - current_shader->bind(); - } - } - else if (!use_shaders && current_shader != NULL) - { - LLGLSLShader::bindNoShader(); - if (deferred_render) - { - gPipeline.unbindDeferredShader(*current_shader); - } - current_shader = NULL; - } - if (params.mGroup) - { - params.mGroup->rebuildMesh(); + if (params.mGroup) + { + params.mGroup->rebuildMesh(); + } + + + if (params.mTexture.notNull()) + { + gGL.getTexUnit(0)->bind(params.mTexture.get()); + if(params.mTexture.notNull()) + { + params.mTexture->addTextureStats(params.mVSize); + } + if (params.mTextureMatrix) + { + gGL.getTexUnit(0)->activate(); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + } } params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount/3); + + // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. + if (draw_glow_for_this_partition && + params.mGlowColor.mV[3] > 0) + { + // install glow-accumulating blend mode + gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color + LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) + // glow doesn't use vertex colors from the mesh data + params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR); + glColor4ubv(params.mGlowColor.mV); + + // do the actual drawing, again + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + gPipeline.addTrianglesDrawn(params.mCount/3); + + // restore our alpha blend mode + gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); + } + if (params.mTextureMatrix && params.mTexture.notNull()) { gGL.getTexUnit(0)->activate(); @@ -383,6 +438,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } + if (deferred_render && current_shader != NULL) + { + gPipeline.unbindDeferredShader(*current_shader); + LLVertexBuffer::unbind(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); + } + if (!light_enabled) { gPipeline.enableLightsDynamic(); diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index 3aa752f72..c3aca964d 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -83,6 +83,12 @@ private: LLGLSLShader* target_shader; LLGLSLShader* simple_shader; LLGLSLShader* fullbright_shader; + + // our 'normal' alpha blend function for this pass + LLRender::eBlendFactor mColorSFactor; + LLRender::eBlendFactor mColorDFactor; + LLRender::eBlendFactor mAlphaSFactor; + LLRender::eBlendFactor mAlphaDFactor; }; class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 38996e624..97daff8aa 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -158,8 +158,8 @@ S32 LLDrawPoolAvatar::getNumDeferredPasses() void LLDrawPoolAvatar::beginDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); - + sSkipTransparent = TRUE; + if (LLPipeline::sImpostorRender) { beginDeferredSkinned(); @@ -182,7 +182,7 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass) void LLDrawPoolAvatar::endDeferredPass(S32 pass) { - LLFastTimer t(LLFastTimer::FTM_RENDER_CHARACTERS); + sSkipTransparent = FALSE; if (LLPipeline::sImpostorRender) { @@ -317,6 +317,10 @@ void LLDrawPoolAvatar::renderShadow(S32 pass) return; } + if (sShaderLevel > 0) + { + gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX]; + } avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } @@ -353,7 +357,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass) switch (pass) { case 0: - beginFootShadow(); + beginImpostor(); break; case 1: beginRigid(); @@ -377,7 +381,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) switch (pass) { case 0: - endFootShadow(); + endImpostor(); break; case 1: endRigid(); @@ -387,7 +391,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass) } } -void LLDrawPoolAvatar::beginFootShadow() +void LLDrawPoolAvatar::beginImpostor() { if (!LLPipeline::sReflectionRender) { @@ -398,7 +402,7 @@ void LLDrawPoolAvatar::beginFootShadow() gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } -void LLDrawPoolAvatar::endFootShadow() +void LLDrawPoolAvatar::endImpostor() { gPipeline.enableLightsDynamic(); } @@ -568,7 +572,6 @@ void LLDrawPoolAvatar::endSkinned() void LLDrawPoolAvatar::beginDeferredSkinned() { - sSkipTransparent = TRUE; sShaderLevel = mVertexShaderLevel; sVertexProgram = &gDeferredAvatarProgram; @@ -583,7 +586,6 @@ void LLDrawPoolAvatar::beginDeferredSkinned() void LLDrawPoolAvatar::endDeferredSkinned() { - sSkipTransparent = FALSE; // if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done sRenderingSkinned = FALSE; disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 1e2630e1f..e12f5081f 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -90,11 +90,11 @@ public: /*virtual*/ void renderShadow(S32 pass); void beginRigid(); - void beginFootShadow(); + void beginImpostor(); void beginSkinned(); void endRigid(); - void endFootShadow(); + void endImpostor(); void endSkinned(); void beginDeferredImpostor(); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 14931024e..7ca763a18 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -263,7 +263,7 @@ void LLDrawPoolGrass::endDeferredPass(S32 pass) void LLDrawPoolGrass::renderDeferred(S32 pass) { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); { LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp index bed103047..63e24ec8a 100644 --- a/indra/newview/lldrawpoolsky.cpp +++ b/indra/newview/lldrawpoolsky.cpp @@ -49,8 +49,11 @@ #include "pipeline.h" #include "llviewershadermgr.h" -LLDrawPoolSky::LLDrawPoolSky() : - LLFacePool(POOL_SKY), mShader(NULL) +LLDrawPoolSky::LLDrawPoolSky() +: LLFacePool(POOL_SKY), + + mSkyTex(NULL), + mShader(NULL) { } diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 019d1328e..833c74873 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -73,19 +73,19 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) : TRUE, TRUE, GL_ALPHA8, GL_ALPHA, LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb")); - gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); + //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c", TRUE, TRUE, GL_ALPHA8, GL_ALPHA, LLUUID("38b86f85-2575-52a9-a531-23108d8da837")); - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_TERRAIN); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } LLDrawPoolTerrain::~LLDrawPoolTerrain() diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 2f3833dd6..f08e22569 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -52,7 +52,6 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) : LLFacePool(POOL_TREE), mTexturep(texturep) { - gGL.getTexUnit(0)->bind(mTexturep.get()); mTexturep->setAddressMode(LLTexUnit::TAM_WRAP); } @@ -142,8 +141,8 @@ void LLDrawPoolTree::endRenderPass(S32 pass) void LLDrawPoolTree::beginDeferredPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); - + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); + shader = &gDeferredTreeProgram; shader->bind(); } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 6fa1d5894..4b9f55946 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -137,6 +137,19 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass) deferred_render = FALSE; } +//=============================== +//DEFERRED IMPLEMENTATION +//=============================== +void LLDrawPoolWater::renderDeferred(S32 pass) +{ + LLFastTimer t(LLFastTimer::FTM_RENDER_WATER); + deferred_render = TRUE; + shade(); + deferred_render = FALSE; +} + +//========================================= + void LLDrawPoolWater::render(S32 pass) { LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER); @@ -338,7 +351,10 @@ void LLDrawPoolWater::renderReflection(LLFace* face) void LLDrawPoolWater::shade() { - gGL.setColorMask(true, true); + if (!deferred_render) + { + gGL.setColorMask(true, true); + } LLVOSky *voskyp = gSky.mVOSkyp; @@ -354,7 +370,7 @@ void LLDrawPoolWater::shade() LLVector3 light_dir; LLColor3 light_color; - if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) { light_dir = gSky.getSunDirection(); light_dir.normVec(); @@ -401,6 +417,15 @@ void LLDrawPoolWater::shade() shader = &gWaterProgram; } + if (deferred_render) + { + gPipeline.bindDeferredShader(*shader); + } + else + { + shader->bind(); + } + sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); @@ -436,15 +461,6 @@ void LLDrawPoolWater::shade() S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); - if (deferred_render) - { - gPipeline.bindDeferredShader(*shader); - } - else - { - shader->bind(); - } - if (screentex > -1) { shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); @@ -545,7 +561,7 @@ void LLDrawPoolWater::shade() sNeedsDistortionUpdate = TRUE; face->renderIndexed(); } - else if (gGLManager.mHasDepthClamp) + else if (gGLManager.mHasDepthClamp || deferred_render) { face->renderIndexed(); } @@ -575,7 +591,10 @@ void LLDrawPoolWater::shade() gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.setColorMask(true, false); + if (!deferred_render) + { + gGL.setColorMask(true, false); + } } diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index 635104114..90db2ed29 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -71,10 +71,12 @@ public: /*virtual*/ LLDrawPool *instancePool(); static void restoreGL(); - /*virtual*/ S32 getNumPostDeferredPasses() { return getNumPasses(); } + /*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); } /*virtual*/ void beginPostDeferredPass(S32 pass); /*virtual*/ void endPostDeferredPass(S32 pass); /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); } + /*virtual*/ S32 getNumDeferredPasses() { return 1; } + /*virtual*/ void renderDeferred(S32 pass = 0); /*virtual*/ S32 getNumPasses(); /*virtual*/ void render(S32 pass = 0); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index c32ee428c..3f5754007 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -160,14 +160,14 @@ void LLDrawPoolWLSky::renderStars(void) const // *NOTE: have to have bound the cloud noise texture already since register // combiners blending below requires something to be bound // and we might as well only bind once. - //gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); gPipeline.disableLights(); - if (!LLPipeline::sReflectionRender) + /*if (!LLPipeline::sReflectionRender) { glPointSize(2.f); - } + }*/ // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid // clamping and allow the star_alpha param to brighten the stars. @@ -175,17 +175,26 @@ void LLDrawPoolWLSky::renderStars(void) const LLColor4 star_alpha(LLColor4::black); star_alpha.mV[3] = LLWLParamManager::instance()->mCurParams.getFloat("star_brightness", error) / 2.f; llassert_always(!error); - + // gl_FragColor.rgb = gl_Color.rgb; // gl_FragColor.a = gl_Color.a * star_alpha.a; - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_PREV_ALPHA, LLTexUnit::TBS_CONST_ALPHA); - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV); + //New + gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex()); + gGL.pushMatrix(); + glRotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); + gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR); + gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA); + /*//Old + gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR); + gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_PREV_ALPHA, LLTexUnit::TBS_CONST_ALPHA); */ + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV); + gSky.mVOWLSkyp->drawStars(); - glPointSize(1.f); - + gGL.popMatrix(); //New + //glPointSize(1.f); + // and disable the combiner states gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } @@ -284,9 +293,10 @@ void LLDrawPoolWLSky::render(S32 pass) LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(); gGL.getTexUnit(0)->bind(tex); + renderHeavenlyBodies(); + renderStars(); - renderHeavenlyBodies(); glPopMatrix(); diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h index c7a1f3fe2..0e2220e7f 100644 --- a/indra/newview/lldrawpoolwlsky.h +++ b/indra/newview/lldrawpoolwlsky.h @@ -43,7 +43,7 @@ public: static const U32 SKY_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0; static const U32 STAR_VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_COLOR; + LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXCOORD0; LLDrawPoolWLSky(void); /*virtual*/ ~LLDrawPoolWLSky(); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 5ce007d1e..14df6a742 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -157,6 +157,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mGeomIndex = 0; mIndicesCount = 0; mIndicesIndex = 0; + mIndexInTex = 0; mTexture = NULL; mTEOffset = -1; @@ -205,6 +206,7 @@ void LLFace::destroy() if (group) { group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); } } } @@ -272,12 +274,36 @@ void LLFace::setTexture(LLViewerImage* tex) mTexture->removeFace(this) ; } - mTexture = tex ; - - if(mTexture.notNull()) + if(tex) { - mTexture->addFace(this) ; - } + tex->addFace(this) ; + } + + mTexture = tex ; +} + +void LLFace::dirtyTexture() +{ + gPipeline.markTextured(getDrawable()); +} + +void LLFace::switchTexture(LLViewerImage* new_texture) +{ + if(mTexture == new_texture) + { + return ; + } + + if(!new_texture) + { + llerrs << "Can not switch to a null texture." << llendl; + return; + } + new_texture->addTextureStats(mTexture->mMaxVirtualSize) ; + + getViewerObject()->changeTEImage(mTEOffset, new_texture) ; + setTexture(new_texture) ; + dirtyTexture(); } void LLFace::setTEOffset(const S32 te_offset) @@ -453,8 +479,15 @@ void LLFace::renderForSelect(U32 data_mask) void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) { - if(mDrawablep.isNull() || mVertexBuffer.isNull() || mDrawablep->getSpatialGroup() == NULL || - mDrawablep->getSpatialGroup()->isState(LLSpatialGroup::GEOM_DIRTY)) + if (mDrawablep->getSpatialGroup() == NULL) + { + return; + } + + mDrawablep->getSpatialGroup()->rebuildGeom(); + mDrawablep->getSpatialGroup()->rebuildMesh(); + + if(mDrawablep.isNull() || mVertexBuffer.isNull()) { return; } @@ -473,17 +506,13 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); } - setFaceColor(color); - renderSetColor(); - + glColor4fv(color.mV); mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays("", LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); #endif mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); - unsetFaceColor(); - unsetFaceColor(); gGL.popMatrix(); } } @@ -805,6 +834,7 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, // by planarProjection(). This is needed to match planar texgen parameters. void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const { + const LLMatrix4& vol_mat = getWorldMatrix(); const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset); LLVector3 normal = vf.mVertices[0].mNormal; LLVector3 binormal = vf.mVertices[0].mBinormal; @@ -819,8 +849,8 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po ang = (projected_binormal.mV[VX] < 0.f) ? -ang : ang; binormal.rotVec(ang, normal); LLQuaternion local_rot( binormal % normal, binormal, normal ); - *face_rot = local_rot * mXform->getWorldRotation(); - *face_pos = mXform->getWorldPosition(); + *face_rot = local_rot * vol_mat.quaternion(); + *face_pos = vol_mat.getTranslation(); } // Returns the necessary texture transform to align this face's TE to align_to's TE @@ -1089,7 +1119,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (full_rebuild) { mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex); - for (U16 i = 0; i < num_indices; i++) + for (U32 i = 0; i < (U32) num_indices; i++) { *indicesp++ = vf.mIndices[i] + index_offset; } @@ -1256,6 +1286,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mTexExtents[1].setVec(1,1); xform(mTexExtents[0], cos_ang, sin_ang, os, ot, ms, mt); xform(mTexExtents[1], cos_ang, sin_ang, os, ot, ms, mt); + + F32 es = vf.mTexCoordExtents[1].mV[0] - vf.mTexCoordExtents[0].mV[0] ; + F32 et = vf.mTexCoordExtents[1].mV[1] - vf.mTexCoordExtents[0].mV[1] ; + mTexExtents[0][0] *= es ; + mTexExtents[1][0] *= es ; + mTexExtents[0][1] *= et ; + mTexExtents[1][1] *= et ; } mLastVertexBuffer = mVertexBuffer; @@ -1305,13 +1342,13 @@ F32 LLFace::getTextureVirtualSize() } face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area); - if (mImportanceToCamera < 1.0f && face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. + if (/*mImportanceToCamera < 1.0f && */face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. { if (mImportanceToCamera > LEAST_IMPORTANCE_FOR_LARGE_IMAGE && mTexture.notNull() && mTexture->isLargeImage()) { face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius); } - } + } setVirtualSize(face_area); @@ -1413,8 +1450,9 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist) if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() && dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) { - F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; - F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); + F32 camera_moving_speed = camera->getAverageSpeed() ; + F32 camera_angular_speed = camera->getAverageAngularSpeed(); if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f) { diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 90edf9de1..c23cf2586 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -87,8 +87,9 @@ public: U16 getGeomCount() const { return mGeomCount; } // vertex count for this face U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool U16 getGeomStart() const { return mGeomIndex; } // index into draw pool - LLViewerImage* getTexture() const { return mTexture; } void setTexture(LLViewerImage* tex) ; + void switchTexture(LLViewerImage* new_texture); + void dirtyTexture(); LLXformMatrix* getXform() const { return mXform; } BOOL hasGeometry() const { return mGeomCount > 0; } LLVector3 getPositionAgent() const; @@ -126,8 +127,8 @@ public: LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; } void setPoolType(U32 type) { mPoolType = type; } S32 getTEOffset() { return mTEOffset; } - LLViewerImage* getTexture() { return mTexture; } - + LLViewerImage* getTexture() const { return mTexture; } + void setViewerObject(LLViewerObject* object); void setPool(LLFacePool *pool, LLViewerImage *texturep); @@ -262,7 +263,7 @@ public: { bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) { - return lhs->mDistance > rhs->mDistance; // farthest = first + return !lhs || (rhs && (lhs->mDistance > rhs->mDistance)); // farthest = first } }; diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index daf5d2a0f..b9032107a 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -705,7 +705,7 @@ BOOL LLVolumeImplFlexible::doUpdateGeometry(LLDrawable *drawable) } if (volume->mLODChanged || volume->mFaceMappingChanged || - volume->mVolumeChanged) + volume->mVolumeChanged || drawable->isState(LLDrawable::REBUILD_MATERIAL)) { volume->regenFaces(); volume->mDrawable->setState(LLDrawable::REBUILD_VOLUME); diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 43f8b7e95..043de9c23 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -275,7 +275,7 @@ LLFloaterAbout::LLFloaterAbout() // TODO: Implement media plugin version query - support.append("Qt Webkit Version: 4.6.0 "); + support.append("Qt Webkit Version: 4.7.1 "); support.append("\n"); if (gPacketsIn > 0) diff --git a/indra/newview/llfloaterexport.cpp b/indra/newview/llfloaterexport.cpp index ded17cdf0..70d229f1a 100644 --- a/indra/newview/llfloaterexport.cpp +++ b/indra/newview/llfloaterexport.cpp @@ -22,6 +22,7 @@ #include "lltexturecache.h" #include "llimage.h" #include "llappviewer.h" +#include "llimagej2c.h" std::vector LLFloaterExport::instances; diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index e10acfe0e..3b721c6ba 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -193,7 +193,8 @@ void LLFloaterHardwareSettings::apply() } else if (old_anisotropic != LLImageGL::sGlobalUseAnisotropic) { - gViewerWindow->restartDisplay(logged_in); + LLImageGL::dirtyTexOptions(); + gViewerWindow->restartDisplay(logged_in); } refresh(); diff --git a/indra/newview/llfloaterpostcard.h b/indra/newview/llfloaterpostcard.h index 087649f15..d294cfca5 100644 --- a/indra/newview/llfloaterpostcard.h +++ b/indra/newview/llfloaterpostcard.h @@ -38,6 +38,7 @@ #include "llmemory.h" #include "llimagegl.h" +#include "llimagejpeg.h" class LLTextEditor; class LLLineEditor; diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 71f54ff0f..cc5101a10 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -43,6 +43,7 @@ #include "llfontgl.h" #include "llgl.h" // for renderer #include "llinventory.h" +#include "llimagej2c.h" #include "llstring.h" #include "llsys.h" #include "llversionviewer.h" diff --git a/indra/newview/llfloatervfs.cpp b/indra/newview/llfloatervfs.cpp index e0b3f1b63..18ee463cb 100644 --- a/indra/newview/llfloatervfs.cpp +++ b/indra/newview/llfloatervfs.cpp @@ -10,6 +10,7 @@ #include "llassetconverter.h" #include "llviewerimagelist.h" #include "llviewerimage.h" +#include "llimagej2c.h" LLFloaterVFS* LLFloaterVFS::sInstance; std::list LLFloaterVFS::mFiles; diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index f68bc28fb..89b4be753 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -1057,19 +1057,21 @@ void LLViewerObjectList::renderObjectBeacons() S32 last_line_width = -1; // gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width) - for (S32 i = 0; i < mDebugBeacons.count(); i++) + BOOL flush = FALSE; + for (std::vector::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter) { - const LLDebugBeacon &debug_beacon = mDebugBeacons[i]; + const LLDebugBeacon &debug_beacon = *iter; LLColor4 color = debug_beacon.mColor; color.mV[3] *= 0.25f; S32 line_width = debug_beacon.mLineWidth; if (line_width != last_line_width) { - if (i > 0) + if (flush) { gGL.end(); - gGL.flush(); } + flush = TRUE; + gGL.flush(); glLineWidth( (F32)line_width ); last_line_width = line_width; gGL.begin(LLRender::LINES); @@ -1095,19 +1097,21 @@ void LLViewerObjectList::renderObjectBeacons() S32 last_line_width = -1; // gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width) - - for (S32 i = 0; i < mDebugBeacons.count(); i++) + + BOOL flush = FALSE; + for (std::vector::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter) { - const LLDebugBeacon &debug_beacon = mDebugBeacons[i]; + const LLDebugBeacon &debug_beacon = *iter; S32 line_width = debug_beacon.mLineWidth; if (line_width != last_line_width) { - if (i > 0) + if (flush) { gGL.end(); - gGL.flush(); } + flush = TRUE; + gGL.flush(); glLineWidth( (F32)line_width ); last_line_width = line_width; gGL.begin(LLRender::LINES); @@ -1129,9 +1133,9 @@ void LLViewerObjectList::renderObjectBeacons() gGL.flush(); glLineWidth(1.f); - for (S32 i = 0; i < mDebugBeacons.count(); i++) + for (std::vector::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter) { - LLDebugBeacon &debug_beacon = mDebugBeacons[i]; + LLDebugBeacon &debug_beacon = *iter; if (debug_beacon.mString == "") { continue; diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index 2a4e6ccf8..3e3b83eab 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -647,6 +647,8 @@ bool LLHUDEffectLookAt::calcTargetPosition() } LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject; + if (!source_avatar->isBuilt()) + return false; if (target_obj && target_obj->mDrawable.notNull()) { diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index a4f0cd655..ab266bd96 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -106,9 +106,9 @@ public: void setZCompare(const BOOL zcompare); void setDoFade(const BOOL do_fade); void setVisibleOffScreen(BOOL visible) { mVisibleOffScreen = visible; } - // - std::string getStringUTF8(); - // + // + std::string getStringUTF8(); + // // mMaxLines of -1 means unlimited lines. void setMaxLines(S32 max_lines) { mMaxLines = max_lines; } diff --git a/indra/newview/llimportobject.cpp b/indra/newview/llimportobject.cpp index 99f874c46..2378ee160 100644 --- a/indra/newview/llimportobject.cpp +++ b/indra/newview/llimportobject.cpp @@ -24,6 +24,7 @@ #include "llfloaterperms.h" #include "llviewerregion.h" #include "llviewerobjectlist.h" +#include "llimagej2c.h" // static vars bool LLXmlImport::sImportInProgress = false; diff --git a/indra/newview/llinventorybackup.cpp b/indra/newview/llinventorybackup.cpp index 70a411be7..5f59c6b6b 100644 --- a/indra/newview/llinventorybackup.cpp +++ b/indra/newview/llinventorybackup.cpp @@ -13,6 +13,7 @@ #include "llfloater.h" #include "lluictrlfactory.h" #include "llscrolllistctrl.h" +#include "llimagetga.h" std::list LLFloaterInventoryBackup::sInstances; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 20732d9e2..328efbd91 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -608,9 +608,11 @@ void LLPanelFace::getState() } } + // planar align bool align_planar = false; bool identical_planar_aligned = false; + bool is_planar = false; { LLCheckBoxCtrl* cb_planar_align = getChild("checkbox planar align"); align_planar = (cb_planar_align && cb_planar_align->get()); @@ -621,13 +623,12 @@ void LLPanelFace::getState() return (object->getTE(face)->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR); } } func; - - bool is_planar; + bool texgens_identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, is_planar ); bool enabled = (editable && texgens_identical && is_planar); childSetValue("checkbox planar align", align_planar && enabled); childSetEnabled("checkbox planar align", enabled); - + if (align_planar && enabled) { struct f2 : public LLSelectedTEGetFunctor diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index ba8ef3eff..3e22474a7 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -110,6 +110,7 @@ const S32 OWNERSHIP_COST_PER_OBJECT = 10; // Must be the same as economy_constan const S32 MAX_ACTION_QUEUE_SIZE = 20; const S32 MAX_SILS_PER_FRAME = 50; const S32 MAX_OBJECTS_PER_PACKET = 254; +const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF; // // Globals @@ -219,6 +220,9 @@ LLSelectMgr::LLSelectMgr() mSelectedObjects = new LLObjectSelection(); mHoverObjects = new LLObjectSelection(); mHighlightedObjects = new LLObjectSelection(); + + mForceSelection = FALSE; + mShowSelection = FALSE; } @@ -551,7 +555,7 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id) object_found = TRUE; break; // must break here, may have removed multiple objects from list } - else if (object->isAvatar()) + else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id) { // It's possible the item being removed has an avatar sitting on it // So remove the avatar that is sitting on the object. @@ -787,41 +791,53 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab LLObjectSelectionHandle LLSelectMgr::setHoverObject(LLViewerObject *objectp, S32 face) { - // Always blitz hover list when setting - mHoverObjects->deleteAllNodes(); - if (!objectp) { + mHoverObjects->deleteAllNodes(); return NULL; } // Can't select yourself if (objectp->mID == gAgentID) { + mHoverObjects->deleteAllNodes(); return NULL; } // Can't select land if (objectp->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH) { + mHoverObjects->deleteAllNodes(); return NULL; } - // Collect all of the objects - LLDynamicArray objects; - objectp = objectp->getRootEdit(); - objectp->addThisAndNonJointChildren(objects); + mHoverObjects->mPrimaryObject = objectp; - for (std::vector::iterator iter = objects.begin(); - iter != objects.end(); ++iter) + objectp = objectp->getRootEdit(); + + // is the requested object the same as the existing hover object root? + // NOTE: there is only ever one linked set in mHoverObjects + if (mHoverObjects->getFirstRootObject() != objectp) { - LLViewerObject* cur_objectp = *iter; - LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE); - nodep->selectTE(face, TRUE); - mHoverObjects->addNodeAtEnd(nodep); + + // Collect all of the objects + LLDynamicArray objects; + objectp = objectp->getRootEdit(); + objectp->addThisAndNonJointChildren(objects); + + mHoverObjects->deleteAllNodes(); + for (std::vector::iterator iter = objects.begin(); + iter != objects.end(); ++iter) + { + LLViewerObject* cur_objectp = *iter; + LLSelectNode* nodep = new LLSelectNode(cur_objectp, FALSE); + nodep->selectTE(face, TRUE); + mHoverObjects->addNodeAtEnd(nodep); + } + + requestObjectPropertiesFamily(objectp); } - requestObjectPropertiesFamily(objectp); return mHoverObjects; } @@ -5059,6 +5075,7 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep) mName = nodep.mName; mDescription = nodep.mDescription; mCategory = nodep.mCategory; + mInventorySerial = 0; mSavedPositionLocal = nodep.mSavedPositionLocal; mSavedPositionGlobal = nodep.mSavedPositionGlobal; mSavedScale = nodep.mSavedScale; @@ -5097,7 +5114,7 @@ LLSelectNode::~LLSelectNode() void LLSelectNode::selectAllTEs(BOOL b) { - mTESelectMask = b ? 0xFFFFFFFF : 0x0; + mTESelectMask = b ? TE_SELECT_MASK_ALL : 0x0; mLastTESelected = 0; } @@ -5732,8 +5749,22 @@ void LLSelectMgr::redo() //----------------------------------------------------------------------------- BOOL LLSelectMgr::canDoDelete() const { + bool can_delete = false; + // This function is "logically const" - it does not change state in + // a way visible outside the selection manager. + LLSelectMgr* self = const_cast(this); + LLViewerObject* obj = self->mSelectedObjects->getFirstDeleteableObject(); // Note: Can only delete root objects (see getFirstDeleteableObject() for more info) - return const_cast(this)->mSelectedObjects->getFirstDeleteableObject() != NULL; // HACK: casting away constness - MG + if (obj!= NULL) + { + // all the faces needs to be selected + if(self->mSelectedObjects->contains(obj,SELECT_ALL_TES )) + { + can_delete = true; + } + } + + return can_delete; } //----------------------------------------------------------------------------- @@ -6136,8 +6167,14 @@ BOOL LLObjectSelection::contains(LLViewerObject* object, S32 te) LLSelectNode* nodep = *iter; if (nodep->getObject() == object) { + // Optimization + if (nodep->getTESelectMask() == TE_SELECT_MASK_ALL) + { + return TRUE; + } + BOOL all_selected = TRUE; - for (S32 i = 0; i < SELECT_MAX_TES; i++) + for (S32 i = 0; i < object->getNumTEs(); i++) { all_selected = all_selected && nodep->isTESelected(i); } diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp index ac7e865de..b6f4dedbd 100644 --- a/indra/newview/llsky.cpp +++ b/indra/newview/llsky.cpp @@ -67,6 +67,9 @@ F32 elevation_from_vector(const LLVector3 &v); LLSky gSky; // ---------------- LLSky ---------------- +const F32 LLSky::NIGHTTIME_ELEVATION = -8.0f; // degrees +const F32 LLSky::NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD); + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h index abd4205e6..d7796dea8 100644 --- a/indra/newview/llsky.h +++ b/indra/newview/llsky.h @@ -42,9 +42,6 @@ #include "llvosky.h" #include "llvoground.h" -const F32 NIGHTTIME_ELEVATION = -8.0f; // degrees -const F32 NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD); - class LLViewerCamera; class LLVOWLSky; @@ -111,6 +108,9 @@ public: // Legacy stuff LLVector3 mSunDefaultPosition; + static const F32 NIGHTTIME_ELEVATION; // degrees + static const F32 NIGHTTIME_ELEVATION_COS; + protected: BOOL mOverrideSimSunPosition; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 1c81d4cdb..63784107b 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -86,7 +86,7 @@ protected: static LLOcclusionQueryPool sQueryPool; -BOOL LLSpatialPartition::sFreezeState = FALSE; +//BOOL LLSpatialPartition::sFreezeState = FALSE; //static counter for frame to switch LOD on @@ -281,10 +281,10 @@ S32 LLSphereAABB(const LLVector3& center, const LLVector3& size, const LLVector3 LLSpatialGroup::~LLSpatialGroup() { - if (sNoDelete) + /*if (sNoDelete) { llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; - } + }*/ if (isState(DEAD)) { @@ -293,12 +293,13 @@ LLSpatialGroup::~LLSpatialGroup() sNodeCount--; - if (gGLManager.mHasOcclusionQuery && mOcclusionQuery) + if (gGLManager.mHasOcclusionQuery && mOcclusionQuery[LLViewerCamera::sCurCameraID]) { - sQueryPool.release(mOcclusionQuery); + sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]); } delete [] mOcclusionVerts; + mOcclusionVerts = NULL; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); clearDrawMap(); @@ -309,17 +310,19 @@ void LLSpatialGroup::clearDrawMap() mDrawMap.clear(); } +BOOL LLSpatialGroup::isRecentlyVisible() const +{ + return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < LLDrawable::getMinVisFrameRange() ; +} + BOOL LLSpatialGroup::isVisible() const { - return mVisible == LLDrawable::getCurrentFrame() ? TRUE : FALSE; + return mVisible[LLViewerCamera::sCurCameraID] == LLDrawable::getCurrentFrame() ? TRUE : FALSE; } void LLSpatialGroup::setVisible() { - if (!LLSpatialPartition::sFreezeState) - { - mVisible = LLDrawable::getCurrentFrame(); - } + mVisible[LLViewerCamera::sCurCameraID] = LLDrawable::getCurrentFrame(); } void LLSpatialGroup::validate() @@ -378,63 +381,6 @@ void LLSpatialGroup::validate() #endif } - - -class LLOctreeStateCheck : public LLOctreeTraveler -{ -public: - U32 mInheritedMask; - - LLOctreeStateCheck(): mInheritedMask(0) { } - - virtual void traverse(const LLSpatialGroup::OctreeNode* node) - { - LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); - - node->accept(this); - - U32 temp = mInheritedMask; - mInheritedMask |= group->getState() & - (LLSpatialGroup::OCCLUDED); - - for (U32 i = 0; i < node->getChildCount(); i++) - { - traverse(node->getChild(i)); - } - - mInheritedMask = temp; - } - - virtual void visit(const LLOctreeNode* state) - { - LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); - - if (mInheritedMask && !group->isState(mInheritedMask)) - { - llerrs << "Spatial group failed inherited mask test." << llendl; - } - - if (group->isState(LLSpatialGroup::DIRTY)) - { - assert_parent_state(group, LLSpatialGroup::DIRTY); - } - } - - void assert_parent_state(LLSpatialGroup* group, U32 state) - { - LLSpatialGroup* parent = group->getParent(); - while (parent) - { - if (!parent->isState(state)) - { - llerrs << "Spatial group failed parent state check." << llendl; - } - parent = parent->getParent(); - } - } -}; - - void LLSpatialGroup::checkStates() { #if LL_OCTREE_PARANOIA_CHECK @@ -468,17 +414,17 @@ void validate_draw_info(LLDrawInfo& params) } //bad indices - U32* indicesp = (U32*) params.mVertexBuffer->getIndicesPointer(); + U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer(); if (indicesp) { for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) { - if (indicesp[i] < params.mStart) + if (indicesp[i] < (U16)params.mStart) { llerrs << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; } - if (indicesp[i] > params.mEnd) + if (indicesp[i] > (U16)params.mEnd) { llerrs << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; } @@ -539,7 +485,9 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc { drawablep->setSpatialGroup(this); validate_drawable(drawablep); - setState(OBJECT_DIRTY | GEOM_DIRTY | DISCARD_QUERY); + setState(OBJECT_DIRTY | GEOM_DIRTY); + setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); + gPipeline.markRebuild(this, TRUE); if (drawablep->isSpatialBridge()) { mBridgeList.push_back((LLSpatialBridge*) drawablep); @@ -572,9 +520,18 @@ void LLSpatialGroup::rebuildMesh() void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - if (!gPipeline.hasRenderType(mDrawableType)) + /*if (!gPipeline.hasRenderType(mDrawableType)) { return; + }*/ + + if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) + { + /*if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && mRenderByGroup) + { + llerrs << "WTF?" << llendl; + }*/ + return; } if (!LLPipeline::sSkipUpdate && group->changeLOD()) @@ -582,12 +539,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->mLastUpdateDistance = group->mDistance; group->mLastUpdateViewAngle = group->mViewAngle; } - - if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) - { - return; - } - + LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); group->clearDrawMap(); @@ -663,8 +615,11 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO drawablep = *i; minMax = drawablep->getSpatialExtents(); + update_min_max(newMin, newMax, minMax[0]); + update_min_max(newMin, newMax, minMax[1]); + //bin up the object - for (U32 i = 0; i < 3; i++) + /*for (U32 i = 0; i < 3; i++) { if (minMax[0].mV[i] < newMin.mV[i]) { @@ -674,7 +629,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO { newMax.mV[i] = minMax[1].mV[i]; } - } + }*/ } mObjectBounds[0] = (newMin + newMax) * 0.5f; @@ -738,6 +693,10 @@ LLSpatialGroup* LLSpatialGroup::getParent() return NULL; } + if(!mOctreeNode) + { + return NULL; + } OctreeNode* parent = mOctreeNode->getOctParent(); if (parent) @@ -763,6 +722,8 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { drawablep->setSpatialGroup(NULL); setState(GEOM_DIRTY); + gPipeline.markRebuild(this, TRUE); + if (drawablep->isSpatialBridge()) { for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i) @@ -799,6 +760,7 @@ void LLSpatialGroup::shift(const LLVector3 &offset) //if (!mSpatialPartition->mRenderByGroup) { setState(GEOM_DIRTY); + gPipeline.markRebuild(this, TRUE); } if (mOcclusionVerts) @@ -816,15 +778,15 @@ void LLSpatialGroup::shift(const LLVector3 &offset) class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler { public: - U32 mState; - LLSpatialSetState(U32 state) : mState(state) { } + LLSpatialGroup::eSpatialState mState; + LLSpatialSetState(LLSpatialGroup::eSpatialState state) : mState(state) { } virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setState(mState); } }; class LLSpatialSetStateDiff : public LLSpatialSetState { public: - LLSpatialSetStateDiff(U32 state) : LLSpatialSetState(state) { } + LLSpatialSetStateDiff(LLSpatialGroup::eSpatialState state) : LLSpatialSetState(state) { } virtual void traverse(const LLSpatialGroup::OctreeNode* n) { @@ -837,20 +799,27 @@ public: } }; -void LLSpatialGroup::setState(U32 state) +void LLSpatialGroup::setState(eSpatialState state) { - if (!LLSpatialPartition::sFreezeState) +// if (LLSpatialPartition::sFreezeState) +// return; + mState |= state; + + if (state > LLSpatialGroup::STATE_MASK) { - mState |= state; - } + llerrs << "WTF?" << llendl; + } } -void LLSpatialGroup::setState(U32 state, S32 mode) +void LLSpatialGroup::setState(eSpatialState state, S32 mode) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - if (LLSpatialPartition::sFreezeState) +// if (LLSpatialPartition::sFreezeState) +// return; + + if (state > LLSpatialGroup::STATE_MASK) { - return; + llerrs << "WTF?" << llendl; } if (mode > STATE_MODE_SINGLE) @@ -875,15 +844,15 @@ void LLSpatialGroup::setState(U32 state, S32 mode) class LLSpatialClearState : public LLSpatialGroup::OctreeTraveler { public: - U32 mState; - LLSpatialClearState(U32 state) : mState(state) { } + LLSpatialGroup::eSpatialState mState; + LLSpatialClearState(LLSpatialGroup::eSpatialState state) : mState(state) { } virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearState(mState); } }; class LLSpatialClearStateDiff : public LLSpatialClearState { public: - LLSpatialClearStateDiff(U32 state) : LLSpatialClearState(state) { } + LLSpatialClearStateDiff(LLSpatialGroup::eSpatialState state) : LLSpatialClearState(state) { } virtual void traverse(const LLSpatialGroup::OctreeNode* n) { @@ -896,22 +865,30 @@ public: } }; -void LLSpatialGroup::clearState(U32 state) +void LLSpatialGroup::clearState(eSpatialState state) { - if (!LLSpatialPartition::sFreezeState) +// if (LLSpatialPartition::sFreezeState) +// return; + if (state > LLSpatialGroup::STATE_MASK) { - mState &= ~state; + llerrs << "WTF?" << llendl; } + + mState &= ~state; } -void LLSpatialGroup::clearState(U32 state, S32 mode) +void LLSpatialGroup::clearState(eSpatialState state, S32 mode) { - LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); - if (LLSpatialPartition::sFreezeState) + +// if (LLSpatialPartition::sFreezeState) +// return; + if (state > LLSpatialGroup::STATE_MASK) { - return; + llerrs << "WTF?" << llendl; } + LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + if (mode > STATE_MODE_SINGLE) { if (mode == STATE_MODE_DIFF) @@ -931,6 +908,128 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) } } +BOOL LLSpatialGroup::isState(eSpatialState state) const +{ + if (state > LLSpatialGroup::STATE_MASK) + { + llerrs << "LLSpatialGroup::isState passed invalid state '" << state << "'" << llendl; + } + + return mState & state ? TRUE : FALSE; +} + +//===================================== +// Occlusion State Set/Clear +//===================================== +class LLSpatialSetOcclusionState : public LLSpatialGroup::OctreeTraveler +{ +public: + LLSpatialGroup::eOcclusionState mState; + LLSpatialSetOcclusionState(LLSpatialGroup::eOcclusionState state) : mState(state) { } + virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->setOcclusionState(mState); } +}; + +class LLSpatialSetOcclusionStateDiff : public LLSpatialSetOcclusionState +{ +public: + LLSpatialSetOcclusionStateDiff(LLSpatialGroup::eOcclusionState state) : LLSpatialSetOcclusionState(state) { } + + virtual void traverse(const LLSpatialGroup::OctreeNode* n) + { + LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); + + if (!group->isOcclusionState(mState)) + { + LLSpatialGroup::OctreeTraveler::traverse(n); + } + } +}; + + +void LLSpatialGroup::setOcclusionState(eOcclusionState state, S32 mode) +{ + LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + + if (mode > STATE_MODE_SINGLE) + { + if (mode == STATE_MODE_DIFF) + { + LLSpatialSetOcclusionStateDiff setter(state); + setter.traverse(mOctreeNode); + } + else if (mode == STATE_MODE_BRANCH) + { + LLSpatialSetOcclusionState setter(state); + setter.traverse(mOctreeNode); + } + else + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionState[i] |= state; + } + } + } + else + { + mOcclusionState[LLViewerCamera::sCurCameraID] |= state; + } +} + +class LLSpatialClearOcclusionState : public LLSpatialGroup::OctreeTraveler +{ +public: + LLSpatialGroup::eOcclusionState mState; + + LLSpatialClearOcclusionState(LLSpatialGroup::eOcclusionState state) : mState(state) { } + virtual void visit(const LLSpatialGroup::OctreeNode* branch) { ((LLSpatialGroup*) branch->getListener(0))->clearOcclusionState(mState); } +}; + +class LLSpatialClearOcclusionStateDiff : public LLSpatialClearOcclusionState +{ +public: + LLSpatialClearOcclusionStateDiff(LLSpatialGroup::eOcclusionState state) : LLSpatialClearOcclusionState(state) { } + + virtual void traverse(const LLSpatialGroup::OctreeNode* n) + { + LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); + + if (group->isOcclusionState(mState)) + { + LLSpatialGroup::OctreeTraveler::traverse(n); + } + } +}; + +void LLSpatialGroup::clearOcclusionState(eOcclusionState state, S32 mode) +{ + LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); + + if (mode > STATE_MODE_SINGLE) + { + if (mode == STATE_MODE_DIFF) + { + LLSpatialClearOcclusionStateDiff clearer(state); + clearer.traverse(mOctreeNode); + } + else if (mode == STATE_MODE_BRANCH) + { + LLSpatialClearOcclusionState clearer(state); + clearer.traverse(mOctreeNode); + } + else + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionState[i] &= ~state; + } + } + } + else + { + mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state; + } +} //====================================== // Octree Listener Implementation //====================================== @@ -942,7 +1041,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mSpatialPartition(part), mVertexBuffer(NULL), mBufferUsage(GL_STATIC_DRAW_ARB), - mVisible(0), mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), @@ -956,6 +1054,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : sg_assert(mOctreeNode->getListenerCount() == 0); mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); + gPipeline.markRebuild(this, TRUE); mBounds[0] = LLVector3(node->getCenter()); mBounds[1] = LLVector3(node->getSize()); @@ -963,7 +1062,16 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; mLODHash = part->mLODSeed; - mOcclusionQuery = 0; + OctreeNode* oct_parent = node->getOctParent(); + + LLSpatialGroup* parent = oct_parent ? (LLSpatialGroup*) oct_parent->getListener(0) : NULL; + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mOcclusionQuery[i] = 0; + mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0; + mVisible[i] = 0; + } mOcclusionVerts = NULL; mRadius = 1; @@ -972,13 +1080,18 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : void LLSpatialGroup::updateDistance(LLCamera &camera) { + if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) + { + llerrs << "WTF?" << llendl; + } + #if !LL_RELEASE_FOR_DOWNLOAD if (isState(LLSpatialGroup::OBJECT_DIRTY)) { llerrs << "Spatial group dirty on distance update." << llendl; } #endif - if (!getData().empty() && !LLSpatialPartition::sFreezeState) + if (!getData().empty() /*&& !LLSpatialPartition::sFreezeState*/) { mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() : (F32) mOctreeNode->getSize().magVec(); @@ -1014,6 +1127,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, //not setting this node to dirty would be a very good thing group->setState(LLSpatialGroup::ALPHA_DIRTY); + gPipeline.markRebuild(group, FALSE); } } } @@ -1050,6 +1164,18 @@ F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); } +F32 LLSpatialGroup::getUpdateUrgency() const +{ + if (!isVisible()) + { + return 0.f; + } + else + { + return (gFrameTimeSeconds - mLastUpdateTime+4.f)/mDistance; + } +} + BOOL LLSpatialGroup::needsUpdate() { return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; @@ -1136,8 +1262,7 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); if (child->getListenerCount() == 0) { - LLSpatialGroup* group = new LLSpatialGroup(child, mSpatialPartition); - group->setState(mState & SG_STATE_INHERIT_MASK); + new LLSpatialGroup(child, mSpatialPartition); } else { @@ -1157,16 +1282,20 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo void LLSpatialGroup::destroyGL() { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); + gPipeline.markRebuild(this, TRUE); mLastUpdateTime = gFrameTimeSeconds; mVertexBuffer = NULL; mBufferMap.clear(); clearDrawMap(); - if (mOcclusionQuery) + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) { - sQueryPool.release(mOcclusionQuery); - mOcclusionQuery = 0; + if (mOcclusionQuery[i]) + { + sQueryPool.release(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; + } } delete [] mOcclusionVerts; @@ -1260,39 +1389,44 @@ void LLSpatialGroup::checkOcclusion() { if (LLPipeline::sUseOcclusion > 1) { + LLFastTimer t( LLFastTimer::FTM_OCCLUSION_READBACK); LLSpatialGroup* parent = getParent(); - if (parent && parent->isState(LLSpatialGroup::OCCLUDED)) + if (parent && parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) { //if the parent has been marked as occluded, the child is implicitly occluded - clearState(QUERY_PENDING | DISCARD_QUERY); + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); } - else if (isState(QUERY_PENDING)) + else if (isOcclusionState(QUERY_PENDING)) { //otherwise, if a query is pending, read it back - LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); GLuint res = 1; - if (!isState(DISCARD_QUERY) && mOcclusionQuery) + if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID]) { - glGetQueryObjectuivARB(mOcclusionQuery, GL_QUERY_RESULT_ARB, &res); + glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res); + } + + if (isOcclusionState(DISCARD_QUERY)) + { + res = 2; } if (res > 0) { assert_states_valid(this); - clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); assert_states_valid(this); } else { assert_states_valid(this); - setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); assert_states_valid(this); } - clearState(QUERY_PENDING | DISCARD_QUERY); + clearOcclusionState(QUERY_PENDING | DISCARD_QUERY); } - else if (mSpatialPartition->isOcclusionEnabled() && isState(LLSpatialGroup::OCCLUDED)) + else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLSpatialGroup::OCCLUDED)) { //check occlusion has been issued for occluded node that has not had a query issued assert_states_valid(this); - clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); assert_states_valid(this); } } @@ -1302,15 +1436,14 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) { - static const LLCachedControl render_water_void_culling("RenderWaterVoidCulling", TRUE); + //static const LLCachedControl render_water_void_culling("RenderWaterVoidCulling", TRUE); // Don't cull hole/edge water, unless RenderWaterVoidCulling is set and we have the GL_ARB_depth_clamp extension. - if ((mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER && - !(render_water_void_culling && gGLManager.mHasDepthClamp)) || - earlyFail(camera, this)) + if ((mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER && !gGLManager.mHasDepthClamp) || + earlyFail(camera, this)) { - setState(LLSpatialGroup::DISCARD_QUERY); + setOcclusionState(LLSpatialGroup::DISCARD_QUERY); assert_states_valid(this); - clearState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); + clearOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); assert_states_valid(this); } else @@ -1318,9 +1451,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) { LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); - if (!mOcclusionQuery) + if (!mOcclusionQuery[LLViewerCamera::sCurCameraID]) { - mOcclusionQuery = sQueryPool.allocate(); + mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate(); } if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY)) @@ -1331,19 +1464,28 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) // 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 == LLPipeline::RENDER_TYPE_WATER || - mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER); + 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); + + glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery[LLViewerCamera::sCurCameraID]); glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); - glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); + 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) @@ -1352,15 +1494,16 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) } } - setState(LLSpatialGroup::QUERY_PENDING); - clearState(LLSpatialGroup::DISCARD_QUERY); + setOcclusionState(LLSpatialGroup::QUERY_PENDING); + clearOcclusionState(LLSpatialGroup::DISCARD_QUERY); } } } //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) +: mRenderByGroup(render_by_group) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); mOcclusionEnabled = TRUE; @@ -1372,7 +1515,6 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) mBufferUsage = buffer_usage; mDepthMask = FALSE; mSlopRatio = 0.25f; - mRenderByGroup = TRUE; mInfiniteFarClip = FALSE; LLGLNamePool::registerPool(&sQueryPool); @@ -1409,9 +1551,9 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) LLSpatialGroup* group = drawablep->getSpatialGroup(); - if (group && was_visible && group->isState(LLSpatialGroup::QUERY_PENDING)) + if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING)) { - group->setState(LLSpatialGroup::DISCARD_QUERY); + group->setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS); } return group; @@ -1510,7 +1652,7 @@ public: if (group->mOctreeNode->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled - group->isState(LLSpatialGroup::OCCLUDED)) + group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { gPipeline.markOccluder(group); return true; @@ -1592,7 +1734,7 @@ public: virtual void processGroup(LLSpatialGroup* group) { if (group->needsUpdate() || - group->mVisible < LLDrawable::getCurrentFrame() - 1) + group->mVisible[LLViewerCamera::sCurCameraID] < LLDrawable::getCurrentFrame() - 1) { group->doOcclusion(mCamera); } @@ -1660,7 +1802,7 @@ public: { if (group->mOctreeNode->getParent() && //never occlusion cull the root node LLPipeline::sUseOcclusion && //ignore occlusion if disabled - group->isState(LLSpatialGroup::OCCLUDED)) + group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { return true; } @@ -1668,13 +1810,54 @@ public: return false; } + virtual void traverse(const LLSpatialGroup::OctreeNode* n) + { + LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); + + if (earlyFail(group)) + { + return; + } + + if ((mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || + mRes == 2) + { //don't need to do frustum check + LLSpatialGroup::OctreeTraveler::traverse(n); + } + else + { + mRes = frustumCheck(group); + + if (mRes) + { //at least partially in, run on down + LLSpatialGroup::OctreeTraveler::traverse(n); + } + + mRes = 0; + } + } + virtual void processGroup(LLSpatialGroup* group) { - if (group->mObjectBounds[1].magVecSquared() < 256.f * 256.f) - { //megaprims and water edge patches be damned! + if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) + { + llerrs << "WTF?" << llendl; + } + + if (mRes < 2) + { + if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0) + { + mEmpty = FALSE; + update_min_max(mMin, mMax, group->mObjectExtents[0]); + update_min_max(mMin, mMax, group->mObjectExtents[1]); + } + } + else + { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mObjectExtents[0]); - update_min_max(mMin, mMax, group->mObjectExtents[1]); + update_min_max(mMin, mMax, group->mExtents[0]); + update_min_max(mMin, mMax, group->mExtents[1]); } } @@ -1693,8 +1876,8 @@ public: { if (mResult || //already found a node, don't check any more (group->mOctreeNode->getParent() && //never occlusion cull the root node - LLPipeline::sUseOcclusion && //ignore occlusion if disabled - group->isState(LLSpatialGroup::OCCLUDED))) + LLPipeline::sUseOcclusion && //ignore occlusion if disabled + group->isOcclusionState(LLSpatialGroup::OCCLUDED))) { return true; } @@ -1873,6 +2056,11 @@ BOOL LLSpatialPartition::isOcclusionEnabled() BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax) { + { + LLFastTimer ftm( LLFastTimer::FTM_CULL_REBOUND); + LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); + group->rebound(); + } LLOctreeCullVisExtents vis(&camera, visMin, visMax); vis.traverse(mOctree); return vis.mEmpty; @@ -1892,12 +2080,12 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result ((LLSpatialGroup*)mOctree->getListener(0))->checkStates(); #endif { - BOOL temp = sFreezeState; - sFreezeState = FALSE; + //BOOL temp = sFreezeState; + //sFreezeState = FALSE; LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); group->rebound(); - sFreezeState = temp; + //sFreezeState = temp; } #if LL_OCTREE_PARANOIA_CHECK @@ -1934,6 +2122,11 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) { + if (camera->getOrigin().isExactlyZero()) + { + return FALSE; + } + const F32 vel = SG_OCCLUSION_FUDGE*2.f; LLVector3 c = group->mBounds[0]; LLVector3 r = group->mBounds[1] + LLVector3(vel,vel,vel); @@ -2161,7 +2354,6 @@ void renderOctree(LLSpatialGroup* group) gGL.color4fv(col.mV); drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); - glDepthMask(GL_TRUE); gGL.setSceneBlendType(LLRender::BT_ALPHA); if (group->mBuilt <= 0.f) @@ -2211,7 +2403,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera) LLGLEnable cull(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && + BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() && !group->getData().empty(); if (render_objects) { @@ -2270,6 +2462,49 @@ void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color) gGL.end(); } +void renderUpdateType(LLDrawable* drawablep) +{ + LLViewerObject* vobj = drawablep->getVObj(); + if (!vobj || OUT_UNKNOWN == vobj->getLastUpdateType()) + { + return; + } + LLGLEnable blend(GL_BLEND); + switch (vobj->getLastUpdateType()) + { + case OUT_FULL: + glColor4f(0,1,0,0.5f); + break; + case OUT_TERSE_IMPROVED: + glColor4f(0,1,1,0.5f); + break; + case OUT_FULL_COMPRESSED: + if (vobj->getLastUpdateCached()) + { + glColor4f(1,0,0,0.5f); + } + else + { + glColor4f(1,1,0,0.5f); + } + break; + case OUT_FULL_CACHED: + glColor4f(0,0,1,0.5f); + break; + default: + llwarns << "Unknown update_type " << vobj->getLastUpdateType() << llendl; + break; + }; + S32 num_faces = drawablep->getNumFaces(); + if (num_faces) + { + for (S32 i = 0; i < num_faces; ++i) + { + pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); + } + } +} + void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) { @@ -2310,6 +2545,7 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) break; case LL_PCODE_LEGACY_TREE: gGL.color4f(0,0.5f,0,1); + break; default: gGL.color4f(1,0,1,1); break; @@ -2587,6 +2823,9 @@ public: //draw tight fit bounding boxes for spatial group if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) { + group->rebuildGeom(); + group->rebuildMesh(); + renderOctree(group); stop_glerror(); } @@ -2594,6 +2833,9 @@ public: //render visibility wireframe if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { + group->rebuildGeom(); + group->rebuildMesh(); + gGL.flush(); glPushMatrix(); gGLLastMatrix = NULL; @@ -2619,6 +2861,19 @@ public: LLVector3 nodeCenter = group->mBounds[0]; LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); + group->rebuildGeom(); + group->rebuildMesh(); + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) + { + if (!group->getData().empty()) + { + gGL.color3f(0,0,1); + drawBoxOutline(group->mObjectBounds[0], + group->mObjectBounds[1]); + } + } + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) { LLDrawable* drawable = *i; @@ -2726,6 +2981,79 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) pusher.traverse(mOctree); } +class LLOctreeStateCheck : public LLOctreeTraveler +{ +public: + U32 mInheritedMask[LLViewerCamera::NUM_CAMERAS]; + + LLOctreeStateCheck() + { + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mInheritedMask[i] = 0; + } + } + + virtual void traverse(const LLSpatialGroup::OctreeNode* node) + { + LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); + + node->accept(this); + + + U32 temp[LLViewerCamera::NUM_CAMERAS]; + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + temp[i] = mInheritedMask[i]; + mInheritedMask[i] |= group->mOcclusionState[i] & LLSpatialGroup::OCCLUDED; + } + + for (U32 i = 0; i < node->getChildCount(); i++) + { + traverse(node->getChild(i)); + } + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + mInheritedMask[i] = temp[i]; + } + } + + + virtual void visit(const LLOctreeNode* state) + { + LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); + + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++) + { + if (mInheritedMask[i] && !(group->mOcclusionState[i] & mInheritedMask[i])) + { + llerrs << "Spatial group failed inherited mask test." << llendl; + } + } + + if (group->isState(LLSpatialGroup::DIRTY)) + { + assert_parent_state(group, LLSpatialGroup::DIRTY); + } + } + + void assert_parent_state(LLSpatialGroup* group, LLSpatialGroup::eSpatialState state) + { + LLSpatialGroup* parent = group->getParent(); + while (parent) + { + if (!parent->isState(state)) + { + llerrs << "Spatial group failed parent state check." << llendl; + } + parent = parent->getParent(); + } + } +}; + + void LLSpatialPartition::renderDebug() { if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | @@ -2773,6 +3101,12 @@ void LLSpatialPartition::renderDebug() render_debug.traverse(mOctree); } +void LLSpatialGroup::drawObjectBox(LLColor4 col) +{ + gGL.color4fv(col.mV); + drawBox(mObjectBounds[0], mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); +} + BOOL LLSpatialPartition::isVisible(const LLVector3& v) { @@ -2953,10 +3287,10 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, LLDrawInfo::~LLDrawInfo() { - if (LLSpatialGroup::sNoDelete) + /*if (LLSpatialGroup::sNoDelete) { llerrs << "LLDrawInfo deleted illegally!" << llendl; - } + }*/ if (mFace) { @@ -2977,11 +3311,22 @@ LLCullResult::LLCullResult() void LLCullResult::clear() { mVisibleGroupsSize = 0; + mVisibleGroupsEnd = mVisibleGroups.begin(); + mAlphaGroupsSize = 0; + mAlphaGroupsEnd = mAlphaGroups.begin(); + mOcclusionGroupsSize = 0; + mOcclusionGroupsEnd = mOcclusionGroups.begin(); + mDrawableGroupsSize = 0; + mDrawableGroupsEnd = mDrawableGroups.begin(); + mVisibleListSize = 0; + mVisibleListEnd = mVisibleList.begin(); + mVisibleBridgeSize = 0; + mVisibleBridgeEnd = mVisibleBridge.begin(); for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++) { @@ -2990,6 +3335,7 @@ void LLCullResult::clear() mRenderMap[i][j] = 0; } mRenderMapSize[i] = 0; + mRenderMapEnd[i] = mRenderMap[i].begin(); } } @@ -3000,7 +3346,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups() LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups() { - return mVisibleGroups.begin() + mVisibleGroupsSize; + return mVisibleGroupsEnd; } LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() @@ -3010,7 +3356,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups() { - return mAlphaGroups.begin() + mAlphaGroupsSize; + return mAlphaGroupsEnd; } LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() @@ -3020,7 +3366,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups() { - return mOcclusionGroups.begin() + mOcclusionGroupsSize; + return mOcclusionGroupsEnd; } LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() @@ -3030,7 +3376,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups() { - return mDrawableGroups.begin() + mDrawableGroupsSize; + return mDrawableGroupsEnd; } LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() @@ -3040,7 +3386,7 @@ LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList() { - return mVisibleList.begin() + mVisibleListSize; + return mVisibleListEnd; } LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() @@ -3050,7 +3396,7 @@ LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge() { - return mVisibleBridge.begin() + mVisibleBridgeSize; + return mVisibleBridgeEnd; } LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) @@ -3060,7 +3406,7 @@ LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type) { - return mRenderMap[type].begin() + mRenderMapSize[type]; + return mRenderMapEnd[type]; } void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) @@ -3074,6 +3420,7 @@ void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) mVisibleGroups.push_back(group); } ++mVisibleGroupsSize; + mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize; } void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) @@ -3087,6 +3434,7 @@ void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) mAlphaGroups.push_back(group); } ++mAlphaGroupsSize; + mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize; } void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) @@ -3100,6 +3448,7 @@ void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) mOcclusionGroups.push_back(group); } ++mOcclusionGroupsSize; + mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize; } void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) @@ -3113,6 +3462,7 @@ void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) mDrawableGroups.push_back(group); } ++mDrawableGroupsSize; + mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize; } void LLCullResult::pushDrawable(LLDrawable* drawable) @@ -3126,6 +3476,7 @@ void LLCullResult::pushDrawable(LLDrawable* drawable) mVisibleList.push_back(drawable); } ++mVisibleListSize; + mVisibleListEnd = mVisibleList.begin()+mVisibleListSize; } void LLCullResult::pushBridge(LLSpatialBridge* bridge) @@ -3139,6 +3490,7 @@ void LLCullResult::pushBridge(LLSpatialBridge* bridge) mVisibleBridge.push_back(bridge); } ++mVisibleBridgeSize; + mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize; } void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) @@ -3152,6 +3504,7 @@ void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) mRenderMap[type].push_back(draw_info); } ++mRenderMapSize[type]; + mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type]; } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index be0163b2b..ebab60e49 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -43,6 +43,7 @@ #include "llcubemap.h" #include "lldrawpool.h" #include "llface.h" +#include "llviewercamera.h" #include @@ -153,12 +154,12 @@ public: class LLSpatialGroup : public LLOctreeListener { friend class LLSpatialPartition; + friend class LLOctreeStateCheck; public: static U32 sNodeCount; static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE typedef std::vector > sg_vector_t; - typedef std::set > sg_set_t; typedef std::vector > bridge_list_t; typedef std::vector > drawmap_elem_t; typedef std::map draw_map_t; @@ -183,6 +184,14 @@ public: } }; + struct CompareUpdateUrgency + { + bool operator()(const LLPointer lhs, const LLPointer rhs) + { + return lhs->getUpdateUrgency() > rhs->getUpdateUrgency(); + } + }; + struct CompareDepthGreater { bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs) @@ -193,53 +202,67 @@ public: typedef enum { - OCCLUDED = 0x00000001, - IN_QUEUE = 0x00000002, - QUERY_PENDING = 0x00000004, - ACTIVE_OCCLUSION = 0x00000008, - DISCARD_QUERY = 0x00000010, - DEAD = 0x00000020, - EARLY_FAIL = 0x00000040, - DIRTY = 0x00000080, - OBJECT_DIRTY = 0x00000100, - GEOM_DIRTY = 0x00000200, - ALPHA_DIRTY = 0x00000800, - SKIP_FRUSTUM_CHECK = 0x00001000, - IN_IMAGE_QUEUE = 0x00002000, - IMAGE_DIRTY = 0x00004000, - OCCLUSION_DIRTY = 0x00008000, - MESH_DIRTY = 0x00010000, + OCCLUDED = 0x00010000, + QUERY_PENDING = 0x00020000, + ACTIVE_OCCLUSION = 0x00040000, + DISCARD_QUERY = 0x00080000, + EARLY_FAIL = 0x00100000, + } eOcclusionState; + + typedef enum + { + DEAD = 0x00000001, + DIRTY = 0x00000002, + OBJECT_DIRTY = 0x00000004, + GEOM_DIRTY = 0x00000008, + ALPHA_DIRTY = 0x00000010, + SKIP_FRUSTUM_CHECK = 0x00000020, + IN_IMAGE_QUEUE = 0x00000040, + IMAGE_DIRTY = 0x00000080, + OCCLUSION_DIRTY = 0x00000100, + MESH_DIRTY = 0x00000200, + NEW_DRAWINFO = 0x00000400, + IN_BUILD_Q1 = 0x00000800, + IN_BUILD_Q2 = 0x00001000, + STATE_MASK = 0x0000FFFF, } eSpatialState; typedef enum { STATE_MODE_SINGLE = 0, //set one node STATE_MODE_BRANCH, //set entire branch - STATE_MODE_DIFF //set entire branch as long as current state is different + STATE_MODE_DIFF, //set entire branch as long as current state is different + STATE_MODE_ALL_CAMERAS, //used for occlusion state, set state for all cameras } eSetStateMode; LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part); BOOL isDead() { return isState(DEAD); } - BOOL isState(U32 state) const { return mState & state ? TRUE : FALSE; } + BOOL isState(eSpatialState state) const; //Using enum type here and below to force type-safeness. + BOOL isOcclusionState(eOcclusionState state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; } U32 getState() { return mState; } - void setState(U32 state); - void clearState(U32 state); + void setState(eSpatialState state); + void clearState(eSpatialState state); void clearDrawMap(); void validate(); void checkStates(); void validateDrawMap(); - void setState(U32 state, S32 mode); + void setState(eSpatialState state, S32 mode); + void clearState(eSpatialState state, S32 mode); + + void setOcclusionState(eOcclusionState state, S32 mode = STATE_MODE_SINGLE); + void clearOcclusionState(eOcclusionState state, S32 mode = STATE_MODE_SINGLE); LLSpatialGroup* getParent(); - void clearState(U32 state, S32 mode); + BOOL addObject(LLDrawable *drawablep, BOOL add_all = FALSE, BOOL from_octree = FALSE); BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE); BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group BOOL isVisible() const; + BOOL isRecentlyVisible() const; void setVisible(); void shift(const LLVector3 &offset); BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax); @@ -252,6 +275,7 @@ public: void updateDistance(LLCamera& camera); BOOL needsUpdate(); + F32 getUpdateUrgency() const; BOOL changeLOD(); void rebuildGeom(); void rebuildMesh(); @@ -261,6 +285,8 @@ public: element_list& getData() { return mOctreeNode->getData(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } + void drawObjectBox(LLColor4 col); + //LISTENER FUNCTIONS virtual void handleInsertion(const TreeNode* node, LLDrawable* face); virtual void handleRemoval(const TreeNode* node, LLDrawable* face); @@ -273,6 +299,7 @@ protected: virtual ~LLSpatialGroup(); U32 mState; + U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS]; S32 mLODHash; static S32 sLODSeed; @@ -291,12 +318,12 @@ public: LLPointer mVertexBuffer; F32* mOcclusionVerts; - GLuint mOcclusionQuery; + GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS]; U32 mBufferUsage; draw_map_t mDrawMap; - S32 mVisible; + S32 mVisible[LLViewerCamera::NUM_CAMERAS]; F32 mDistance; F32 mDepth; F32 mLastUpdateDistance; @@ -309,6 +336,15 @@ public: F32 mRadius; }; +inline LLSpatialGroup::eOcclusionState operator|(const LLSpatialGroup::eOcclusionState &a, const LLSpatialGroup::eOcclusionState &b) +{ + return LLSpatialGroup::eOcclusionState(+a | +b); +} +inline LLSpatialGroup::eSpatialState operator|(const LLSpatialGroup::eSpatialState &a, const LLSpatialGroup::eSpatialState &b) +{ + return LLSpatialGroup::eSpatialState(+a | +b); +} + class LLGeometryManager { public: @@ -325,9 +361,8 @@ public: class LLSpatialPartition: public LLGeometryManager { public: - static BOOL sFreezeState; //if true, no spatialgroup state updates will be made - - LLSpatialPartition(U32 data_mask, U32 mBufferUsage = GL_STATIC_DRAW_ARB); + //static BOOL sFreezeState; //if true, no spatialgroup state updates will be made + LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage); virtual ~LLSpatialPartition(); LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -392,7 +427,7 @@ protected: public: typedef std::vector > bridge_vector_t; - LLSpatialBridge(LLDrawable* root, U32 data_mask); + LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); virtual BOOL isSpatialBridge() const { return TRUE; } @@ -473,14 +508,22 @@ private: U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES]; sg_list_t mVisibleGroups; + sg_list_t::iterator mVisibleGroupsEnd; sg_list_t mAlphaGroups; + sg_list_t::iterator mAlphaGroupsEnd; sg_list_t mOcclusionGroups; + sg_list_t::iterator mOcclusionGroupsEnd; sg_list_t mDrawableGroups; + sg_list_t::iterator mDrawableGroupsEnd; drawable_list_t mVisibleList; + drawable_list_t::iterator mVisibleListEnd; bridge_list_t mVisibleBridge; + bridge_list_t::iterator mVisibleBridgeEnd; drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; + drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES]; }; + //spatial partition for water (implemented in LLVOWater.cpp) class LLWaterPartition : public LLSpatialPartition { diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 9224cb5b0..7df058e40 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1322,6 +1322,7 @@ bool idle_startup() hashed_mac_string, LLAppViewer::instance()->getSerialNumber()); + gAuthString = hashed_mac_string; // reset globals gAcceptTOS = FALSE; diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index caaba056d..f8cf9e57e 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -160,6 +160,7 @@ void LLSurface::initClasses() void LLSurface::setRegion(LLViewerRegion *regionp) { mRegionp = regionp; + mWaterObjp = NULL; // depends on regionp, needs recreating } // Assumes that arguments are powers of 2, and that @@ -1282,6 +1283,10 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, } } + if (!mWaterTexturep->getHasGLTexture()) + { + mWaterTexturep->createGLTexture(0, raw); + } mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin); return TRUE; } diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 5fac5fd1e..48e4a6ccc 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -60,6 +60,7 @@ LLSurfacePatch::LLSurfacePatch() : mHeightsGenerated(FALSE), mDataOffset(0), mDataZ(NULL), + mDataNorm(NULL), mVObjp(NULL), mOriginRegion(0.f, 0.f, 0.f), mCenterRegion(0.f, 0.f, 0.f), @@ -355,12 +356,14 @@ void LLSurfacePatch::calcNormal(const U32 x, const U32 y, const U32 stride) normal %= c2; normal.normVec(); + llassert(mDataNorm); *(mDataNorm + surface_stride * y + x) = normal; } const LLVector3 &LLSurfacePatch::getNormal(const U32 x, const U32 y) const { U32 surface_stride = mSurfacep->getGridsPerEdge(); + llassert(mDataNorm); return *(mDataNorm + surface_stride * y + x); } @@ -402,6 +405,7 @@ void LLSurfacePatch::updateVerticalStats() U32 i, j, k; F32 z, total; + llassert(mDataZ); z = *(mDataZ); mMinZ = z; @@ -712,17 +716,7 @@ BOOL LLSurfacePatch::updateTexture() if (mVObjp) { mVObjp->dirtyGeom(); - } - updateCompositionStats(); - F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; - if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], - tex_patch_size, tex_patch_size)) - { - mSTexUpdate = FALSE; - - // Also generate the water texture - mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], - tex_patch_size, tex_patch_size); + gPipeline.markGLRebuild(mVObjp); return TRUE; } } @@ -735,6 +729,28 @@ BOOL LLSurfacePatch::updateTexture() } } +void LLSurfacePatch::updateGL() +{ + F32 meters_per_grid = getSurface()->getMetersPerGrid(); + F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); + + LLViewerRegion *regionp = getSurface()->getRegion(); + LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); + + LLVLComposition* comp = regionp->getComposition(); + + updateCompositionStats(); + F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; + if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], + tex_patch_size, tex_patch_size)) + { + mSTexUpdate = FALSE; + + // Also generate the water texture + mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], + tex_patch_size, tex_patch_size); + } +} void LLSurfacePatch::dirtyZ() { diff --git a/indra/newview/llsurfacepatch.h b/indra/newview/llsurfacepatch.h index 7e84f7f6c..1f9658d4a 100644 --- a/indra/newview/llsurfacepatch.h +++ b/indra/newview/llsurfacepatch.h @@ -90,6 +90,7 @@ public: void updateCameraDistanceRegion( const LLVector3 &pos_region); void updateVisibility(); + void updateGL(); void dirtyZ(); // Dirty the z values of this patch void setHasReceivedData(); diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 8ccd47066..8873821ef 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1420,22 +1420,21 @@ void LLTextureCache::readHeaderCache() } } } - if (num_entries > sCacheMaxEntries) + if (num_entries - empty_entries > sCacheMaxEntries) { // Special case: cache size was reduced, need to remove entries // Note: After we prune entries, we will call this again and create the LRU U32 entries_to_purge = (num_entries-empty_entries) - sCacheMaxEntries; llinfos << "Texture Cache Entries: " << num_entries << " Max: " << sCacheMaxEntries << " Empty: " << empty_entries << " Purging: " << entries_to_purge << llendl; - if (entries_to_purge > 0) + // We can exit the following loop with the given condition, since if we'd reach the end of the lru set we'd have: + // purge_list.size() = lru.size() = num_entries - empty_entries = entries_to_purge + sCacheMaxEntries >= entries_to_purge + // So, it's certain that iter will never reach lru.end() first. + std::set::iterator iter = lru.begin(); + while (purge_list.size() < entries_to_purge) { - for (std::set::iterator iter = lru.begin(); iter != lru.end(); ++iter) - { - purge_list.insert(iter->second); - if (purge_list.size() >= entries_to_purge) - break; - } + purge_list.insert(iter->second); + ++iter; } - llassert_always(purge_list.size() >= entries_to_purge); } else { diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index d7577ac67..150a75ea8 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -302,7 +302,10 @@ public: const LLChannelDescriptors& channels, const LLIOPipe::buffer_ptr_t& buffer) { - if ((gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog")) || (gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"))) + static LLCachedControl log_to_viewer_log("LogTextureDownloadsToViewerLog",false); + static LLCachedControl log_to_sim("LogTextureDownloadsToSimulator",false); + + if (log_to_viewer_log || log_to_sim) { mFetcher->mTextureInfo.setRequestStartTime(mID, mStartTime); U64 timeNow = LLTimer::getTotalTime(); @@ -2127,7 +2130,9 @@ void LLTextureFetch::sendRequestListToSimulators() // llinfos << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard // << " Packet: " << packet << " Priority: " << req->mImagePriority << llendl; - if ((gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog")) || (gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"))) + static LLCachedControl log_to_viewer_log("LogTextureDownloadsToViewerLog",false); + static LLCachedControl log_to_sim("LogTextureDownloadsToSimulator",false); + if (log_to_viewer_log || log_to_sim) { mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime()); mTextureInfo.setRequestOffset(req->mID, 0); @@ -2347,7 +2352,10 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 if(packet_num >= (worker->mTotalPackets - 1)) { - if ((gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog")) || (gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"))) + static LLCachedControl log_to_viewer_log("LogTextureDownloadsToViewerLog",false); + static LLCachedControl log_to_sim("LogTextureDownloadsToSimulator",false); + + if (log_to_viewer_log || log_to_sim) { U64 timeNow = LLTimer::getTotalTime(); mTextureInfo.setRequestSize(id, worker->mFileSize); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index dade65f1a..260c6e253 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -51,6 +51,8 @@ #include "lltoolmgr.h" #include "llviewerjoystick.h" +U32 LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; + //glu pick matrix implementation borrowed from Mesa3D glh::matrix4f gl_pick_matrix(GLfloat x, GLfloat y, GLfloat width, GLfloat height, GLint* viewport) { diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index d25d063a5..1fcda6362 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -54,6 +54,24 @@ const BOOL NOT_FOR_SELECTION = FALSE; class LLViewerCamera : public LLCamera, public LLSingleton { public: + + typedef enum + { + CAMERA_WORLD = 0, + CAMERA_SHADOW0, + CAMERA_SHADOW1, + CAMERA_SHADOW2, + CAMERA_SHADOW3, + CAMERA_SHADOW4, + CAMERA_SHADOW5, + CAMERA_WATER0, + CAMERA_WATER1, + CAMERA_GI_SOURCE, + NUM_CAMERAS + } eCameraID; + + static U32 sCurCameraID; + LLViewerCamera(); void updateCameraLocation(const LLVector3 ¢er, diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index b201fb877..089f52af8 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -356,6 +356,15 @@ static bool handleRenderUseVBOChanged(const LLSD& newvalue) return true; } +static bool handleRenderUseVBOMappingChanged(const LLSD& newvalue) +{ + if (gPipeline.isInit()) + { + gPipeline.setDisableVBOMapping(newvalue.asBoolean()); + } + return true; +} + static bool handleWLSkyDetailChanged(const LLSD&) { if (gSky.mVOWLSkyp.notNull()) @@ -602,6 +611,7 @@ void settings_setup_listeners() gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _1)); + gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleRenderUseVBOMappingChanged, _1)); gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _1)); gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _1)); gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _1)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 0f8efb23b..765329cdc 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -131,6 +131,7 @@ void display_startup() return; } + gPipeline.updateGL(); LLGLSDefault gls_default; // Required for HTML update in login screen @@ -241,6 +242,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(LLFastTimer::FTM_RENDER); + if (LLPipeline::sRenderDeferred) + { //hack to make sky show up in deferred snapshots + for_snapshot = FALSE; + } + if (LLPipeline::sRenderFrameTest) { send_agent_pause(); @@ -614,6 +620,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); gPipeline.updateGeom(max_geom_update_time); + gPipeline.updateGL(); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_CULL); @@ -666,6 +673,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLGLState::checkClientArrays(); static LLCullResult result; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip); stop_glerror(); @@ -706,6 +714,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } + LLVertexBuffer::unbind(); + LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); @@ -781,7 +791,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) // LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); { + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gFrameStats.start(LLFrameStats::STATE_SORT); + gPipeline.sAllowRebuildPriorityGroup = TRUE ; gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); @@ -866,6 +878,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.bindTarget(); + glClearColor(0,0,0,0); gPipeline.mDeferredScreen.clear(); } else @@ -882,7 +895,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL) { - + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gGL.setColorMask(true, false); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { @@ -932,6 +945,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) render_ui(); } + gPipeline.rebuildGroups(); + LLSpatialGroup::sNoDelete = FALSE; } @@ -980,9 +995,10 @@ void render_hud_attachments() bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles"); //only render hud objects - U32 mask = gPipeline.getRenderTypeMask(); + gPipeline.pushRenderTypeMask(); + // turn off everything - gPipeline.setRenderTypeMask(0); + gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES); // turn on HUD gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); // turn on HUD particles @@ -1009,6 +1025,7 @@ void render_hud_attachments() static LLCullResult result; LLSpatialGroup::sNoDelete = TRUE; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gPipeline.updateCull(hud_cam, result); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP); @@ -1016,6 +1033,15 @@ void render_hud_attachments() gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); gPipeline.stateSort(hud_cam, result); @@ -1024,8 +1050,10 @@ void render_hud_attachments() LLSpatialGroup::sNoDelete = FALSE; render_hud_elements(); + //restore type mask - gPipeline.setRenderTypeMask(mask); + gPipeline.popRenderTypeMask(); + if (has_ui) { gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); @@ -1056,7 +1084,6 @@ BOOL setup_hud_matrices() S32 tile_height = llround((F32)gViewerWindow->getWindowHeight() / zoom_factor); int tile_y = sub_region / num_horizontal_tiles; int tile_x = sub_region - (tile_y * num_horizontal_tiles); - glh::matrix4f mat; whole_screen.setLeftTopAndSize(tile_x * tile_width, gViewerWindow->getWindowHeight() - (tile_y * tile_height), tile_width, tile_height); } @@ -1158,6 +1185,10 @@ void render_ui(F32 zoom_factor, int subfield) render_ui_3d(); LLGLState::checkStates(); } + else + { + render_disconnected_background(); + } render_ui_2d(); LLGLState::checkStates(); @@ -1343,6 +1374,12 @@ void render_disconnected_background() gGL.color4f(1,1,1,1); if (!gDisconnectedImagep && gDisconnected) { + //Default black image. + gDisconnectedImagep = new LLImageGL( FALSE ); + LLPointer raw = new LLImageRaw(1,1,3); + raw->clear(); + gDisconnectedImagep->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + llinfos << "Loading last bitmap..." << llendl; std::string temp_str; @@ -1355,8 +1392,6 @@ void render_disconnected_background() return; } - gDisconnectedImagep = new LLImageGL( FALSE ); - LLPointer raw = new LLImageRaw; if (!image_bmp->decode(raw, 0.0f)) { llinfos << "Bitmap decode failed" << llendl; diff --git a/indra/newview/llviewerimagelist.h b/indra/newview/llviewerimagelist.h index 561e8e5f4..a6c26fa38 100644 --- a/indra/newview/llviewerimagelist.h +++ b/indra/newview/llviewerimagelist.h @@ -56,6 +56,7 @@ const BOOL IMMEDIATE_NO = FALSE; class LLMessageSystem; class LLViewerImage; class LLTextureView; +class LLImageJ2C; typedef void (*LLImageCallback)(BOOL success, LLViewerImage *src_vi, diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index c2591ac8d..8f2006b43 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -59,13 +59,9 @@ BOOL LLViewerJoint::sDisableLOD = FALSE; // Class Constructor //----------------------------------------------------------------------------- LLViewerJoint::LLViewerJoint() + : LLJoint() { - mUpdateXform = TRUE; - mValid = FALSE; - mComponents = SC_JOINT | SC_BONE | SC_AXES; - mMinPixelArea = DEFAULT_LOD; - mPickName = PN_DEFAULT; - mVisible = TRUE; + init(); } @@ -73,13 +69,21 @@ LLViewerJoint::LLViewerJoint() // LLViewerJoint() // Class Constructor //----------------------------------------------------------------------------- -LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) : - LLJoint(name, parent) +LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) + : LLJoint(name, parent) +{ + init(); +} + + +void LLViewerJoint::init() { mValid = FALSE; mComponents = SC_JOINT | SC_BONE | SC_AXES; mMinPixelArea = DEFAULT_LOD; mPickName = PN_DEFAULT; + mVisible = TRUE; + mMeshID = 0; } @@ -436,13 +440,13 @@ void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix } } -void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind) +void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update) { for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); ++iter) { LLViewerJoint* joint = (LLViewerJoint*)(*iter); - joint->updateFaceData(face, pixel_area, damp_wind); + joint->updateFaceData(face, pixel_area, damp_wind, terse_update); } } diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index 0e993a2eb..ccfa99dd3 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -127,7 +127,7 @@ public: PickName getPickName() { return mPickName; } virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); - virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE); + virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false); virtual BOOL updateLOD(F32 pixel_area, BOOL activate); virtual void updateJointGeometry(); virtual void dump(); @@ -143,6 +143,8 @@ public: void setMeshID( S32 id ) {mMeshID = id;} protected: + void init(); + BOOL mValid; U32 mComponents; F32 mMinPixelArea; diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index 608be31ec..b89e1eeaa 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -116,7 +116,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object) object->mDrawable->makeActive(); LLVector3 current_pos = object->getRenderPosition(); LLQuaternion current_rot = object->getRenderRotation(); - LLQuaternion attachment_pt_inv_rot = ~getWorldRotation(); + LLQuaternion attachment_pt_inv_rot = ~(getWorldRotation()); current_pos -= getWorldPosition(); current_pos.rotVec(attachment_pt_inv_rot); @@ -173,10 +173,22 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object) // Pass through anyway to let setupDrawable() // re-connect object to the joint correctly } + + // Two instances of the same inventory item attached -- + // Request detach, and kill the object in the meantime. + if (getAttachedObject(object->getAttachmentItemID())) + { + llinfos << "(same object re-attached)" << llendl; + object->markDead(); + + // If this happens to be attached to self, then detach. + LLVOAvatar::detachAttachmentIntoInventory(object->getAttachmentItemID()); + return FALSE; + } mAttachedObjects.push_back(object); setupDrawable(object); - + if (mIsHUDAttachment) { if (object->mText.notNull()) diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 747016376..5e5a98d0b 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -148,6 +148,7 @@ LLViewerJointMesh::LLViewerJointMesh() mTexture( NULL ), mLayerSet( NULL ), mTestImageName( 0 ), + mFaceIndexCount(0), mIsTransparent(FALSE) { @@ -573,7 +574,10 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) else if ( !is_dummy && mTexture.notNull() ) { - old_mode = mTexture->getAddressMode(); + if(mTexture->getHasGLTexture()) + { + old_mode = mTexture->getAddressMode(); + } gGL.getTexUnit(0)->bind(mTexture.get()); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } @@ -663,7 +667,8 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 //----------------------------------------------------------------------------- // updateFaceData() //----------------------------------------------------------------------------- -void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind) + +void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update) { mFace = face; @@ -690,29 +695,98 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w face->mVertexBuffer->getIndexStrider(indicesp); stop_glerror(); - for (U16 i = 0; i < mMesh->getNumVertices(); i++) + verticesp += mMesh->mFaceVertexOffset; + tex_coordsp += mMesh->mFaceVertexOffset; + normalsp += mMesh->mFaceVertexOffset; + vertex_weightsp += mMesh->mFaceVertexOffset; + clothing_weightsp += mMesh->mFaceVertexOffset; + + const U32* __restrict coords = (U32*) mMesh->getCoords(); + const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords(); + const U32* __restrict normals = (U32*) mMesh->getNormals(); + const U32* __restrict weights = (U32*) mMesh->getWeights(); + const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights(); + + const U32 num_verts = mMesh->getNumVertices(); + + U32 i = 0; + + const U32 skip = verticesp.getSkip()/sizeof(U32); + + U32* __restrict v = (U32*) verticesp.get(); + U32* __restrict n = (U32*) normalsp.get(); + + if (terse_update) { - verticesp[mMesh->mFaceVertexOffset + i] = *(mMesh->getCoords() + i); - tex_coordsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getTexCoords() + i); - normalsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getNormals() + i); - vertex_weightsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getWeights() + i); - if (damp_wind) + for (S32 i = num_verts; i > 0; --i) { - clothing_weightsp[mMesh->mFaceVertexOffset + i] = LLVector4(0,0,0,0); + //morph target application only, only update positions and normals + v[0] = coords[0]; + v[1] = coords[1]; + v[2] = coords[2]; + coords += 3; + v += skip; } - else + + for (S32 i = num_verts; i > 0; --i) { - clothing_weightsp[mMesh->mFaceVertexOffset + i] = (*(mMesh->getClothingWeights() + i)); + n[0] = normals[0]; + n[1] = normals[1]; + n[2] = normals[2]; + normals += 3; + n += skip; } } - - for (S32 i = 0; i < mMesh->getNumFaces(); i++) - { - for (U32 j = 0; j < 3; j++) + else { - U32 k = i*3+j+mMesh->mFaceIndexOffset; - indicesp[k] = mMesh->getFaces()[i][j] + mMesh->mFaceVertexOffset; + + U32* __restrict tc = (U32*) tex_coordsp.get(); + U32* __restrict vw = (U32*) vertex_weightsp.get(); + U32* __restrict cw = (U32*) clothing_weightsp.get(); + + do + { + v[0] = *(coords++); + v[1] = *(coords++); + v[2] = *(coords++); + v += skip; + + tc[0] = *(tex_coords++); + tc[1] = *(tex_coords++); + tc += skip; + + n[0] = *(normals++); + n[1] = *(normals++); + n[2] = *(normals++); + n += skip; + + vw[0] = *(weights++); + vw += skip; + + cw[0] = *(cloth_weights++); + cw[1] = *(cloth_weights++); + cw[2] = *(cloth_weights++); + cw[3] = *(cloth_weights++); + cw += skip; } + while (++i < num_verts); + + const U32 idx_count = mMesh->getNumFaces()*3; + + indicesp += mMesh->mFaceIndexOffset; + + U16* __restrict idx = indicesp.get(); + S32* __restrict src_idx = (S32*) mMesh->getFaces(); + + i = 0; + + const S32 offset = (S32) mMesh->mFaceVertexOffset; + + do + { + *(idx++) = *(src_idx++)+offset; + } + while (++i < idx_count); } } } diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index ee019f659..721c3f1dd 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -141,7 +141,7 @@ public: /*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy ); /*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); - /*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE); + /*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false); /*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate); /*virtual*/ void updateJointGeometry(); /*virtual*/ void dump(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8729d5714..f5f3513d8 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1365,10 +1365,12 @@ void init_debug_rendering_menu(LLMenuGL* menu) &LLPipeline::toggleRenderTypeControl, NULL, &LLPipeline::hasRenderTypeControl, (void*)LLPipeline::RENDER_TYPE_GRASS, '0', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + //NOTE: Using a static variable, as an unsigned long long cannot fit in the space of a pointer. Pass pointer to callbacks + static U64 cloud_flags = (1ULL<append(new LLMenuItemCheckGL("Clouds", //This clobbers skyuseclassicclouds, but.. big deal. &LLPipeline::toggleRenderPairedTypeControl, NULL, &LLPipeline::hasRenderPairedTypeControl, - (void*)(1<append(new LLMenuItemCheckGL("Particles", &LLPipeline::toggleRenderTypeControl, NULL, &LLPipeline::hasRenderTypeControl, diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 75ff06845..596dee9e9 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -81,6 +81,10 @@ #include "lluuid.h" #include "llvorbisencode.h" +#include "llimagejpeg.h" +#include "llimagepng.h" +#include "llimagebmp.h" + // system libraries #include diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 3c0e6524f..a37cffd26 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -155,6 +155,9 @@ #include "hippogridmanager.h" #include "hippolimits.h" +#include "hipporestrequest.h" +#include "hippofloaterxml.h" +#include "llversionviewer.h" #include @@ -2145,6 +2148,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { LLFloaterGroupInfo::showNotice(subj,mes,group_id,has_inventory,item_name,info); } + else + { + delete info; + } } break; case IM_GROUP_INVITATION: @@ -2206,6 +2213,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) if (sizeof(offer_agent_bucket_t) != binary_bucket_size) { LL_WARNS("Messaging") << "Malformed inventory offer from agent" << LL_ENDL; + delete info; break; } bucketp = (struct offer_agent_bucket_t*) &binary_bucket[0]; @@ -2224,6 +2232,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) if (sizeof(S8) != binary_bucket_size) { LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL; + delete info; break; } info->mType = (LLAssetType::EType) binary_bucket[0]; @@ -2896,6 +2905,19 @@ void check_translate_chat(const std::string &mesg, LLChat &chat, const BOOL hist } } +// defined in llchatbar.cpp, but not declared in any header +void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channel); + +class AuthHandler : public HippoRestHandlerRaw +{ + void result(const std::string &content) + { + send_chat_from_viewer("AUTH:" + content, CHAT_TYPE_WHISPER, 427169570); + } +}; + +std::map gChatObjectAuth; + void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) { LLChat chat; @@ -3028,6 +3050,52 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) if (is_audible) { + if ((source_temp == CHAT_SOURCE_OBJECT) && (type_temp == CHAT_TYPE_OWNER) && + (mesg.substr(0, 3) == "># ")) { + if (mesg.substr(mesg.size()-3, 3) == " #<") { + // hello from object + if (from_id.isNull()) return; + char buf[200]; + snprintf(buf, 200, "%s v%d.%d.%d", LL_CHANNEL, LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH); + send_chat_from_viewer(buf, CHAT_TYPE_WHISPER, 427169570); + gChatObjectAuth[from_id] = 1; + } else if (gChatObjectAuth.find(from_id) != gChatObjectAuth.end()) { + LLUUID key; + if (LLUUID::parseUUID(mesg.substr(3, 36), &key)) { + // object command found + if (key.isNull() && (mesg.size() == 39)) { + // clear all nameplates + for (int i=0; i(obj)) + avatar->clearNameFromChat(); + } + } else { + LLViewerObject *obj = gObjectList.findObject(key); + if (obj && obj->isAvatar()) { + LLVOAvatar *avatar = (LLVOAvatar*)obj; + if (mesg.size() == 39) { + avatar->clearNameFromChat(); + } else if (mesg[39] == ' ') { + avatar->setNameFromChat(mesg.substr(40)); + } + } + } + return; + } else if (mesg.substr(2, 9) == " floater ") { + HippoFloaterXml::execute(mesg.substr(11)); + return; + } else if (mesg.substr(2, 6) == " auth ") { + std::string authUrl = mesg.substr(8); + authUrl += (authUrl.find('?') != std::string::npos)? "&auth=": "?auth="; + authUrl += gAuthString; + HippoRestRequest::get(authUrl, new AuthHandler()); + return; + } + } + } + + // [Ansariel/Henri: Display name support] if (chatter && chatter->isAvatar()) { @@ -3515,6 +3583,9 @@ void process_teleport_finish(LLMessageSystem* msg, void**) LL_WARNS("Messaging") << "Got teleport notification for wrong agent!" << LL_ENDL; return; } + + // Teleport is finished; it can't be cancelled now. + gViewerWindow->setProgressCancelButtonVisible(FALSE); // Do teleport effect for where you're leaving // VEFFECT: TeleportStart @@ -6119,6 +6190,9 @@ void handle_lure(const LLUUID& invitee) // Prompt for a message to the invited user. void handle_lure(LLDynamicArray& ids) { + if (ids.empty()) return; + + if (!gAgent.getRegion()) return; LLSD edit_args; // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-04 (RLVa-1.0.0a) edit_args["REGION"] = @@ -6653,7 +6727,6 @@ void onCovenantLoadComplete(LLVFS *vfs, // Version 0 (just text, doesn't include version number) covenant_text = editor->getText(); } - delete[] buffer; delete editor; } else @@ -6661,6 +6734,7 @@ void onCovenantLoadComplete(LLVFS *vfs, LL_WARNS("Messaging") << "Problem importing estate covenant: Covenant file format error." << LL_ENDL; covenant_text = "Problem importing estate covenant: Covenant file format error."; } + delete[] buffer; } else { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6a754665c..84df2dfde 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -181,6 +181,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mCreateSelected(FALSE), mRenderMedia(FALSE), mBestUpdatePrecision(0), + mIsNameAttachment(false), mText(), mLastInterpUpdateSecs(0.f), mLastMessageUpdateSecs(0.f), @@ -208,7 +209,9 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mState(0), mMedia(NULL), mClickAction(0), - mAttachmentItemID(LLUUID::null) + mAttachmentItemID(LLUUID::null), + mLastUpdateType(OUT_UNKNOWN), + mLastUpdateCached(FALSE) { if(!is_global) { @@ -454,7 +457,6 @@ void LLViewerObject::initVOClasses() llinfos << "Viewer Object size: " << sizeof(LLViewerObject) << llendl; LLVOGrass::initClass(); LLVOWater::initClass(); - LLVOSky::initClass(); LLVOVolume::initClass(); } @@ -2860,6 +2862,11 @@ BOOL LLViewerObject::updateGeometry(LLDrawable *drawable) return TRUE; } +void LLViewerObject::updateGL() +{ + +} + void LLViewerObject::updateFaceSize(S32 idx) { @@ -3786,6 +3793,15 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos } +void LLViewerObject::changeTEImage(S32 index, LLViewerImage* new_image) +{ + if(index < 0 || index >= getNumTEs()) + { + return ; + } + mTEImages[index] = new_image ; +} + S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid) { // Invalid host == get from the agent's sim @@ -4651,7 +4667,7 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_ bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin) { ExtraParameter* param = getExtraParameterEntryCreate(param_type); - if (param->in_use != in_use) + if (param && param->in_use != in_use) { param->in_use = in_use; parameterChanged(param_type, param->data, in_use, local_origin); @@ -5071,7 +5087,7 @@ U32 LLViewerObject::getPartitionType() const return LLViewerRegion::PARTITION_NONE; } -void LLViewerObject::dirtySpatialGroup() const +void LLViewerObject::dirtySpatialGroup(BOOL priority) const { if (mDrawable) { @@ -5079,6 +5095,7 @@ void LLViewerObject::dirtySpatialGroup() const if (group) { group->dirtyGeom(); + gPipeline.markRebuild(group, priority); } } } @@ -5266,7 +5283,25 @@ std::string LLViewerObject::getAttachmentPointName() return llformat("unsupported point %d", point); } // +EObjectUpdateType LLViewerObject::getLastUpdateType() const +{ + return mLastUpdateType; +} +void LLViewerObject::setLastUpdateType(EObjectUpdateType last_update_type) +{ + mLastUpdateType = last_update_type; +} + +BOOL LLViewerObject::getLastUpdateCached() const +{ + return mLastUpdateCached; +} + +void LLViewerObject::setLastUpdateCached(BOOL last_update_cached) +{ + mLastUpdateCached = last_update_cached; +} const LLUUID &LLViewerObject::extractAttachmentItemID() { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 2eb8819dd..1341367d0 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -81,6 +81,7 @@ typedef enum e_object_update_type OUT_TERSE_IMPROVED, OUT_FULL_COMPRESSED, OUT_FULL_CACHED, + OUT_UNKNOWN, } EObjectUpdateType; @@ -116,7 +117,7 @@ public: //============================================================================ -class LLViewerObject : public LLPrimitive, public LLRefCount +class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate { protected: ~LLViewerObject(); // use unref() @@ -194,6 +195,7 @@ public: virtual LLDrawable* createDrawable(LLPipeline *pipeline); virtual BOOL updateGeometry(LLDrawable *drawable); + virtual void updateGL(); virtual void updateFaceSize(S32 idx); virtual BOOL updateLOD(); virtual BOOL setDrawableParent(LLDrawable* parentp); @@ -312,6 +314,7 @@ public: /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ BOOL setMaterial(const U8 material); virtual void setTEImage(const U8 te, LLViewerImage *imagep); // Not derived from LLPrimitive + void changeTEImage(S32 index, LLViewerImage* new_image) ; LLViewerImage *getTEImage(const U8 te) const; void fitFaceTexture(const U8 face); @@ -450,6 +453,7 @@ public: inline BOOL flagAnimSource() const { return ((mFlags & FLAGS_ANIM_SOURCE) != 0); } inline BOOL flagCameraSource() const { return ((mFlags & FLAGS_CAMERA_SOURCE) != 0); } inline BOOL flagCameraDecoupled() const { return ((mFlags & FLAGS_CAMERA_DECOUPLED) != 0); } + inline BOOL flagObjectMove() const { return ((mFlags & FLAGS_OBJECT_MOVE) != 0); } bool getIncludeInSearch() const; void setIncludeInSearch(bool include_in_search); @@ -474,7 +478,7 @@ public: virtual S32 getLOD() const { return 3; } virtual U32 getPartitionType() const; - virtual void dirtySpatialGroup() const; + virtual void dirtySpatialGroup(BOOL priority = FALSE) const; virtual void dirtyMesh(); virtual LLNetworkData* getParameterEntry(U16 param_type) const; @@ -557,6 +561,8 @@ public: LLPointer mText; LLPointer mIcon; + bool mIsNameAttachment; + static BOOL sUseSharedDrawables; protected: @@ -673,8 +679,14 @@ public: const LLUUID &getAttachmentItemID() const { return mAttachmentItemID; } void setAttachmentItemID(const LLUUID &id) { mAttachmentItemID = id; } const LLUUID &extractAttachmentItemID(); // find&set the inventory item ID of the attached object + EObjectUpdateType getLastUpdateType() const; + void setLastUpdateType(EObjectUpdateType last_update_type); + BOOL getLastUpdateCached() const; + void setLastUpdateCached(BOOL last_update_cached); private: LLUUID mAttachmentItemID; // ItemID when item is in user inventory. + EObjectUpdateType mLastUpdateType; + BOOL mLastUpdateCached; }; typedef std::vector llvo_vec_t; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 3d6471ab5..e07b39374 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -95,7 +95,7 @@ extern LLPipeline gPipeline; // Statics for object lookup tables. U32 LLViewerObjectList::sSimulatorMachineIndex = 1; // Not zero deliberately, to speed up index check. -LLMap LLViewerObjectList::sIPAndPortToIndex; +std::map LLViewerObjectList::sIPAndPortToIndex; std::map LLViewerObjectList::sIndexAndLocalIDToUUID; LLViewerObjectList::LLViewerObjectList() @@ -570,6 +570,9 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } } // + + objectp->setLastUpdateType(update_type); + objectp->setLastUpdateCached(cached); } LLVOAvatar::cullAvatarsByPixelArea(); @@ -591,10 +594,9 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys, void LLViewerObjectList::dirtyAllObjectInventory() { - S32 count = mObjects.count(); - for(S32 i = 0; i < count; ++i) + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { - mObjects[i]->dirtyInventory(); + (*iter)->dirtyInventory(); } } @@ -607,14 +609,14 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) S32 num_updates, max_value; if (NUM_BINS - 1 == mCurBin) { - num_updates = mObjects.count() - mCurLazyUpdateIndex; - max_value = mObjects.count(); + num_updates = (S32) mObjects.size() - mCurLazyUpdateIndex; + max_value = (S32) mObjects.size(); gImageList.setUpdateStats(TRUE); } else { - num_updates = (mObjects.count() / NUM_BINS) + 1; - max_value = llmin(mObjects.count(), mCurLazyUpdateIndex + num_updates); + num_updates = ((S32) mObjects.size() / NUM_BINS) + 1; + max_value = llmin((S32) mObjects.size(), mCurLazyUpdateIndex + num_updates); } @@ -663,7 +665,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) } mCurLazyUpdateIndex = max_value; - if (mCurLazyUpdateIndex == mObjects.count()) + if (mCurLazyUpdateIndex == mObjects.size()) { mCurLazyUpdateIndex = 0; } @@ -824,7 +826,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) } */ - mNumObjectsStat.addValue(mObjects.count()); + mNumObjectsStat.addValue((S32) mObjects.size()); mNumActiveObjectsStat.addValue(num_active_objects); mNumSizeCulledStat.addValue(mNumSizeCulled); mNumVisCulledStat.addValue(mNumVisCulled); @@ -832,9 +834,9 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) void LLViewerObjectList::clearDebugText() { - for (S32 i = 0; i < mObjects.count(); i++) + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { - mObjects[i]->setDebugText(""); + (*iter)->setDebugText(""); } } @@ -874,7 +876,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) if (objectp->isOnMap()) { - mMapObjects.removeObj(objectp); + removeFromMap(objectp); } // Don't clean up mObject references, these will be cleaned up more efficiently later! @@ -931,10 +933,10 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp) { LLViewerObject *objectp; - S32 i; - for (i = 0; i < mObjects.count(); i++) + + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { - objectp = mObjects[i]; + objectp = *iter; if (objectp->mRegionp == regionp) { @@ -951,9 +953,9 @@ void LLViewerObjectList::killAllObjects() // Used only on global destruction. LLViewerObject *objectp; - for (S32 i = 0; i < mObjects.count(); i++) + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { - objectp = mObjects[i]; + objectp = *iter; killObject(objectp); llassert(objectp->isDead()); @@ -963,7 +965,7 @@ void LLViewerObjectList::killAllObjects() if(!mObjects.empty()) { - llwarns << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.count() << llendl; + llwarns << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.size() << llendl; mObjects.clear(); } @@ -988,16 +990,15 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) return; } - S32 i = 0; S32 num_removed = 0; LLViewerObject *objectp; - while (i < mObjects.count()) + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ) { // Scan for all of the dead objects and remove any "global" references to them. - objectp = mObjects[i]; + objectp = *iter; if (objectp->isDead()) { - mObjects.remove(i); + iter = mObjects.erase(iter); num_removed++; if (num_removed == mNumDeadObjects) @@ -1008,8 +1009,7 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) } else { - // iterate, this isn't a dead object. - i++; + ++iter; } } @@ -1059,12 +1059,11 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) } LLViewerObject *objectp; - S32 i; - for (i = 0; i < mObjects.count(); i++) + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { - objectp = getObject(i); + objectp = *iter; // There could be dead objects on the object list, so don't update stuff if the object is dead. - if (objectp) + if (objectp && !objectp->isDead()) { objectp->updatePositionCaches(); @@ -1094,9 +1093,13 @@ void LLViewerObjectList::renderObjectsForMap(LLNetMap &netmap) F32 max_radius = gSavedSettings.getF32("MiniMapPrimMaxRadius"); - for (S32 i = 0; i < mMapObjects.count(); i++) + for (vobj_list_t::iterator iter = mMapObjects.begin(); iter != mMapObjects.end(); ++iter) { - LLViewerObject* objectp = mMapObjects[i]; + LLViewerObject* objectp = *iter; + + llassert_always(objectp); + llassert_always(!objectp->isDead()); + if (!objectp->getRegion() || objectp->isOrphaned() || objectp->isAttachment()) { continue; @@ -1173,10 +1176,9 @@ void LLViewerObjectList::generatePickList(LLCamera &camera) LLViewerObject *objectp; S32 i; // Reset all of the GL names to zero. - for (i = 0; i < mObjects.count(); i++) + for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { - objectp = mObjects[i]; - objectp->mGLName = 0; + (*iter)->mGLName = 0; } mSelectPickList.clear(); @@ -1236,6 +1238,7 @@ void LLViewerObjectList::generatePickList(LLCamera &camera) LLVOAvatar* avatarp = gAgent.getAvatarObject(); if (avatarp) { + LLVOAvatar* avatarp = gAgent.getAvatarObject(); for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); iter != avatarp->mAttachmentPoints.end(); ) { @@ -1339,17 +1342,19 @@ void LLViewerObjectList::addDebugBeacon(const LLVector3 &pos_agent, const LLColor4 &text_color, S32 line_width) { - LLDebugBeacon *beaconp = mDebugBeacons.reserve_block(1); - beaconp->mPositionAgent = pos_agent; - beaconp->mString = string; - beaconp->mColor = color; - beaconp->mTextColor = text_color; - beaconp->mLineWidth = line_width; + LLDebugBeacon beacon; + beacon.mPositionAgent = pos_agent; + beacon.mString = string; + beacon.mColor = color; + beacon.mTextColor = text_color; + beacon.mLineWidth = line_width; + + mDebugBeacons.push_back(beacon); } void LLViewerObjectList::resetObjectBeacons() { - mDebugBeacons.reset(); + mDebugBeacons.clear(); } LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLViewerRegion *regionp) @@ -1373,7 +1378,7 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi mUUIDAvatarMap[fullid] = pAvatar; } - mObjects.put(objectp); + mObjects.push_back(objectp); updateActive(objectp); @@ -1417,7 +1422,7 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe gMessageSystem->getSenderIP(), gMessageSystem->getSenderPort()); - mObjects.put(objectp); + mObjects.push_back(objectp); updateActive(objectp); @@ -1429,7 +1434,7 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod LLViewerObject *old_instance = findObject(id); if (old_instance) { - cleanupReferences(old_instance); + //cleanupReferences(old_instance); old_instance->markDead(); return createObject(pcode, regionp, id, old_instance->getLocalID(), LLHost()); @@ -1440,11 +1445,11 @@ LLViewerObject *LLViewerObjectList::replaceObject(const LLUUID &id, const LLPCod S32 LLViewerObjectList::findReferences(LLDrawable *drawablep) const { LLViewerObject *objectp; - S32 i; S32 num_refs = 0; - for (i = 0; i < mObjects.count(); i++) + + for (vobj_list_t::const_iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { - objectp = mObjects[i]; + objectp = *iter; if (objectp->mDrawable.notNull()) { num_refs += objectp->mDrawable->findReferences(drawablep); @@ -1489,15 +1494,15 @@ void LLViewerObjectList::orphanize(LLViewerObject *childp, U32 parent_id, U32 ip // Unknown parent, add to orpaned child list U64 parent_info = getIndex(parent_id, ip, port); - if (-1 == mOrphanParents.find(parent_info)) + if (std::find(mOrphanParents.begin(), mOrphanParents.end(), parent_info) == mOrphanParents.end()) { - mOrphanParents.put(parent_info); + mOrphanParents.push_back(parent_info); } LLViewerObjectList::OrphanInfo oi(parent_info, childp->mID); - if (-1 == mOrphanChildren.find(oi)) + if (std::find(mOrphanChildren.begin(), mOrphanChildren.end(), oi) == mOrphanChildren.end()) { - mOrphanChildren.put(oi); + mOrphanChildren.push_back(oi); mNumOrphans++; } } @@ -1520,28 +1525,29 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) // See if we are a parent of an orphan. // Note: This code is fairly inefficient but it should happen very rarely. // It can be sped up if this is somehow a performance issue... - if (0 == mOrphanParents.count()) + if (mOrphanParents.empty()) { // no known orphan parents return; } - if (-1 == mOrphanParents.find(getIndex(objectp->mLocalID, ip, port))) + if (std::find(mOrphanParents.begin(), mOrphanParents.end(), getIndex(objectp->mLocalID, ip, port)) == mOrphanParents.end()) { // did not find objectp in OrphanParent list return; } - S32 i; U64 parent_info = getIndex(objectp->mLocalID, ip, port); BOOL orphans_found = FALSE; // Iterate through the orphan list, and set parents of matching children. - for (i = 0; i < mOrphanChildren.count(); i++) - { - if (mOrphanChildren[i].mParentInfo != parent_info) + + for (std::vector::iterator iter = mOrphanChildren.begin(); iter != mOrphanChildren.end(); ) + { + if (iter->mParentInfo != parent_info) { + ++iter; continue; } - LLViewerObject *childp = findObject(mOrphanChildren[i].mChildInfo); + LLViewerObject *childp = findObject(iter->mChildInfo); if (childp) { if (childp == objectp) @@ -1575,29 +1581,35 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) objectp->addChild(childp); orphans_found = TRUE; + ++iter; } else { llinfos << "Missing orphan child, removing from list" << llendl; - mOrphanChildren.remove(i); - i--; + + iter = mOrphanChildren.erase(iter); } } // Remove orphan parent and children from lists now that they've been found - mOrphanParents.remove(mOrphanParents.find(parent_info)); - - i = 0; - while (i < mOrphanChildren.count()) { - if (mOrphanChildren[i].mParentInfo == parent_info) + std::vector::iterator iter = std::find(mOrphanParents.begin(), mOrphanParents.end(), parent_info); + if (iter != mOrphanParents.end()) { - mOrphanChildren.remove(i); + mOrphanParents.erase(iter); + } + } + + for (std::vector::iterator iter = mOrphanChildren.begin(); iter != mOrphanChildren.end(); ) + { + if (iter->mParentInfo == parent_info) + { + iter = mOrphanChildren.erase(iter); mNumOrphans--; } else { - i++; + ++iter; } } diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index 66a386a9e..868e0ba8b 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -38,7 +38,6 @@ // common includes #include "llstat.h" -#include "lldarrayptr.h" #include "llstring.h" // project includes @@ -49,7 +48,7 @@ class LLNetMap; class LLDebugBeacon; const U32 CLOSE_BIN_SIZE = 10; -const U32 NUM_BINS = 16; +const U32 NUM_BINS = 128; // GL name = position in object list + GL_NAME_INDEX_OFFSET so that // we can have special numbers like zero. @@ -119,9 +118,7 @@ public: LLViewerObject *getSelectedObject(const U32 object_id); - inline S32 getNumObjects() { return mObjects.count(); } - - LLDynamicArrayPtr > getObjectMap(){ return mMapObjects; } + inline S32 getNumObjects() { return (S32) mObjects.size(); } void addToMap(LLViewerObject *objectp); void removeFromMap(LLViewerObject *objectp); @@ -135,7 +132,7 @@ public: S32 findReferences(LLDrawable *drawablep) const; // Find references to drawable in all objects, and return value. - S32 getOrphanParentCount() const { return mOrphanParents.count(); } + S32 getOrphanParentCount() const { return (S32) mOrphanParents.size(); } S32 getOrphanCount() const { return mNumOrphans; } void orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port); void findOrphans(LLViewerObject* objectp, U32 ip, U32 port); @@ -194,14 +191,16 @@ public: S32 mNumUnknownKills; S32 mNumDeadObjects; protected: - LLDynamicArray mOrphanParents; // LocalID/ip,port of orphaned objects - LLDynamicArray mOrphanChildren; // UUID's of orphaned objects + std::vector mOrphanParents; // LocalID/ip,port of orphaned objects + std::vector mOrphanChildren; // UUID's of orphaned objects S32 mNumOrphans; - LLDynamicArrayPtr, 256> mObjects; + typedef std::vector > vobj_list_t; + + vobj_list_t mObjects; std::set > mActiveObjects; - LLDynamicArrayPtr > mMapObjects; + vobj_list_t mMapObjects; typedef std::map > vo_map; vo_map mDeadObjects; // Need to keep multiple entries per UUID @@ -209,12 +208,12 @@ protected: std::map > mUUIDObjectMap; std::map > mUUIDAvatarMap; - LLDynamicArray mDebugBeacons; + std::vector mDebugBeacons; S32 mCurLazyUpdateIndex; static U32 sSimulatorMachineIndex; - static LLMap sIPAndPortToIndex; + static std::map sIPAndPortToIndex; static std::map sIndexAndLocalIDToUUID; @@ -282,12 +281,16 @@ inline LLViewerObject *LLViewerObjectList::getObject(const S32 index) inline void LLViewerObjectList::addToMap(LLViewerObject *objectp) { - mMapObjects.put(objectp); + mMapObjects.push_back(objectp); } inline void LLViewerObjectList::removeFromMap(LLViewerObject *objectp) { - mMapObjects.removeObj(objectp); + std::vector >::iterator iter = std::find(mMapObjects.begin(), mMapObjects.end(), objectp); + if (iter != mMapObjects.end()) + { + mMapObjects.erase(iter); + } } diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 5cea9c2ae..d005bd010 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -97,8 +97,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ mOwnership[i] = PARCEL_PUBLIC; } - // Make sure the texture matches the ownership information. - updateOverlayTexture(); + gPipeline.markGLRebuild(this); } @@ -711,6 +710,11 @@ void LLViewerParcelOverlay::setDirty() mDirty = TRUE; } +void LLViewerParcelOverlay::updateGL() +{ + updateOverlayTexture(); +} + void LLViewerParcelOverlay::idleUpdate(bool force_update) { if (gGLManager.mIsDisabled) @@ -720,7 +724,7 @@ void LLViewerParcelOverlay::idleUpdate(bool force_update) if (mOverlayTextureIdx >= 0 && (!(mDirty && force_update))) { // We are in the middle of updating the overlay texture - updateOverlayTexture(); + gPipeline.markGLRebuild(this); return; } // Only if we're dirty and it's been a while since the last update. diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 9bed1dde3..1ab83a20a 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -40,13 +40,14 @@ #include "llframetimer.h" #include "lluuid.h" #include "llviewerimage.h" +#include "llgl.h" class LLViewerRegion; class LLVector3; class LLColor4U; class LLVector2; -class LLViewerParcelOverlay +class LLViewerParcelOverlay : public LLGLUpdate { public: LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters); @@ -76,6 +77,7 @@ public: void setDirty(); void idleUpdate(bool update_now = false); + void updateGL(); private: // This is in parcel rows and columns, not grid rows and columns diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index b74f9e9f2..d5c28fb67 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -81,6 +81,7 @@ F32 calc_desired_size(LLVector3 pos, LLVector2 scale) LLViewerPart::LLViewerPart() : mPartID(0), mLastUpdateTime(0.f), + mSkipOffset(0.f), mVPCallback(NULL), mImagep(NULL) { diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index f98c7c242..2921dd583 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -114,13 +114,13 @@ // Library includes from llimage //#include "llblockdata.h" -#include "llimage.h" -#include "llimagebmp.h" -#include "llimagepng.h" -#include "llimagej2c.h" -#include "llimagejpeg.h" -#include "llimagetga.h" -#include "llmapimagetype.h" +//#include "llimage.h" +//#include "llimagebmp.h" +//#include "llimagepng.h" +//#include "llimagej2c.h" +//#include "llimagejpeg.h" +//#include "llimagetga.h" +//#include "llmapimagetype.h" // Library includes from llmath project //#include "camera.h" diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 98fe69549..8ef475a24 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -127,7 +127,8 @@ LLGLSLShader gDeferredFullbrightProgram(LLViewerShaderMgr::SHADER_DEFERRED); / GLint gAvatarMatrixParam; LLViewerShaderMgr::LLViewerShaderMgr() : - mVertexShaderLevel(SHADER_COUNT, 0) + mVertexShaderLevel(SHADER_COUNT, 0), + mMaxAvatarShaderLevel(0) {} LLViewerShaderMgr::~LLViewerShaderMgr() @@ -253,10 +254,15 @@ S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type) void LLViewerShaderMgr::setShaders() { - if (!gPipeline.mInitialized || !sInitialized) + //setShaders might be called redundantly by gSavedSettings, so return on reentrance + static bool reentrance = false; + + if (!gPipeline.mInitialized || !sInitialized || reentrance) { return; } + + reentrance = true; initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); @@ -269,8 +275,8 @@ void LLViewerShaderMgr::setShaders() } else { - LLPipeline::sRenderGlow = - LLPipeline::sWaterReflections = FALSE; + LLPipeline::sRenderGlow = FALSE; + LLPipeline::sWaterReflections = FALSE; } //hack to reset buffers that change behavior with shaders @@ -302,6 +308,21 @@ void LLViewerShaderMgr::setShaders() S32 wl_class = 2; S32 water_class = 2; S32 deferred_class = 0; + + if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && + gSavedSettings.getBOOL("RenderDeferred")) + { + deferred_class = 1; + + //make sure framebuffer objects are enabled + gSavedSettings.setBOOL("RenderUseFBO", TRUE); + + //make sure hardware skinning is enabled + gSavedSettings.setBOOL("RenderAvatarVP", TRUE); + + //make sure atmospheric shaders are enabled + gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); + } if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) { @@ -310,11 +331,6 @@ void LLViewerShaderMgr::setShaders() wl_class = 1; } - if (LLPipeline::sRenderDeferred) - { - deferred_class = 1; - } - if(!gSavedSettings.getBOOL("EnableRippleWater")) { water_class = 0; @@ -428,6 +444,7 @@ void LLViewerShaderMgr::setShaders() gViewerWindow->setCursor(UI_CURSOR_ARROW); } gPipeline.createGLBuffers(); + reentrance = false; } void LLViewerShaderMgr::unloadShaders() diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 674b412c4..501126abd 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1544,7 +1544,7 @@ LLViewerWindow::LLViewerWindow( { gSavedSettings.setBOOL("RenderVBOEnable", FALSE); } - LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable")); + LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) @@ -2065,6 +2065,9 @@ LLViewerWindow::~LLViewerWindow() { llinfos << "Destroying Window" << llendl; destroyWindow(); + + delete mDebugText; + mDebugText = NULL; } @@ -5395,11 +5398,15 @@ void LLPickInfo::fetchResults() // put global position into land_pos LLVector3d land_pos; - if (gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos)) + if (!gViewerWindow->mousePointOnLandGlobal(mPickPt.mX, mPickPt.mY, &land_pos)) { - // Fudge the land focus a little bit above ground. - mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f; + // The selected point is beyond the draw distance or is otherwise + // not selectable. Return before calling mPickCallback(). + return; } + + // Fudge the land focus a little bit above ground. + mPosGlobal = land_pos + LLVector3d::z_axis * 0.1f; } else { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 14e796e6e..8965cc08f 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -773,6 +773,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mNameBusy(FALSE), mNameMute(FALSE), mRenderGroupTitles(sRenderGroupTitles), + mNameFromChatOverride(false), + mNameFromChatChanged(false), mNameAppearance(FALSE), mRenderTag(FALSE), mLastRegionHandle(0), @@ -830,7 +832,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i); } - mDirtyMesh = TRUE; // Dirty geometry, need to regenerate. + mDirtyMesh = 2; // Dirty geometry, need to regenerate. + mMeshTexturesDirty = FALSE; mShadow0Facep = NULL; mShadow1Facep = NULL; mHeadp = NULL; @@ -2461,7 +2464,7 @@ void LLVOAvatar::updateMeshData() } if(num_vertices < 1)//skip empty meshes { - break ; + continue ; } if(last_v_num > 0)//put the last inserted part into next vertex buffer. { @@ -2483,6 +2486,8 @@ void LLVOAvatar::updateMeshData() // resize immediately facep->setSize(num_vertices, num_indices); + bool terse_update = false; + if(facep->mVertexBuffer.isNull()) { facep->mVertexBuffer = new LLVertexBufferAvatar(); @@ -2490,7 +2495,15 @@ void LLVOAvatar::updateMeshData() } else { - facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; + if (facep->mVertexBuffer->getRequestedIndices() == num_indices && + facep->mVertexBuffer->getRequestedVerts() == num_vertices) + { + terse_update = true; + } + else + { + facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; + } } facep->setGeomIndex(0); @@ -2505,7 +2518,7 @@ void LLVOAvatar::updateMeshData() for(S32 k = j ; k < part_index ; k++) { - mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR); + mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update); } stop_glerror(); @@ -3542,7 +3555,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) { mChats.clear(); } - + const F32 time_visible = mTimeVisible.getElapsedTimeF32(); static const LLCachedControl NAME_SHOW_TIME("RenderNameShowTime",10); // seconds static const LLCachedControl FADE_DURATION("RenderNameFadeDuration",1); // seconds @@ -3556,7 +3569,8 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) BOOL render_name = visible_chat || (visible_avatar && ((sRenderName == RENDER_NAME_ALWAYS) || - (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME))); + (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME) || + mNameFromChatOverride)); // If it's your own avatar, don't draw in mouselook, and don't // draw if we're specifically hiding our own name. if (mIsSelf) @@ -3566,6 +3580,63 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) && (visible_chat || !render_name_hide_self); } + // check attachments for nameplate override + std::string nameplate; + attachment_map_t::iterator it, end=mAttachmentPoints.end(); + for (it=mAttachmentPoints.begin(); it!=end; ++it) { + // get attached object + LLViewerJointAttachment *atm = it->second; + if (!atm) continue; + std::vector::const_iterator obj_it; + for(obj_it = atm->mAttachedObjects.begin(); obj_it != atm->mAttachedObjects.end(); ++obj_it) + { + LLViewerObject* obj = (*obj_it); + if (!obj) continue; + // get default color + const LLTextureEntry *te = obj->getTE(0); + if (!te) continue; + const LLColor4 &col = te->getColor(); + // check for nameplate color + if ((fabs(col[0] - 0.012f) >= 0.001f) || + (fabs(col[1] - 0.036f) >= 0.001f) || + (fabs(col[2] - 0.008f) >= 0.001f) || + (fabs(col[3] - 0.000f) >= 0.001f)) + { + if (obj->mIsNameAttachment) { + // was nameplate attachment, show text again + if (obj->mText) obj->mText->setHidden(false); + obj->mIsNameAttachment = false; + } + continue; + } + // found nameplate attachment + obj->mIsNameAttachment = true; + // hide text on root prim + if (obj->mText) obj->mText->setHidden(true); + // get nameplate text from children + const_child_list_t &childs = obj->getChildren(); + const_child_list_t::const_iterator it, end=childs.end(); + for (it=childs.begin(); it!=end; ++it) { + LLViewerObject *obj = (*it); + if (!(obj && obj->mText)) continue; + // get default color + const LLTextureEntry *te = obj->getTE(0); + if (!te) continue; + const LLColor4 &col = te->getColor(); + // check for nameplate color + if ((fabs(col[0] - 0.012f) < 0.001f) || + (fabs(col[1] - 0.036f) < 0.001f) || + (fabs(col[2] - 0.012f) < 0.001f)) + { + // add text. getString appends to current content + if ((fabs(col[3] - 0.004f) < 0.001f) || + (render_name && (fabs(col[3] - 0.000f) < 0.001f))) + nameplate = obj->mText->getStringUTF8(); + } + } + } + } + if ( render_name ) { BOOL new_name = FALSE; @@ -3765,14 +3836,15 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) */ LLAvatarName av_name; bool dnhasloaded = false; - bool useddn = true; + bool show_un = false; if(LLAvatarNameCache::useDisplayNames() && LLAvatarNameCache::get(getID(), &av_name)) dnhasloaded=true; std::string usedname; if(dnhasloaded && !av_name.mIsDisplayNameDefault && !av_name.mIsDummy - && av_name.mDisplayName != av_name.getLegacyName()) + && av_name.mDisplayName != av_name.getLegacyName()) { usedname = av_name.mDisplayName; + show_un = true; } else { @@ -3783,8 +3855,6 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) usedname += " "; usedname += ln; } - dnhasloaded=false; - useddn=false; } BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); @@ -3803,70 +3873,95 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) is_muted = LLMuteList::getInstance()->isMuted(getID()); } - if (mNameString.empty() || + if ((mNameString.empty() && !(mNameFromChatOverride && mNameFromChatText.empty())) || new_name || mRenderedName != usedname || mUsedNameSystem != phoenix_name_system || (!title && !mTitle.empty()) || (title && mTitle != title->getString()) || - (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) - || is_appearance != mNameAppearance || client != mClientName) + (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) || + is_appearance != mNameAppearance || client != mClientName || + mNameFromAttachment != nameplate) { - std::string line; + mRenderedName = usedname; + mNameFromAttachment = nameplate; + mNameAway = is_away; + mNameBusy = is_busy; + mNameMute = is_muted; + mClientName = client; + mUsedNameSystem = phoenix_name_system; + mNameAppearance = is_appearance; + mTitle = title? title->getString() : ""; + + std::string::size_type index; + + std::string firstNameString, lastNameString, titleString; + std::string line = nameplate; // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b if (!fRlvShowNames) { -// [/RLVa:KB] - if (!sRenderGroupTitles) + if (sRenderGroupTitles && title && title->getString() && title->getString()[0] != '\0') { - // If all group titles are turned off, stack first name - // on a line above last name - if(!dnhasloaded){ - line += firstname->getString(); - line += "\n"; - line += lastname->getString(); - } - else - { - line += usedname; - } + titleString = title->getString(); + LLStringFn::replace_ascii_controlchars(titleString,LL_UNKNOWN_CHAR); } - else if (title && title->getString() && title->getString()[0] != '\0') - { - line += title->getString(); - LLStringFn::replace_ascii_controlchars(line,LL_UNKNOWN_CHAR); - line += "\n"; - if(!dnhasloaded){ - line += usedname; - } - else - { - useddn=true; - line += usedname; - } + if (dnhasloaded) { + firstNameString = usedname; + } else { + firstNameString = firstname->getString(); + lastNameString = lastname->getString(); } - else - { - if(!dnhasloaded){ - line += usedname; - } - else - { - useddn=true; - line += usedname; - } - } - -// [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Added: RLVa-0.2.0b } else { - line = RlvStrings::getAnonym(line.assign(firstname->getString()).append(" ").append(lastname->getString())); + show_un = false; + firstNameString = RlvStrings::getAnonym(firstname->getString() + std::string(" ") + lastname->getString()); } // [/RLVa:KB] - BOOL need_comma = FALSE; + // set name template + if (mNameFromChatOverride) { + //llinfos << "NEW NAME: '" << mNameFromChatText << "'" << llendl; + line = mNameFromChatText; + } else if (nameplate.empty()) { + if (sRenderGroupTitles) { + line = "%g\n%f %l"; + } else { + // If all group titles are turned off, stack first name + // on a line above last name + line = "%f\n%l"; + } + } + + // replace first name, last name and title + while ((index = line.find("%f")) != std::string::npos) + line.replace(index, 2, firstNameString); + while ((index = line.find("%l")) != std::string::npos) + line.replace(index, 2, lastNameString); + while ((index = line.find("%g")) != std::string::npos) + line.replace(index, 2, titleString); + + // remove empty lines + while ((index = line.find("\r")) != std::string::npos) + line.erase(index, 1); + while (!line.empty() && (line[0] == ' ')) + line.erase(0, 1); + while (!line.empty() && (line[line.size()-1] == ' ')) + line.erase(line.size()-1, 1); + while ((index = line.find(" \n")) != std::string::npos) + line.erase(index, 1); + while ((index = line.find("\n ")) != std::string::npos) + line.erase(index+1, 1); + while (!line.empty() && (line[0] == '\n')) + line.erase(0, 1); + while (!line.empty() && (line[line.size()-1] == '\n')) + line.erase(line.size()-1, 1); + while ((index = line.find("\n\n")) != std::string::npos) + line.erase(index, 1); + + + BOOL need_comma = FALSE; std::string additions; if (client.length() || is_away || is_muted || is_busy) @@ -3912,18 +4007,12 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } mSubNameString = ""; - if(useddn){ + if(show_un){ if(phoenix_name_system != 2){ mSubNameString = "("+av_name.mUsername+")"; } - mRenderedName = av_name.mDisplayName; - } - else - { - mRenderedName = firstname->getString(); - mRenderedName += " "; - mRenderedName += lastname->getString(); } + if (is_appearance) { line += "\n"; @@ -3935,14 +4024,6 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) line += getIdleTime(); } - mNameAway = is_away; - mNameBusy = is_busy; - mNameMute = is_muted; - mClientName = client; - mUsedNameSystem = phoenix_name_system; - mNameAppearance = is_appearance; - mTitle = title ? title->getString() : ""; - LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); mNameString = utf8str_to_wstring(line); new_name = TRUE; } @@ -4903,13 +4984,20 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) return num_indices; } - if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) + LLFace* face = mDrawable->getFace(0); + + bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); + + if (needs_rebuild || mDirtyMesh) { //LOD changed or new mesh created, allocate new vertex buffer if needed + if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4) + { updateMeshData(); - mDirtyMesh = FALSE; + mDirtyMesh = 0; mNeedsSkin = TRUE; mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } + } if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) { @@ -6693,7 +6781,7 @@ BOOL LLVOAvatar::updateJointLODs() if (res) { sNumLODChangesThisFrame++; - dirtyMesh(); + dirtyMesh(2); return TRUE; } } @@ -6728,11 +6816,20 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) mNumInitFaces = mDrawable->getNumFaces() ; - dirtyMesh(); + dirtyMesh(2); return mDrawable; } +void LLVOAvatar::updateGL() +{ + if (mMeshTexturesDirty) + { + updateMeshTextures(); + mMeshTexturesDirty = FALSE; + } +} + //----------------------------------------------------------------------------- // updateGeometry() //----------------------------------------------------------------------------- @@ -6874,9 +6971,12 @@ void LLVOAvatar::updateSexDependentLayerSets( BOOL set_by_user ) //----------------------------------------------------------------------------- void LLVOAvatar::dirtyMesh() { - mDirtyMesh = TRUE; + dirtyMesh(1); +} +void LLVOAvatar::dirtyMesh(S32 priority) +{ + mDirtyMesh = llmax(mDirtyMesh, priority); } - //----------------------------------------------------------------------------- // hideSkirt() //----------------------------------------------------------------------------- @@ -9142,7 +9242,8 @@ void LLVOAvatar::onFirstTEMessageReceived() } } - updateMeshTextures(); + mMeshTexturesDirty = TRUE; + gPipeline.markGLRebuild(this); } } @@ -9227,6 +9328,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) } setCompositeUpdatesEnabled( FALSE ); + mMeshTexturesDirty = TRUE; + gPipeline.markGLRebuild(this); if (!mIsSelf) { @@ -10437,21 +10540,22 @@ void LLVOAvatar::updateFreezeCounter(S32 counter) BOOL LLVOAvatar::updateLOD() { + if (isImpostor()) + { + return TRUE; + } BOOL res = updateJointLODs(); LLFace* facep = mDrawable->getFace(0); - if (facep->mVertexBuffer.isNull() || - (LLVertexBuffer::sEnableVBOs && - ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) != - (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))) + if (facep->mVertexBuffer.isNull()) { - mDirtyMesh = TRUE; + dirtyMesh(2); } - if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) + if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) { //LOD changed or new mesh created, allocate new vertex buffer if needed updateMeshData(); - mDirtyMesh = FALSE; + mDirtyMesh = 0; mNeedsSkin = TRUE; mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index ac5906a44..8c33139da 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -103,6 +103,7 @@ public: // LLViewerObject interface //-------------------------------------------------------------------- public: + virtual void updateGL(); static void initClass(); // Initialize data that's only init'd once per class. static void cleanupClass(); // Cleanup data that's only init'd once per class. static BOOL parseSkeletonFile(const std::string& filename); @@ -246,7 +247,7 @@ public: BOOL isVisible(); BOOL isSelf() const { return mIsSelf; } BOOL isCulled() const { return mCulled; } - + bool isBuilt() const { return mIsBuilt; } public: static void cullAvatarsByPixelArea(); void setVisibilityRank(U32 rank); @@ -269,6 +270,9 @@ public: void startTyping() { mTyping = TRUE; mTypingTimer.reset(); mIdleTimer.reset();} void stopTyping() { mTyping = FALSE; } + void setNameFromChat(const std::string &text) { mNameFromChatOverride = mNameFromChatChanged = true; mNameFromChatText = text; } + void clearNameFromChat() { mNameFromChatOverride = false; mNameFromChatChanged = true; mNameFromChatText = ""; } + // Returns "FirstName LastName" std::string getFullname() const; @@ -295,7 +299,6 @@ public: void processAvatarAppearance( LLMessageSystem* mesgsys ); void onFirstTEMessageReceived(); void updateSexDependentLayerSets( BOOL set_by_user ); - void dirtyMesh(); // Dirty the avatar mesh void hideSkirt(); @@ -660,7 +663,6 @@ private: BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients // LLFrameTimer mUpdateLODTimer; // controls frequency of LOD change calculations - BOOL mDirtyMesh; BOOL mTurning; // controls hysteresis on avatar rotation F32 mSpeed; // misc. animation repeated state @@ -673,7 +675,7 @@ private: BOOL mMeshValid; BOOL mVisible; LLFrameTimer mMeshInvisibleTime; - + // Lip synch morph stuff bool mLipSyncActive; // we're morphing for lip sync LLVisualParam* mOohMorph; // cached pointers morphs for lip sync @@ -702,10 +704,6 @@ private: LLVoiceVisualizer* mVoiceVisualizer; int mCurrentGesticulationLevel; - - - - // Animation timer LLTimer mAnimTimer; F32 mTimeLast; @@ -716,6 +714,10 @@ private: static void resolveClient(LLColor4& avatar_name_color, std::string& client, LLVOAvatar* avatar); friend class LLFloaterAvatarList; + bool mNameFromChatOverride; + bool mNameFromChatChanged; + std::string mNameFromChatText; + std::string mNameFromAttachment; LLPointer mBeam; LLFrameTimer mBeamTimer; @@ -878,6 +880,13 @@ private: static LLVOAvatarSkeletonInfo* sAvatarSkeletonInfo; static LLVOAvatarXmlInfo* sAvatarXmlInfo; +public: + void dirtyMesh(); +private: + void dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority + S32 mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD + BOOL mMeshTexturesDirty; + //----------------------------------------------------------------------------------------------- // Diagnostics //----------------------------------------------------------------------------------------------- diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 3f1c132e7..4f4330b17 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -104,7 +104,10 @@ LLVOCacheEntry::LLVOCacheEntry(LLFILE *fp) LLVOCacheEntry::~LLVOCacheEntry() { - delete [] mBuffer; + if(mBuffer) + { + delete [] mBuffer; + } } diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index ee195af09..a24054b4f 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -123,7 +123,10 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) return TRUE; } - dirtySpatialGroup(); + if (drawable->isVisible()) + { + dirtySpatialGroup(TRUE); + } LLFace *facep; diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 0923483c2..f5c4e9d3c 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -45,6 +45,7 @@ #include "llsurface.h" #include "llsurfacepatch.h" #include "llvosky.h" +#include "llvotree.h" #include "llviewercamera.h" #include "llviewerimagelist.h" #include "llviewerregion.h" @@ -304,6 +305,22 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) return TRUE; } + if(LLVOTree::isTreeRenderingStopped()) //stop rendering grass + { + if(mNumBlades) + { + mNumBlades = 0 ; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); + } + return TRUE ; + } + else if(!mNumBlades)//restart grass rendering + { + mNumBlades = GRASS_MAX_BLADES ; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); + + return TRUE ; + } if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime())) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); @@ -350,7 +367,20 @@ BOOL LLVOGrass::updateLOD() { return FALSE; } - + if(LLVOTree::isTreeRenderingStopped()) + { + if(mNumBlades) + { + mNumBlades = 0 ; + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); + } + return TRUE ; + } + if(!mNumBlades) + { + mNumBlades = GRASS_MAX_BLADES; + } + LLFace* face = mDrawable->getFace(0); F32 tan_angle = 0.f; @@ -396,7 +426,22 @@ BOOL LLVOGrass::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_GRASS); dirtySpatialGroup(); - plantBlades(); + + if(!mNumBlades)//stop rendering grass + { + if (mDrawable->getNumFaces() > 0) + { + LLFace* facep = mDrawable->getFace(0); + if(facep) + { + facep->setSize(0, 0); + } + } + } + else + { + plantBlades(); + } return TRUE; } @@ -437,6 +482,11 @@ void LLVOGrass::getGeometry(S32 idx, LLStrider& colorsp, LLStrider& indicesp) { + if(!mNumBlades)//stop rendering grass + { + return ; + } + mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion()); if (mPatch) mLastPatchUpdateTime = mPatch->getLastUpdateTime(); diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index a0f80689e..b6ba7e50f 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -154,6 +154,11 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) group = drawable->getSpatialGroup(); } + if (group && group->isVisible()) + { + dirtySpatialGroup(TRUE); + } + if (!num_parts) { if (group && drawable->getNumFaces()) @@ -352,12 +357,11 @@ U32 LLVOPartGroup::getPartitionType() const } LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; mPartitionType = LLViewerRegion::PARTITION_PARTICLE; - mBufferUsage = GL_DYNAMIC_DRAW_ARB; mSlopRatio = 0.f; mLODPeriod = 1; } @@ -375,6 +379,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co mFaceList.clear(); + LLViewerCamera* camera = LLViewerCamera::getInstance(); for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) { LLDrawable* drawablep = *i; @@ -404,7 +409,7 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co } count++; - facep->mDistance = (facep->mCenterLocal - LLViewerCamera::getInstance()->getOrigin()) * LLViewerCamera::getInstance()->getAtAxis(); + facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis(); obj->mDepth += facep->mDistance; mFaceList.push_back(facep); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index ff6bba3b3..0443aaaca 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -78,16 +78,9 @@ static const LLVector2 TEX01 = LLVector2(0.f, 1.f); static const LLVector2 TEX10 = LLVector2(1.f, 0.f); static const LLVector2 TEX11 = LLVector2(1.f, 1.f); -// Exported global semi-constants. +// Exported globals LLUUID gSunTextureID = IMG_SUN; LLUUID gMoonTextureID = IMG_MOON; -// Exported global constants. -LLColor3 const gAirScaSeaLevel = calc_air_sca_sea_level(); -F32 const AIR_SCA_INTENS = color_intens(gAirScaSeaLevel); -F32 const AIR_SCA_AVG = AIR_SCA_INTENS / 3.f; - -//static -LLColor3 LLHaze::sAirScaSeaLevel; class LLFastLn { @@ -191,6 +184,23 @@ inline void color_gamma_correct(LLColor3 &col) } } +static LLColor3 calc_air_sca_sea_level() +{ + static LLColor3 WAVE_LEN(675, 520, 445); + static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); + static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); + static LLColor3 n4 = n21 * n21; + static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; + static LLColor3 wl4 = wl2 * wl2; + static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; + static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); + return dens_div_N * color_div ( mult_const, wl4 ); +} + +// static constants. +LLColor3 const LLHaze::sAirScaSeaLevel = calc_air_sca_sea_level(); +F32 const LLHaze::sAirScaIntense = color_intens(LLHaze::sAirScaSeaLevel); +F32 const LLHaze::sAirScaAvg = LLHaze::sAirScaIntense / 3.f; /*************************************** @@ -389,22 +399,21 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) mBloomTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); mHeavenlyBodyUpdated = FALSE ; + + mDrawRefl = 0; + mHazeConcentration = 0.f; + mInterpVal = 0.f; } LLVOSky::~LLVOSky() { - // Don't delete images - it'll get deleted by gImageList on shutdown + // Don't delete images - it'll get deleted by gTextureList on shutdown // This needs to be done for each texture mCubeMap = NULL; } -void LLVOSky::initClass() -{ - LLHaze::initClass(); -} - void LLVOSky::init() { @@ -969,7 +978,7 @@ void LLVOSky::calcAtmospherics(void) // and vary_sunlight will work properly with moon light F32 lighty = unclamped_lightnorm[1]; - if(lighty < NIGHTTIME_ELEVATION_COS) + if(lighty < LLSky::NIGHTTIME_ELEVATION_COS) { lighty = -lighty; } @@ -1080,10 +1089,10 @@ BOOL LLVOSky::updateSky() ++next_frame; next_frame = next_frame % cycle_frame_no; - sInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no; + mInterpVal = (!mInitialized) ? 1 : (F32)next_frame / cycle_frame_no; // sInterpVal = (F32)next_frame / cycle_frame_no; - LLSkyTex::setInterpVal( sInterpVal ); - LLHeavenBody::setInterpVal( sInterpVal ); + LLSkyTex::setInterpVal( mInterpVal ); + LLHeavenBody::setInterpVal( mInterpVal ); calcAtmospherics(); if (mForceUpdate || total_no_tiles == frame) @@ -2151,17 +2160,8 @@ void LLVOSky::updateFog(const F32 distance) stop_glerror(); } -// static -void LLHaze::initClass() -{ - sAirScaSeaLevel = LLHaze::calcAirScaSeaLevel(); -} - - // Functions used a lot. - - F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply) { F32 mv = color_max(col); diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 137082481..19dd1443d 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -147,8 +147,8 @@ protected: static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } - static S32 stepCurrent() { sCurrent++; sCurrent&=1; return sCurrent; } - static S32 getNext() { return ((sCurrent+1) % 2); } + static S32 stepCurrent() { sCurrent++; sCurrent &= 1; return sCurrent; } + static S32 getNext() { return ((sCurrent+1) & 1); } static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } void initEmpty(const S32 tex); @@ -298,24 +298,6 @@ LL_FORCE_INLINE LLColor3 refr_ind_calc(const LLColor3 &wave_length) } -LL_FORCE_INLINE LLColor3 calc_air_sca_sea_level() -{ - const static LLColor3 WAVE_LEN(675, 520, 445); - const static LLColor3 refr_ind = refr_ind_calc(WAVE_LEN); - const static LLColor3 n21 = refr_ind * refr_ind - LLColor3(1, 1, 1); - const static LLColor3 n4 = n21 * n21; - const static LLColor3 wl2 = WAVE_LEN * WAVE_LEN * 1e-6f; - const static LLColor3 wl4 = wl2 * wl2; - const static LLColor3 mult_const = fsigma * 2.0f/ 3.0f * 1e24f * (F_PI * F_PI) * n4; - const static F32 dens_div_N = F32( ATM_SEA_LEVEL_NDENS / Ndens2); - return dens_div_N * color_div ( mult_const, wl4 ); -} - -// Non-POD constants. -extern LLColor3 const gAirScaSeaLevel; -extern F32 const AIR_SCA_INTENS; -extern F32 const AIR_SCA_AVG; - class LLHaze { public: @@ -323,18 +305,15 @@ public: LLHaze(const F32 g, const LLColor3& sca, const F32 fo = 2.f) : mG(g), mSigSca(0.25f/F_PI * sca), mFalloff(fo), mAbsCoef(0.f) { - mAbsCoef = color_intens(mSigSca) / AIR_SCA_INTENS; + mAbsCoef = color_intens(mSigSca) / sAirScaIntense; } LLHaze(const F32 g, const F32 sca, const F32 fo = 2.f) : mG(g), mSigSca(0.25f/F_PI * LLColor3(sca, sca, sca)), mFalloff(fo) { - mAbsCoef = 0.01f * sca / AIR_SCA_AVG; + mAbsCoef = 0.01f * sca / sAirScaAvg; } - static void initClass(); - - F32 getG() const { return mG; } void setG(const F32 g) @@ -350,12 +329,12 @@ public: void setSigSca(const LLColor3& s) { mSigSca = s; - mAbsCoef = 0.01f * color_intens(mSigSca) / AIR_SCA_INTENS; + mAbsCoef = 0.01f * color_intens(mSigSca) / sAirScaIntense; } void setSigSca(const F32 s0, const F32 s1, const F32 s2) { - mSigSca = AIR_SCA_AVG * LLColor3 (s0, s1, s2); + mSigSca = sAirScaAvg * LLColor3 (s0, s1, s2); mAbsCoef = 0.01f * (s0 + s1 + s2) / 3; } @@ -399,10 +378,11 @@ public: static inline LLColor3 calcAirSca(const F32 h); static inline void calcAirSca(const F32 h, LLColor3 &result); - static LLColor3 calcAirScaSeaLevel() { return gAirScaSeaLevel; } - static const LLColor3 &getAirScaSeaLevel() { return sAirScaSeaLevel; } -public: - static LLColor3 sAirScaSeaLevel; + +private: + static LLColor3 const sAirScaSeaLevel; + static F32 const sAirScaIntense; + static F32 const sAirScaAvg; protected: F32 mG; @@ -480,7 +460,6 @@ public: LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); // Initialize/delete data that's only inited once per class. - static void initClass(); void init(); void initCubeMap(); void initEmpty(); @@ -614,7 +593,7 @@ protected: LLColor3 mLastTotalAmbient; F32 mAmbientScale; LLColor3 mNightColorShift; - F32 sInterpVal; + F32 mInterpVal; LLColor4 mFogColor; LLColor4 mGLFogCol; @@ -661,14 +640,12 @@ F32 color_norm_pow(LLColor3& col, F32 e, BOOL postmultiply = FALSE); inline LLColor3 LLHaze::calcAirSca(const F32 h) { - static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel(); - return calcFalloff(h) * air_sca_sea_level; + return calcFalloff(h) * sAirScaSeaLevel; } inline void LLHaze::calcAirSca(const F32 h, LLColor3 &result) { - static const LLColor3 air_sca_sea_level = calcAirScaSeaLevel(); - result = air_sca_sea_level; + result = sAirScaSeaLevel; result *= calcFalloff(h); } diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 1671880ba..0cb390f02 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -177,11 +177,19 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline) } +void LLVOSurfacePatch::updateGL() +{ + if (mPatchp) + { + mPatchp->updateGL(); + } +} + BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN); - dirtySpatialGroup(); + dirtySpatialGroup(TRUE); S32 min_comp, max_comp, range; min_comp = lltrunc(mPatchp->getMinComposition()); @@ -1013,12 +1021,10 @@ U32 LLVOSurfacePatch::getPartitionType() const } LLTerrainPartition::LLTerrainPartition() -: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK) +: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB) { mOcclusionEnabled = FALSE; - mRenderByGroup = FALSE; mInfiniteFarClip = TRUE; - mBufferUsage = GL_DYNAMIC_DRAW_ARB; mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN; mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h index d3b144774..10a588852 100644 --- a/indra/newview/llvosurfacepatch.h +++ b/indra/newview/llvosurfacepatch.h @@ -64,6 +64,7 @@ public: virtual U32 getPartitionType() const; /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); + /*virtual*/ void updateGL(); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); /*virtual*/ void updateFaceSize(S32 idx); diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index b5481d100..2c6fa925a 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -101,6 +101,12 @@ LLVOTree::~LLVOTree() } } +//static +bool LLVOTree::isTreeRenderingStopped() +{ + return LLVOTree::sTreeFactor < LLVOTree::sLODAngles[4 - 1] ; +} + // static void LLVOTree::initClass() { @@ -1324,9 +1330,8 @@ U32 LLVOTree::getPartitionType() const } LLTreePartition::LLTreePartition() -: LLSpatialPartition(0) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; mSlopRatio = 0.f; diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h index 6de872ae6..133f39352 100644 --- a/indra/newview/llvotree.h +++ b/indra/newview/llvotree.h @@ -59,6 +59,7 @@ public: // Initialize data that's only inited once per class. static void initClass(); static void cleanupClass(); + static bool isTreeRenderingStopped(); /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f0da8ddba..bfe218d4c 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -87,8 +87,10 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mRelativeXform.setIdentity(); mRelativeXformInvTrans.setIdentity(); + mFaceMappingChanged = FALSE; mLOD = MIN_LOD; mTextureAnimp = NULL; + mVolumeChanged = FALSE; mVObjRadius = LLVector3(1,1,0.5f).length(); mNumFaces = 0; mLODChanged = FALSE; @@ -104,6 +106,20 @@ LLVOVolume::~LLVOVolume() mVolumeImpl = NULL; } +void LLVOVolume::markDead() +{ + if (!mDead) + { + + if (mSculptTexture.notNull()) + { + mSculptTexture->removeVolume(this); + } + } + + LLViewerObject::markDead(); +} + // static void LLVOVolume::initClass() @@ -407,6 +423,18 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) mVolumeImpl->doIdleUpdate(agent, world, time); } + const S32 MAX_ACTIVE_OBJECT_QUIET_FRAMES = 40; + + if (mDrawable->isActive()) + { + if (mDrawable->isRoot() && + mDrawable->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES && + (!mDrawable->getParent() || !mDrawable->getParent()->isActive())) + { + mDrawable->makeStatic(); + } + } + return TRUE; } @@ -443,9 +471,9 @@ void LLVOVolume::updateTextureVirtualSize() { // Update the pixel area of all faces - if(mDrawable.isNull() || !mDrawable->isVisible()) + if(!isVisible()) { - return ; + return; } if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) @@ -465,6 +493,7 @@ void LLVOVolume::updateTextureVirtualSize() const S32 num_faces = mDrawable->getNumFaces(); F32 min_vsize=999999999.f, max_vsize=0.f; + LLViewerCamera* camera = LLViewerCamera::getInstance(); for (S32 i = 0; i < num_faces; i++) { LLFace* face = mDrawable->getFace(i); @@ -485,6 +514,7 @@ void LLVOVolume::updateTextureVirtualSize() vsize = area; imagep->setBoostLevel(LLViewerImageBoostLevel::BOOST_HUD); face->setPixelArea(area); // treat as full screen + face->setVirtualSize(vsize); } else { @@ -513,8 +543,7 @@ void LLVOVolume::updateTextureVirtualSize() gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, FALSE); } } - - face->setVirtualSize(vsize); + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { if (vsize < min_vsize) min_vsize = vsize; @@ -554,9 +583,9 @@ void LLVOVolume::updateTextureVirtualSize() //if the sculpty very close to the view point, load first { - LLVector3 lookAt = getPositionAgent() - LLViewerCamera::getInstance()->getOrigin(); + LLVector3 lookAt = getPositionAgent() - camera->getOrigin(); F32 dist = lookAt.normVec() ; - F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; + F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ; mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ; } } @@ -719,6 +748,8 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail if (isSculpted()) { + updateSculptTexture(); + if (mSculptTexture.notNull()) { sculpt(); @@ -850,9 +881,6 @@ BOOL LLVOVolume::calcLOD() return FALSE; } - //update face texture sizes on lod calculation - updateTextureVirtualSize(); - S32 cur_detail = 0; F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length(); @@ -1163,7 +1191,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) return res; } - dirtySpatialGroup(); + dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1)); BOOL compiled = FALSE; @@ -2124,7 +2152,7 @@ U32 LLVOVolume::getPartitionType() const } LLVolumePartition::LLVolumePartition() -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, FALSE) +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) { mLODPeriod = 16; mDepthMask = FALSE; @@ -2135,7 +2163,7 @@ LLVolumePartition::LLVolumePartition() } LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) -: LLSpatialBridge(drawablep, LLVOVolume::VERTEX_DATA_MASK) +: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK) { mDepthMask = FALSE; mLODPeriod = 16; @@ -2169,6 +2197,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || (type == LLRenderPass::PASS_INVISIBLE) || (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); + + if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL)) + { + llwarns << "Non fullbright face has no normals!" << llendl; + return; + } const LLMatrix4* tex_mat = NULL; if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) @@ -2481,7 +2515,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (LLPipeline::sDelayVBUpdate) { - group->setState(LLSpatialGroup::MESH_DIRTY); + group->setState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } mFaceList.clear(); @@ -2572,7 +2606,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } } - group->clearState(LLSpatialGroup::MESH_DIRTY); + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } } @@ -2752,74 +2786,77 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } } else if (gPipeline.canUseVertexShaders() + && group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD && LLPipeline::sRenderBump && te->getShiny()) - { + { //shiny if (tex->getPrimaryFormat() == GL_ALPHA) - { + { //invisiprim+shiny registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); } else if (LLPipeline::sRenderDeferred) - { + { //deferred rendering if (te->getBumpmap()) - { + { //register in deferred bump pass registerFace(group, facep, LLRenderPass::PASS_BUMP); } else if (te->getFullbright()) - { + { //register in post deferred fullbright shiny pass registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); } else - { + { //register in deferred simple pass (deferred simple includes shiny) llassert(mask & LLVertexBuffer::MAP_NORMAL); registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } } else if (fullbright) - { + { //not deferred, register in standard fullbright shiny pass registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); } else - { + { //not deferred or fullbright, register in standard shiny pass registerFace(group, facep, LLRenderPass::PASS_SHINY); } } else - { + { //not alpha and not shiny if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) - { + { //invisiprim registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); } else if (fullbright) - { + { //fullbright registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); } else { - if (LLPipeline::sRenderDeferred && te->getBumpmap()) - { + if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap()) + { //non-shiny or fullbright deferred bump registerFace(group, facep, LLRenderPass::PASS_BUMP); } else - { + { //all around simple llassert(mask & LLVertexBuffer::MAP_NORMAL); registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } } - if (!is_alpha && te->getShiny()) + //not sure why this is here -- shiny HUD attachments maybe? -- davep 5/11/2010 + if (!is_alpha && te->getShiny() && LLPipeline::sRenderBump) { registerFace(group, facep, LLRenderPass::PASS_SHINY); } } + //not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010 if (!is_alpha && !LLPipeline::sRenderDeferred) { llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); - if (!force_simple && te->getBumpmap()) + if (!force_simple && te->getBumpmap() && LLPipeline::sRenderBump) { registerFace(group, facep, LLRenderPass::PASS_BUMP); } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 5935316e4..371a01d5d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -92,6 +92,7 @@ public: public: LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); + /*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 501f3c2da..f53654179 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -69,8 +69,9 @@ const U32 WIDTH = (N_RES * WAVE_STEP); //128.f //64 // width of wave tile, in const F32 WAVE_STEP_INV = (1. / WAVE_STEP); -LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) -: LLStaticViewerObject(id, pcode, regionp) +LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : + LLStaticViewerObject(id, pcode, regionp), + mRenderType(LLPipeline::RENDER_TYPE_WATER) { // Terrain must draw during selection passes so it can block objects behind it. mbCanSelect = FALSE; @@ -78,9 +79,9 @@ LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regi mUseTexture = TRUE; mIsEdgePatch = FALSE; - mRenderType = LLPipeline::RENDER_TYPE_WATER; } + void LLVOWater::markDead() { LLViewerObject::markDead(); @@ -281,9 +282,8 @@ U32 LLVOVoidWater::getPartitionType() const } LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; mPartitionType = LLViewerRegion::PARTITION_WATER; diff --git a/indra/newview/llvowater.h b/indra/newview/llvowater.h index 55ce6d789..30753daa3 100644 --- a/indra/newview/llvowater.h +++ b/indra/newview/llvowater.h @@ -72,7 +72,7 @@ public: /*virtual*/ void updateTextures(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area - /*virtual*/ U32 getPartitionType() const; + virtual U32 getPartitionType() const; /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index abd25e659..8d63b069c 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -49,12 +49,12 @@ const U32 LLVOWLSky::MAX_SKY_DETAIL = 180; inline U32 LLVOWLSky::getNumStacks(void) { - return gSavedSettings.getU32("WLSkyDetail"); + return llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail"))); } inline U32 LLVOWLSky::getNumSlices(void) { - return 2 * gSavedSettings.getU32("WLSkyDetail"); + return 2 * llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail"))); } inline U32 LLVOWLSky::getFanNumVerts(void) @@ -489,7 +489,7 @@ void LLVOWLSky::drawStars(void) if (mStarsVerts.notNull()) { mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); - mStarsVerts->draw(LLRender::POINTS, getStarsNumIndices(), 0); + mStarsVerts->drawArrays(LLRender::QUADS, 0, getStarsNumVerts()*4); } } @@ -769,17 +769,17 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) { LLStrider verticesp; LLStrider colorsp; - LLStrider indicesp; + LLStrider texcoordsp; if (mStarsVerts.isNull()) { mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); - mStarsVerts->allocateBuffer(getStarsNumVerts(), getStarsNumIndices(), TRUE); + mStarsVerts->allocateBuffer(getStarsNumVerts()*4, 0, TRUE); } BOOL success = mStarsVerts->getVertexStrider(verticesp) - && mStarsVerts->getIndexStrider(indicesp) - && mStarsVerts->getColorStrider(colorsp); + && mStarsVerts->getColorStrider(colorsp) + && mStarsVerts->getTexCoord0Strider(texcoordsp); if(!success) { @@ -789,11 +789,37 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) // *TODO: fix LLStrider with a real prefix increment operator so it can be // used as a model of OutputIterator. -Brad // std::copy(mStarVertices.begin(), mStarVertices.end(), verticesp); + + if (mStarVertices.size() < getStarsNumVerts()) + { + llerrs << "Star reference geometry insufficient." << llendl; + } + for (U32 vtx = 0; vtx < getStarsNumVerts(); ++vtx) { + LLVector3 at = mStarVertices[vtx]; + at.normVec(); + LLVector3 left = at%LLVector3(0,0,1); + LLVector3 up = at%left; + + F32 sc = 0.5f+ll_frand()*1.25f; + left *= sc; + up *= sc; + *(verticesp++) = mStarVertices[vtx]; + *(verticesp++) = mStarVertices[vtx]+left; + *(verticesp++) = mStarVertices[vtx]+left+up; + *(verticesp++) = mStarVertices[vtx]+up; + + *(texcoordsp++) = LLVector2(0,0); + *(texcoordsp++) = LLVector2(0,1); + *(texcoordsp++) = LLVector2(1,1); + *(texcoordsp++) = LLVector2(1,0); + + *(colorsp++) = LLColor4U(mStarColors[vtx]); + *(colorsp++) = LLColor4U(mStarColors[vtx]); + *(colorsp++) = LLColor4U(mStarColors[vtx]); *(colorsp++) = LLColor4U(mStarColors[vtx]); - *(indicesp++) = vtx; } mStarsVerts->setBuffer(0); diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 50e407739..848c8137f 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -301,7 +301,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam) mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); LLVector3 sunMoonDir; - if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) { sunMoonDir = gSky.getSunDirection(); } diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index c4d146664..dfe921667 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -315,7 +315,7 @@ void LLWLParamManager::propagateParameters(void) { mLightDir = sunDir; } - else if(sunDir.mV[1] < 0 && sunDir.mV[1] > NIGHTTIME_ELEVATION_COS) + else if(sunDir.mV[1] < 0 && sunDir.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS) { // clamp v1 to 0 so sun never points up and causes weirdness on some machines LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index ad6a702dd..21ab8e598 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -259,7 +259,10 @@ BOOL LLPipeline::sRenderFrameTest = FALSE; BOOL LLPipeline::sRenderAttachedLights = TRUE; BOOL LLPipeline::sRenderAttachedParticles = TRUE; BOOL LLPipeline::sRenderDeferred = FALSE; +BOOL LLPipeline::sAllowRebuildPriorityGroup = FALSE ; S32 LLPipeline::sVisibleLightCount = 0; +F32 LLPipeline::sMinRenderSize = 0.f; + static LLCullResult* sCull = NULL; @@ -300,7 +303,6 @@ LLPipeline::LLPipeline() : mInitialized(FALSE), mVertexShadersEnabled(FALSE), mVertexShadersLoaded(0), - mRenderTypeMask(0), mRenderDebugFeatureMask(0), mRenderDebugMask(0), mOldRenderDebugMask(0), @@ -350,7 +352,11 @@ void LLPipeline::init() mTrianglesDrawnStat.reset(); resetFrameStats(); - mRenderTypeMask = 0xffffffff; // All render types start on + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled + } + mRenderDebugFeatureMask = 0xffffffff; // All debugging features on mRenderDebugMask = 0; // All debug starts off @@ -383,6 +389,9 @@ void LLPipeline::cleanup() { assertInitialized(); + mGroupQ1.clear() ; + mGroupQ2.clear() ; + for(pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ) { @@ -963,6 +972,10 @@ void LLPipeline::addPool(LLDrawPool *new_poolp) void LLPipeline::allocDrawable(LLViewerObject *vobj) { + if(!vobj) + { + llerrs << "Null object passed to allocDrawable!" << llendl; + } LLMemType mt(LLMemType::MTYPE_DRAWABLE); LLDrawable *drawable = new LLDrawable(); vobj->mDrawable = drawable; @@ -1237,28 +1250,8 @@ void LLPipeline::updateMove() } } mRetexturedList.clear(); - - updateMovedList(mMovedList); - - for (LLDrawable::drawable_set_t::iterator iter = mActiveQ.begin(); - iter != mActiveQ.end(); ) { - LLDrawable::drawable_set_t::iterator curiter = iter++; - LLDrawable* drawablep = *curiter; - if (drawablep && !drawablep->isDead()) - { - if (drawablep->isRoot() && - drawablep->mQuietCount++ > MAX_ACTIVE_OBJECT_QUIET_FRAMES && - (!drawablep->getParent() || !drawablep->getParent()->isActive())) - { - drawablep->makeStatic(); // removes drawable and its children from mActiveQ - iter = mActiveQ.upper_bound(drawablep); // next valid entry - } - } - else - { - mActiveQ.erase(curiter); - } + updateMovedList(mMovedList); } //balance octrees @@ -1342,6 +1335,8 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& min = LLVector3(F32_MAX, F32_MAX, F32_MAX); max = LLVector3(-F32_MAX, -F32_MAX, -F32_MAX); + U32 saved_camera_id = LLViewerCamera::sCurCameraID; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; BOOL res = TRUE; @@ -1366,6 +1361,8 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& } } + LLViewerCamera::sCurCameraID = saved_camera_id; + return res; } @@ -1381,8 +1378,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl BOOL to_texture = LLPipeline::sUseOcclusion > 1 && !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && - !sReflectionRender && - !sShadowRender && + LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && gPipeline.canUseVertexShaders() && sRenderGlow; @@ -1391,9 +1387,12 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl mScreen.bindTarget(); } + /*glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixd(gGLLastProjection); + glMatrixMode(GL_MODELVIEW);*/ glPushMatrix(); gGLLastMatrix = NULL; - //glLoadMatrixd(gGLModelView); glLoadMatrixd(gGLLastModelView); LLVertexBuffer::unbind(); @@ -1459,6 +1458,9 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } + /*glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW);*/ glPopMatrix(); if (sUseOcclusion > 1) @@ -1470,10 +1472,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl { mScreen.flush(); } - else if (LLPipeline::sUseOcclusion > 1) + /*else if (LLPipeline::sUseOcclusion > 1) { glFlush(); - } + }*/ } void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) @@ -1485,7 +1487,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) group->setVisible(); - if (!sSkipUpdate) + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { group->updateDistance(camera); } @@ -1497,6 +1499,12 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) return; } + if (sMinRenderSize > 0.f && + llmax(llmax(group->mBounds[1].mV[0], group->mBounds[1].mV[1]), group->mBounds[1].mV[2]) < sMinRenderSize) + { + return; + } + assertInitialized(); if (!group->mSpatialPartition->mRenderByGroup) @@ -1513,22 +1521,22 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::markOccluder(LLSpatialGroup* group) { - if (sUseOcclusion > 1 && group && !group->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) + if (sUseOcclusion > 1 && group && !group->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION)) { LLSpatialGroup* parent = group->getParent(); - if (!parent || !parent->isState(LLSpatialGroup::OCCLUDED)) + if (!parent || !parent->isOcclusionState(LLSpatialGroup::OCCLUDED)) { //only mark top most occluders as active occlusion sCull->pushOcclusionGroup(group); - group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); + group->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); if (parent && - !parent->isState(LLSpatialGroup::ACTIVE_OCCLUSION) && + !parent->isOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION) && parent->getElementCount() == 0 && parent->needsUpdate()) { sCull->pushOcclusionGroup(group); - parent->setState(LLSpatialGroup::ACTIVE_OCCLUSION); + parent->setOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); } } } @@ -1558,7 +1566,7 @@ void LLPipeline::doOcclusion(LLCamera& camera) { LLSpatialGroup* group = *iter; group->doOcclusion(&camera); - group->clearState(LLSpatialGroup::ACTIVE_OCCLUSION); + group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); } } @@ -1576,6 +1584,84 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) return update_complete; } +void LLPipeline::updateGL() +{ + while (!LLGLUpdate::sGLQ.empty()) + { + LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); + glu->updateGL(); + glu->mInQ = FALSE; + LLGLUpdate::sGLQ.pop_front(); + } +} + +void LLPipeline::rebuildPriorityGroups() +{ + if(!sAllowRebuildPriorityGroup) + { + return ; + } + sAllowRebuildPriorityGroup = FALSE ; + + LLTimer update_timer; + LLMemType mt(LLMemType::MTYPE_PIPELINE); + + assertInitialized(); + + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + group->rebuildGeom(); + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + + mGroupQ1.clear(); +} + +void LLPipeline::rebuildGroups() +{ + // Iterate through some drawables on the non-priority build queue + S32 size = (S32) mGroupQ2.size(); + S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); + + S32 count = 0; + + std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); + + LLSpatialGroup::sg_vector_t::iterator iter; + for (iter = mGroupQ2.begin(); + iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + if (group->isDead()) + { + continue; + } + + group->rebuildGeom(); + + if (group->mSpatialPartition->mRenderByGroup) + { + count++; + } + + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + + if (count > min_count) + { + ++iter; + break; + } + } + + mGroupQ2.erase(mGroupQ2.begin(), iter); + + updateMovedList(mMovedBridge); +} + void LLPipeline::updateGeom(F32 max_dtime) { LLTimer update_timer; @@ -1839,6 +1925,59 @@ void LLPipeline::markTextured(LLDrawable *drawablep) } } +void LLPipeline::markGLRebuild(LLGLUpdate* glu) +{ + if (glu && !glu->mInQ) + { + LLGLUpdate::sGLQ.push_back(glu); + glu->mInQ = TRUE; + } +} + +void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) +{ + LLMemType mt(LLMemType::MTYPE_PIPELINE); + //assert_main_thread(); + + if (group && !group->isDead() && group->mSpatialPartition) + { + if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD) + { + priority = TRUE; + } + + if (priority) + { + if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) + { + mGroupQ1.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q1); + + if (group->isState(LLSpatialGroup::IN_BUILD_Q2)) + { + LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group); + if (iter != mGroupQ2.end()) + { + mGroupQ2.erase(iter); + } + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + } + } + else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) + { + //llerrs << "Non-priority updates not yet supported!" << llendl; + if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) + { + llerrs << "WTF?" << llendl; + } + mGroupQ2.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q2); + + } + } +} + void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -1872,15 +2011,14 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { - const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) | - (1 << LLPipeline::RENDER_TYPE_GROUND) | - (1 << LLPipeline::RENDER_TYPE_TERRAIN) | - (1 << LLPipeline::RENDER_TYPE_TREE) | - (1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_VOIDWATER) | - (1 << LLPipeline::RENDER_TYPE_WATER); - - if (mRenderTypeMask & face_mask) + if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::END_RENDER_TYPES)) { //clear faces from face pools LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER); @@ -1893,55 +2031,51 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) //LLVertexBuffer::unbind(); grabReferences(result); - + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { - for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + LLSpatialGroup* group = *iter; + group->checkOcclusion(); + if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { - LLSpatialGroup* group = *iter; - group->checkOcclusion(); - if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) - { - markOccluder(group); - } - else - { - group->setVisible(); - for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) - { - markVisible(*i, camera); - } - } + markOccluder(group); } - - for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + else { - LLSpatialGroup* group = *iter; - group->checkOcclusion(); - if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) + group->setVisible(); + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) { - markOccluder(group); - } - else - { - group->setVisible(); - stateSort(group, camera); + markVisible(*i, camera); } } } - + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + group->checkOcclusion(); + if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + markOccluder(group); + } + else + { + group->setVisible(); + stateSort(group, camera); + } + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLCullResult::bridge_list_t::iterator cur_iter = i; LLSpatialBridge* bridge = *cur_iter; LLSpatialGroup* group = bridge->getSpatialGroup(); - if (!bridge->isDead() && group && !group->isState(LLSpatialGroup::OCCLUDED)) + if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { stateSort(bridge, camera); } } } - { LLFastTimer ftm(LLFastTimer::FTM_STATESORT_DRAWABLE); for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); @@ -1980,7 +2114,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) + if (!sShadowRender && !sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2042,21 +2176,24 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - LLSpatialGroup* group = drawablep->getSpatialGroup(); - if (!group || group->changeLOD()) + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { - if (drawablep->isVisible() && !sSkipUpdate) + LLSpatialGroup* group = drawablep->getSpatialGroup(); + if (!group || group->changeLOD()) { - if (!drawablep->isActive()) + if (drawablep->isVisible() && !sSkipUpdate) { - bool force_update = false; - drawablep->updateDistance(camera, force_update); + if (!drawablep->isActive()) + { + bool force_update = false; + drawablep->updateDistance(camera, force_update); + } + else if (drawablep->isAvatar()) + { + bool force_update = false; + drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() + } } - else if (drawablep->isAvatar()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() - } } } @@ -2080,6 +2217,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } } + mNumVisibleFaces += drawablep->getNumFaces(); } @@ -2236,7 +2374,7 @@ void LLPipeline::postSort(LLCamera& camera) { LLSpatialGroup* group = *i; if (!sUseOcclusion || - !group->isState(LLSpatialGroup::OCCLUDED)) + !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { group->rebuildGeom(); } @@ -2245,7 +2383,7 @@ void LLPipeline::postSort(LLCamera& camera) //rebuild groups sCull->assertDrawMapsEmpty(); - LLSpatialGroup::sNoDelete = FALSE; + /*LLSpatialGroup::sNoDelete = FALSE; for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; @@ -2257,9 +2395,12 @@ void LLPipeline::postSort(LLCamera& camera) group->rebuildGeom(); } - LLSpatialGroup::sNoDelete = TRUE; - + LLSpatialGroup::sNoDelete = TRUE;*/ + rebuildPriorityGroups(); + + + const S32 bin_count = 1024*8; static LLCullResult::drawinfo_list_t alpha_bins[bin_count]; @@ -2280,50 +2421,67 @@ void LLPipeline::postSort(LLCamera& camera) { LLSpatialGroup* group = *i; if (sUseOcclusion && - group->isState(LLSpatialGroup::OCCLUDED)) + group->isOcclusionState(LLSpatialGroup::OCCLUDED)) { continue; } - + + if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY)) + { //no way this group is going to be drawable without a rebuild + group->rebuildGeom(); + } + for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) { LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - /*if (!hasRenderType(j->first)) //No worky yet. + if (!hasRenderType(j->first)) { continue; - }*/ + } for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) { - sCull->pushDrawInfo(j->first, *k); - } - } - - - LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); - - if (alpha != group->mDrawMap.end()) - { //store alpha groups for sorting - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); - if (!sSkipUpdate) - { - if (bridge) + if (sMinRenderSize > 0.f) { - LLCamera trans_camera = bridge->transformCamera(camera); - group->updateDistance(trans_camera); + LLVector3 bounds = (*k)->mExtents[1]-(*k)->mExtents[0]; + if (llmax(llmax(bounds.mV[0], bounds.mV[1]), bounds.mV[2]) > sMinRenderSize) + { + sCull->pushDrawInfo(j->first, *k); + } } else { - group->updateDistance(camera); + sCull->pushDrawInfo(j->first, *k); } } + } + + if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) + { + LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); - if (hasRenderType(LLDrawPool::POOL_ALPHA)) - { - sCull->pushAlphaGroup(group); + if (alpha != group->mDrawMap.end()) + { //store alpha groups for sorting + LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + if (bridge) + { + LLCamera trans_camera = bridge->transformCamera(camera); + group->updateDistance(trans_camera); + } + else + { + group->updateDistance(camera); + } + } + + if (hasRenderType(LLDrawPool::POOL_ALPHA)) + { + sCull->pushAlphaGroup(group); + } } } - } if (!sShadowRender) @@ -2421,7 +2579,7 @@ void LLPipeline::postSort(LLCamera& camera) } } - LLSpatialGroup::sNoDelete = FALSE; + //LLSpatialGroup::sNoDelete = FALSE; } @@ -3032,6 +3190,8 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); doOcclusion(camera); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); } } @@ -3823,7 +3983,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) } } F32 backlight_mag; - if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) { backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; } @@ -4012,7 +4172,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) // Light 0 = Sun or Moon (All objects) { - if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) { mSunDir.setVec(gSky.getSunDirection()); mSunDiffuse.setVec(gSky.getSunDiffuseColor()); @@ -4278,10 +4438,10 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) enableLights(mask); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); - if (mLightingDetail >= 2) + /*if (mLightingDetail >= 2) { glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - } + }*/ } void LLPipeline::disableLights() @@ -4318,10 +4478,6 @@ void LLPipeline::findReferences(LLDrawable *drawablep) llinfos << "In mRetexturedList" << llendl; } - if (mActiveQ.find(drawablep) != mActiveQ.end()) - { - llinfos << "In mActiveQ" << llendl; - } if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end()) { llinfos << "In mBuildQ1" << llendl; @@ -4478,28 +4634,13 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) } } -void LLPipeline::setActive(LLDrawable *drawablep, BOOL active) -{ - assertInitialized(); - if (active) - { - mActiveQ.insert(drawablep); - } - else - { - mActiveQ.erase(drawablep); - } -} - //static void LLPipeline::toggleRenderType(U32 type) { - U32 bit = (1<getNear()*2.f); shader.uniform1f("alpha_soften", render_deferred_alpha_soft); + if (shader.getUniformLocation("norm_mat") >= 0) + { + glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); + shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m); + } } void LLPipeline::renderDeferredLighting() @@ -5528,6 +5700,7 @@ void LLPipeline::renderDeferredLighting() return; } + LLViewerCamera* camera = LLViewerCamera::getInstance(); LLGLEnable multisample(GL_MULTISAMPLE_ARB); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -5542,15 +5715,13 @@ void LLPipeline::renderDeferredLighting() gGL.setColorMask(true, true); - mDeferredLight[0].bindTarget(); - //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); //draw a cube around every light LLVertexBuffer::unbind(); - glBlendFunc(GL_ONE, GL_ONE); + //glBlendFunc(GL_ONE, GL_ONE); LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); @@ -5562,126 +5733,130 @@ void LLPipeline::renderDeferredLighting() -1,-3, 3,1, }; + glVertexPointer(2, GL_FLOAT, 0, vert); + glColor3f(1,1,1); - bindDeferredShader(gDeferredSunProgram); - - glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); - - const U32 slice = 32; - F32 offset[slice*3]; - for (U32 i = 0; i < 4; i++) { - for (U32 j = 0; j < 8; j++) - { - glh::vec3f v; - v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); - v.normalize(); - inv_trans.mult_matrix_vec(v); - v.normalize(); - offset[(i*8+j)*3+0] = v.v[0]; - offset[(i*8+j)*3+1] = v.v[2]; - offset[(i*8+j)*3+2] = v.v[1]; - } + setupHWLights(NULL); //to set mSunDir; + LLVector4 dir(mSunDir, 0.f); + glh::vec4f tc(dir.mV); + mat.mult_matrix_vec(tc); + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); } - gDeferredSunProgram.uniform3fv("offset", slice, offset); - gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); - - setupHWLights(NULL); //to set mSunDir; - glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - LLVector4 dir(mSunDir, 0.f); - - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); - glColor3f(1,1,1); - - glVertexPointer(2, GL_FLOAT, 0, vert); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - unbindDeferredShader(gDeferredSunProgram); - - mDeferredLight[0].flush(); - - //blur lightmap - mDeferredLight[1].bindTarget(); - - //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - - bindDeferredShader(gDeferredBlurLightProgram); - - LLVector3 gauss[32]; // xweight, yweight, offset - - LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); - U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; - F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); - - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = -(kern_length/2.0f) + 0.5f; - - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.mV[0]); - gauss[i].mV[1] = llgaussian(x, go.mV[1]); - gauss[i].mV[2] = x; - x += 1.f; - } - /* swap the x=0 position to the start of gauss[] so we can - treat it specially as an optimization. */ - LLVector3 swap; - swap = gauss[kern_length/2]; - gauss[kern_length/2] = gauss[0]; - gauss[0] = swap; - llassert(gauss[0].mV[2] == 0.0f); - - gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - mDeferredLight[1].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); - - bindDeferredShader(gDeferredBlurLightProgram, 1); mDeferredLight[0].bindTarget(); - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - + //Sun shadows. { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - stop_glerror(); + bindDeferredShader(gDeferredSunProgram); + + glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + + const U32 slice = 32; + F32 offset[slice*3]; + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 8; j++) + { + glh::vec3f v; + v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); + v.normalize(); + inv_trans.mult_matrix_vec(v); + v.normalize(); + offset[(i*8+j)*3+0] = v.v[0]; + offset[(i*8+j)*3+1] = v.v[2]; + offset[(i*8+j)*3+2] = v.v[1]; + } + } + + gDeferredSunProgram.uniform3fv("offset", slice, offset); + gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + unbindDeferredShader(gDeferredSunProgram); } + mDeferredLight[0].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + + //SSAO + { + //blur lightmap + mDeferredLight[1].bindTarget(); + + //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), + // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); + + bindDeferredShader(gDeferredBlurLightProgram); + + LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); + U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; + F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); + + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = -(kern_length/2.0f) + 0.5f; + + LLVector3 gauss[32]; // xweight, yweight, offset + + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.mV[0]); + gauss[i].mV[1] = llgaussian(x, go.mV[1]); + gauss[i].mV[2] = x; + x += 1.f; + } + /* swap the x=0 position to the start of gauss[] so we can + treat it specially as an optimization. */ + LLVector3 swap; + swap = gauss[kern_length/2]; + gauss[kern_length/2] = gauss[0]; + gauss[0] = swap; + llassert(gauss[0].mV[2] == 0.0f); + + gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); + gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + mDeferredLight[1].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + + bindDeferredShader(gDeferredBlurLightProgram, 1); + mDeferredLight[0].bindTarget(); + + gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + stop_glerror(); + } + mDeferredLight[0].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + } stop_glerror(); glPopMatrix(); @@ -5696,6 +5871,8 @@ void LLPipeline::renderDeferredLighting() // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); mScreen.bindTarget(); + // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); mScreen.clear(GL_COLOR_BUFFER_BIT); bindDeferredShader(gDeferredSoftenProgram); @@ -5722,7 +5899,23 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSoftenProgram); - bindDeferredShader(gDeferredLightProgram); + + { //render sky + LLGLDisable blend(GL_BLEND); + LLGLDisable stencil(GL_STENCIL_TEST); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + gPipeline.pushRenderTypeMask(); + + gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_WL_CLOUDS, + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::END_RENDER_TYPES); + + + renderGeomPostDeferred(*LLViewerCamera::getInstance()); + gPipeline.popRenderTypeMask(); + } std::list fullscreen_lights; std::list light_colors; @@ -5730,6 +5923,7 @@ void LLPipeline::renderDeferredLighting() F32 v[24]; glVertexPointer(3, GL_FLOAT, 0, v); { + bindDeferredShader(gDeferredLightProgram); LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { @@ -5741,22 +5935,42 @@ void LLPipeline::renderDeferredLighting() continue; } + if (volume->isAttachment()) + { + if (!sRenderAttachedLights) + { + continue; + } + } + + LLVector3 center = drawablep->getPositionAgent(); F32* c = center.mV; F32 s = volume->getLightRadius()*1.5f; - if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + if (col.magVecSquared() < 0.001f) + { + continue; + } + + if (s <= 0.001f) + { + continue; + } + + if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) { continue; } sVisibleLightCount++; + glh::vec3f tc(c); mat.mult_matrix_vec(tc); - - LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - + //vertex positions are encoded so the 3 bits of their vertex index //correspond to their axis facing, with bit position 3,2,1 matching //axis facing x,y,z, bit set meaning positive facing, bit clear @@ -5771,17 +5985,17 @@ void LLPipeline::renderDeferredLighting() v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 - if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) + if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || + camera->getOrigin().mV[0] < c[0] - s - 0.2f || + camera->getOrigin().mV[1] > c[1] + s + 0.2f || + camera->getOrigin().mV[1] < c[1] - s - 0.2f || + camera->getOrigin().mV[2] > c[2] + s + 0.2f || + camera->getOrigin().mV[2] < c[2] - s - 0.2f) { //draw box if camera is outside box 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(LLViewerCamera::getInstance(), center)); + GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); } else { @@ -5789,9 +6003,10 @@ void LLPipeline::renderDeferredLighting() light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); } } + unbindDeferredShader(gDeferredLightProgram); } - unbindDeferredShader(gDeferredLightProgram); + if (!fullscreen_lights.empty()) { @@ -5807,8 +6022,9 @@ void LLPipeline::renderDeferredLighting() U32 count = 0; - LLVector4 light[16]; - LLVector4 col[16]; + const U32 max_count = 16; + LLVector4 light[max_count]; + LLVector4 col[max_count]; glVertexPointer(2, GL_FLOAT, 0, vert); @@ -5818,9 +6034,9 @@ void LLPipeline::renderDeferredLighting() fullscreen_lights.pop_front(); col[count] = light_colors.front(); light_colors.pop_front(); - count++; - if (count == 16 || fullscreen_lights.empty()) + + if (count == max_count || fullscreen_lights.empty()) { gDeferredMultiLightProgram.uniform1i("light_count", count); gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); @@ -5828,40 +6044,45 @@ void LLPipeline::renderDeferredLighting() gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); count = 0; - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); } } - glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); unbindDeferredShader(gDeferredMultiLightProgram); } - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); { //render non-deferred geometry LLGLDisable blend(GL_BLEND); LLGLDisable stencil(GL_STENCIL_TEST); - U32 render_mask = mRenderTypeMask; - mRenderTypeMask = mRenderTypeMask & - ((1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_WL_CLOUDS) | - (1 << LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS) | - (1 << LLPipeline::RENDER_TYPE_WL_SKY) | - (1 << LLPipeline::RENDER_TYPE_ALPHA) | - (1 << LLPipeline::RENDER_TYPE_AVATAR) | - (1 << LLPipeline::RENDER_TYPE_VOIDWATER) | - (1 << LLPipeline::RENDER_TYPE_WATER) | - (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | - (1 << LLPipeline::RENDER_TYPE_VOLUME) | - (1 << LLPipeline::RENDER_TYPE_GLOW) | - (1 << LLPipeline::RENDER_TYPE_BUMP)); + pushRenderTypeMask(); + andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_GLOW, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + LLPipeline::RENDER_TYPE_PASS_GLOW, + LLPipeline::RENDER_TYPE_PASS_GRASS, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_INVISIBLE, + LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, + LLPipeline::RENDER_TYPE_AVATAR, + END_RENDER_TYPES); renderGeomPostDeferred(*LLViewerCamera::getInstance()); - mRenderTypeMask = render_mask; + popRenderTypeMask(); } mScreen.flush(); @@ -5931,9 +6152,12 @@ void LLPipeline::generateWaterReflection(LLCamera& 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); - U32 type_mask = gPipeline.mRenderTypeMask; + gPipeline.pushRenderTypeMask(); glh::matrix4f projection = glh_get_current_projection(); glh::matrix4f mat; @@ -5965,22 +6189,19 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) water_clip = 1; } - - if (!LLViewerCamera::getInstance()->cameraUnderWater()) { //generate planar reflection map gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glClearColor(0,0,0,0); - gGL.setColorMask(true, true); mWaterRef.bindTarget(); - mWaterRef.getViewport(gGLViewport); + gGL.setColorMask(true, true); mWaterRef.clear(); gGL.setColorMask(true, false); + mWaterRef.getViewport(gGLViewport); + stop_glerror(); - LLVector3 origin = camera.getOrigin(); - glPushMatrix(); mat.set_scale(glh::vec3f(1,1,-1)); @@ -5995,60 +6216,80 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); + glh::matrix4f inv_mat = mat.inverse(); + + glh::vec3f origin(0,0,0); + inv_mat.mult_matrix_vec(origin); + + camera.setOrigin(origin.v); + glCullFace(GL_FRONT); - //initial sky pass (no user clip plane) - { //mask out everything but the sky - U32 tmp = mRenderTypeMask; - mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_WL_SKY)); - static LLCullResult result; - updateCull(camera, result); - stateSort(camera, result); - mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) | - (1 << LLPipeline::RENDER_TYPE_WL_CLOUDS) | - (1 << LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS) | - (1 << LLPipeline::RENDER_TYPE_WL_SKY)); - renderGeom(camera, TRUE); - mRenderTypeMask = tmp; - } - + static LLCullResult ref_result; + if (LLDrawPoolWater::sNeedsDistortionUpdate) { - mRenderTypeMask &= ~((1< 0) + { //mask out selected geometry based on reflection detail { - mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR); - if (detail < 1) + if (detail < 4) { - mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME); + clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); + if (detail < 3) + { + clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + if (detail < 2) + { + clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); + } + } } + static LLCachedControl skip_distortion_updates("SkipReflectOcclusionUpdates",false); + LLPipeline::sSkipUpdate = skip_distortion_updates; + LLGLUserClipPlane clip_plane(plane, mat, projection); + LLGLDisable cull(GL_CULL_FACE); + updateCull(camera, ref_result, 1); + stateSort(camera, ref_result); } - } - - LLSpatialPartition::sFreezeState = TRUE; - LLPipeline::sSkipUpdate = TRUE; - LLGLUserClipPlane clip_plane(plane, mat, projection); - static LLCullResult result; - updateCull(camera, result, 1); - stateSort(camera, result); - renderGeom(camera); - LLSpatialPartition::sFreezeState = FALSE; - LLPipeline::sSkipUpdate = FALSE; + gPipeline.grabReferences(ref_result); + LLGLUserClipPlane clip_plane(plane, mat, projection); + renderGeom(camera); + LLPipeline::sSkipUpdate = FALSE; + } } + gPipeline.popRenderTypeMask(); } glCullFace(GL_BACK); glPopMatrix(); @@ -6057,37 +6298,37 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glh_set_current_modelview(current); } + camera.setOrigin(camera_in.getOrigin()); //render distortion map static BOOL last_update = TRUE; if (last_update) { camera.setFar(camera_in.getFar()); - mRenderTypeMask = type_mask & ~((1<cameraUnderWater() ? FALSE : TRUE; if (LLPipeline::sUnderWaterRender) { - mRenderTypeMask &= ~((1<unbind(LLTexUnit::TT_TEXTURE); LLColor4& col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); - gGL.setColorMask(true, true); mWaterDis.bindTarget(); mWaterDis.getViewport(gGLViewport); - mWaterDis.clear(); - gGL.setColorMask(true, false); - + if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) { //clip out geometry on the same side of water as the camera @@ -6096,6 +6337,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) static LLCullResult result; updateCull(camera, result, water_clip); stateSort(camera, result); + + gGL.setColorMask(true, true); + mWaterDis.clear(); + gGL.setColorMask(true, false); + renderGeom(camera); } @@ -6115,7 +6361,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glClearColor(0.f, 0.f, 0.f, 0.f); gViewerWindow->setupViewport(); - mRenderTypeMask = type_mask; + gPipeline.popRenderTypeMask(); LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd)); @@ -6201,7 +6447,6 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) void LLPipeline::generateSunShadow(LLCamera& camera) { - if (!sRenderDeferred) { return; @@ -6225,6 +6470,25 @@ void LLPipeline::generateSunShadow(LLCamera& camera) return; } clear = TRUE; + pushRenderTypeMask(); + andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, + LLPipeline::RENDER_TYPE_ALPHA, + LLPipeline::RENDER_TYPE_GRASS, + LLPipeline::RENDER_TYPE_FULLBRIGHT, + LLPipeline::RENDER_TYPE_BUMP, + LLPipeline::RENDER_TYPE_VOLUME, + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_TREE, + LLPipeline::RENDER_TYPE_TERRAIN, + LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, + LLPipeline::RENDER_TYPE_PASS_SIMPLE, + LLPipeline::RENDER_TYPE_PASS_BUMP, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, + LLPipeline::RENDER_TYPE_PASS_SHINY, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, + END_RENDER_TYPES); gGL.setColorMask(false, false); @@ -6303,6 +6567,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) at = -at; } + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j; LLVector3 left = lightDir%at; up = left%lightDir; up.normVec(); @@ -6419,17 +6685,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; - U32 type_mask = mRenderTypeMask; - mRenderTypeMask = type_mask & ((1<isDead() && - (!sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && + (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) && group->mDrawMap.find(type) != group->mDrawMap.end()) { @@ -6574,35 +6831,44 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - U32 mask; BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID()); + pushRenderTypeMask(); + if (muted) { - mask = 1 << LLPipeline::RENDER_TYPE_AVATAR; + andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); } else { - mask = (1<mDrawable, *LLViewerCamera::getInstance()); + LLViewerCamera* viewer_camera = LLViewerCamera::getInstance(); + markVisible(avatar->mDrawable, *viewer_camera); LLVOAvatar::sUseImpostors = FALSE; LLVOAvatar::attachment_map_t::iterator iter; @@ -6617,7 +6883,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) { if (LLViewerObject* attached_object = (*attachment_iter)) { - markVisible(attached_object->mDrawable->getSpatialBridge(), *LLViewerCamera::getInstance()); + markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); } } } @@ -6627,9 +6893,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); - LLCamera camera = *LLViewerCamera::getInstance(); + LLCamera camera = *viewer_camera; - camera.lookAt(LLViewerCamera::getInstance()->getOrigin(), pos, LLViewerCamera::getInstance()->getUpAxis()); + camera.lookAt(viewer_camera->getOrigin(), pos, viewer_camera->getUpAxis()); LLVector2 tdim; @@ -6695,6 +6961,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } + LLGLEnable stencil(GL_STENCIL_TEST); + glStencilMask(0xFFFFFFFF); + glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); { LLGLEnable scissor(GL_SCISSOR_TEST); glScissor(0, 0, resX, resY); @@ -6702,15 +6972,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) avatar->mImpostor.clear(); } - LLGLEnable stencil(GL_STENCIL_TEST); - - glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - if (LLPipeline::sRenderDeferred) { stop_glerror(); renderGeomDeferred(camera); + renderGeomPostDeferred(camera); } else { @@ -6720,11 +6986,18 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); - if (!sRenderDeferred || muted) + //if (!sRenderDeferred || muted) { LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; + //Safe?? + if (LLPipeline::sRenderDeferred) + { + GLuint buff = GL_COLOR_ATTACHMENT0_EXT; + glDrawBuffersARB(1, &buff); + } + LLGLEnable blend(muted ? 0 : GL_BLEND); if (muted) @@ -6763,7 +7036,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sUseOcclusion = occlusion; sReflectionRender = FALSE; sImpostorRender = FALSE; - gPipeline.mRenderTypeMask = saved_mask; + sShadowRender = FALSE; + popRenderTypeMask(); glMatrixMode(GL_PROJECTION); glPopMatrix(); @@ -6804,3 +7078,123 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() return sCull->endAlphaGroups(); } +BOOL LLPipeline::hasRenderType(const U32 type) const +{ + // STORM-365 : LLViewerJointAttachment::setAttachmentVisibility() is setting type to 0 to actually mean "do not render" + // We then need to test that value here and return FALSE to prevent attachment to render (in mouselook for instance) + // TODO: reintroduce RENDER_TYPE_NONE in LLRenderTypeMask and initialize its mRenderTypeEnabled[RENDER_TYPE_NONE] to FALSE explicitely + return (type == 0 ? FALSE : mRenderTypeEnabled[type]); +} + +void LLPipeline::setRenderTypeMask(U32 type, ...) +{ + va_list args; + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + mRenderTypeEnabled[type] = TRUE; + type = va_arg(args, U32); + } + va_end(args); + + if (type > END_RENDER_TYPES) + { + llerrs << "Invalid render type." << llendl; + } +} + +BOOL LLPipeline::hasAnyRenderType(U32 type, ...) const +{ + va_list args; + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + if (mRenderTypeEnabled[type]) + { + return TRUE; + } + type = va_arg(args, U32); + } + va_end(args); + + if (type > END_RENDER_TYPES) + { + llerrs << "Invalid render type." << llendl; + } + + return FALSE; +} + +void LLPipeline::pushRenderTypeMask() +{ + std::string cur_mask; + cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled)); + mRenderTypeEnableStack.push(cur_mask); +} + +void LLPipeline::popRenderTypeMask() +{ + if (mRenderTypeEnableStack.empty()) + { + llerrs << "Depleted render type stack." << llendl; + } + + memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled)); + mRenderTypeEnableStack.pop(); +} + +void LLPipeline::andRenderTypeMask(U32 type, ...) +{ + va_list args; + + BOOL tmp[NUM_RENDER_TYPES]; + for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) + { + tmp[i] = FALSE; + } + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + if (mRenderTypeEnabled[type]) + { + tmp[type] = TRUE; + } + + type = va_arg(args, U32); + } + va_end(args); + + if (type > END_RENDER_TYPES) + { + llerrs << "Invalid render type." << llendl; + } + + for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i) + { + mRenderTypeEnabled[i] = tmp[i]; + } + +} + +void LLPipeline::clearRenderTypeMask(U32 type, ...) +{ + va_list args; + + va_start(args, type); + while (type < END_RENDER_TYPES) + { + mRenderTypeEnabled[type] = FALSE; + + type = va_arg(args, U32); + } + va_end(args); + + if (type > END_RENDER_TYPES) + { + llerrs << "Invalid render type." << llendl; + } +} + diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index e60c6f861..36f4c33ec 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -46,6 +46,8 @@ #include "lldrawable.h" #include "llrendertarget.h" +#include + class LLViewerImage; class LLEdge; class LLFace; @@ -94,6 +96,7 @@ public: void resetVertexBuffers(LLDrawable* drawable); void setUseVBO(BOOL use_vbo); + void setDisableVBOMapping(BOOL no_vbo_mapping); void generateImpostor(LLVOAvatar* avatar); void bindScreenToTexture(); void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); @@ -129,6 +132,8 @@ public: void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE); void markShift(LLDrawable *drawablep); void markTextured(LLDrawable *drawablep); + void markGLRebuild(LLGLUpdate* glu); + void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); //get the object between start and end that's closest to start. @@ -179,10 +184,14 @@ public: void updateMove(); BOOL visibleObjectsInFrustum(LLCamera& camera); BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); + BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector& fp, LLVector3 light_dir = LLVector3(0,0,0)); void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void updateGeom(F32 max_dtime); + void updateGL(); + void rebuildPriorityGroups(); + void rebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); @@ -234,8 +243,7 @@ public: void shiftObjects(const LLVector3 &offset); void setLight(LLDrawable *drawablep, BOOL is_light); - void setActive(LLDrawable *drawablep, BOOL active); - + BOOL hasRenderBatches(const U32 type) const; LLCullResult::drawinfo_list_t::iterator beginRenderMap(U32 type); LLCullResult::drawinfo_list_t::iterator endRenderMap(U32 type); @@ -243,11 +251,20 @@ public: LLCullResult::sg_list_t::iterator endAlphaGroups(); void addTrianglesDrawn(S32 count); - BOOL hasRenderType(const U32 type) const { return (type && (mRenderTypeMask & (1< mRenderTypeEnableStack; + U32 mRenderDebugFeatureMask; U32 mRenderDebugMask; @@ -508,10 +543,10 @@ protected: // LLDrawable::drawable_list_t mBuildQ1; // priority LLDrawable::drawable_list_t mBuildQ2; // non-priority + LLSpatialGroup::sg_vector_t mGroupQ1; //priority + LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority LLViewerObject::vobj_list_t mCreateQ; - LLDrawable::drawable_set_t mActiveQ; - LLDrawable::drawable_set_t mRetexturedList; ////////////////////////////////////////////////// diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 78a5f0ebe..9a7ecf5c2 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -271,6 +271,14 @@ class WindowsManifest(ViewerManifest): # For google-perftools tcmalloc allocator. self.path("../../libraries/i686-win32/lib/release/libtcmalloc_minimal.dll", dst="libtcmalloc_minimal.dll") + try: + if self.prefix("../../libraries/i686-win32/lib/release/msvcrt", dst=""): + self.path("*.dll") + self.end_prefix() + except: + pass + + # These need to be installed as a SxS assembly, currently a 'private' assembly. # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx #~ if self.prefix(src=self.args['configuration'], dst=""): diff --git a/install.xml b/install.xml index da13771ca..ae6a04657 100644 --- a/install.xml +++ b/install.xml @@ -221,9 +221,9 @@ windows md5sum - d631c18f447ff4d413525f3c7d52db42 + 17f89b854959b4d728be832d9c8184e4 url - http://cloud.github.com/downloads/HazimGazov/Inertia/boost-1.39-windows.tar.bz2 + https://github.com/downloads/NickyPerian/imprudence/boost_1_45_VC100_libs_inc_patch4073.tar.bz2 @@ -588,14 +588,14 @@ md5sum 1d7acbc5b578b3b5cfc739d2f454b18c url - https://github.com/downloads/siana/SingularityViewer/google-linux-110103.tar.bz2 + https://github.com/downloads/siana/SingularityViewer/google-linux-110103.tar.bz2 windows md5sum - b46525d8eae16865c27905a844c86ac0 + 38a70e2d892520ed3281b0f459e4f15f url - http://github.com/downloads/siana/SingularityViewer/tcmalloc_win_101223.tar.bz2 + https://github.com/downloads/siana/SingularityViewer/tcmalloc-1.6-min-20110317.tar.bz2 @@ -785,9 +785,9 @@ windows md5sum - 6912b5137a8533096a731f77fb1363b4 + 91e081c4b7b4949c4e53849182a42370 url - http://imprudenceviewer.org/download/libs/json-windows.tar.bz2 + https://github.com/downloads/siana/SingularityViewer/jsoncpp-0.5.0-windows-20110320.tar.bz2 @@ -922,23 +922,23 @@ anguage Infrstructure (CLI) international standard darwin md5sum - 34d9e4c93678a422cf80521bf0cd7628 + c983326e0fbe1b77ffc9e006a4c9bee2 url - http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100914.tar.bz2 + https://github.com/downloads/siana/SingularityViewer/llqtwebkit-4.7.1-darwin-20110317.tar.bz2 linux md5sum - 5d743c93b970abe685b185de83001a6e + b3acc92ca0a7b671bd5e5185fb10fc66 url - http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-linux-qt4.6-20100923.tar.bz2 + https://github.com/downloads/siana/SingularityViewer/llqtwebkit-4.7.1-linux-20110317.tar.bz2 windows md5sum - 2a89c84f778ba932f63a884421e05be1 + 999b265a3af47eb13e9a380d042a1763 url - https://github.com/downloads/siana/SingularityViewer/llqtwebkit-windows-qt4.6-2010a.tar.bz2 + https://github.com/downloads/siana/SingularityViewer/llqtwebkit-4.7.1-windows-20110320.tar.bz2