diff options
265 files changed, 4859 insertions, 6823 deletions
diff --git a/autobuild.xml b/autobuild.xml index e984551455..b240b13a94 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -482,9 +482,9 @@ <key>archive</key> <map> <key>hash</key> - <string>2653c3627fd8687ff9e003425fd14834</string> + <string>439d92ec73f0500ba1671faad2bd8090</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90199/821852/dullahan-1.12.3.202111032211_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-565428.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104637/916643/dullahan-1.12.4.202209142017_91.1.21_g9dd45fe_chromium-91.0.4472.114-darwin64-575005.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -494,9 +494,9 @@ <key>archive</key> <map> <key>hash</key> - <string>b4003772562a5dd40bc112eec7cba5f5</string> + <string>2a7c01da15de77bc1fd1863327174d5e</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90201/821871/dullahan-1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-565428.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104638/916654/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows-575005.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -506,16 +506,16 @@ <key>archive</key> <map> <key>hash</key> - <string>d9030d7a7390b3bda7de2adcc27e535a</string> + <string>d06bee9b2517fbb09ba1a65e6d675361</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/90200/821876/dullahan-1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-565428.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104639/916659/dullahan-1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114-windows64-575005.tar.bz2</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>1.12.3.202111032221_91.1.21_g9dd45fe_chromium-91.0.4472.114</string> + <string>1.12.4.202209142021_91.1.21_g9dd45fe_chromium-91.0.4472.114</string> </map> <key>expat</key> <map> @@ -2401,9 +2401,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>6ce3cbaed968a69fb7a2cca80220874d</string> + <string>b583668b28fde0490e6953f10e93e4ab</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80380/758537/slvoice-4.10.0000.32327.5fc3fe7c.558436-darwin64-558436.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98681/871545/slvoice-4.10.0000.32327.5fc3fe7c.571099-darwin64-571099.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -2425,9 +2425,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>2eb38c5eff4d0f18fbb89d0c30c4f0a4</string> + <string>6e0ed41653955afe8eeb8945776cf07b</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80382/758550/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows-558436.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98683/871560/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows-571099.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -2437,16 +2437,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>9ee8f3cbc5369c598a998c61961ed16d</string> + <string>c39735851fd05c194d0be09b8f9e8cb7</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80381/758551/slvoice-4.10.0000.32327.5fc3fe7c.558436-windows64-558436.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/98682/871552/slvoice-4.10.0000.32327.5fc3fe7c.571099-windows64-571099.tar.bz2</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>4.10.0000.32327.5fc3fe7c.558436</string> + <string>4.10.0000.32327.5fc3fe7c.571099</string> </map> <key>threejs</key> <map> diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake index 3cbb7ad561..513ff9f81d 100644 --- a/indra/cmake/LLMath.cmake +++ b/indra/cmake/LLMath.cmake @@ -2,6 +2,7 @@ include(Variables) include(Mikktspace) +include(MESHOPTIMIZER) set(LLMATH_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llmath diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 3430a25536..e1a3a83841 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1509,7 +1509,14 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } else { // platforms with working drivers... - glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + // We just want GL_ALPHA, but that isn't supported in OGL core profile 4. + static const size_t TEMP_BYTES_PER_PIXEL = 4; + U8* temp_data = (U8*)ll_aligned_malloc_32(mem_size * TEMP_BYTES_PER_PIXEL); + glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_data); + for (size_t pixel = 0; pixel < pixels; pixel++) { + alpha_data[pixel] = temp_data[(pixel * TEMP_BYTES_PER_PIXEL) + 3]; + } + ll_aligned_free_32(temp_data); } } else diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index e0ebbb76bd..9e897a7ce8 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -276,7 +276,7 @@ void LLAudioEngine::idle(F32 max_decode_time) { // The source is done playing, clean it up. delete sourcep; - mAllSources.erase(iter++); + iter = mAllSources.erase(iter); continue; } @@ -827,7 +827,8 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i addAudioSource(asp); if (pos_global.isExactlyZero()) { - asp->setAmbient(true); + // For sound preview and UI + asp->setForcedPriority(true); } else { @@ -1273,7 +1274,7 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 mPriority(0.f), mGain(gain), mSourceMuted(false), - mAmbient(false), + mForcedPriority(false), mLoop(false), mSyncMaster(false), mSyncSlave(false), @@ -1339,7 +1340,7 @@ void LLAudioSource::update() void LLAudioSource::updatePriority() { - if (isAmbient()) + if (isForcedPriority()) { mPriority = 1.f; } diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index b5fd4c27a1..e12fb970ca 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -266,8 +266,8 @@ public: void addAudioData(LLAudioData *adp, bool set_current = TRUE); - void setAmbient(const bool ambient) { mAmbient = ambient; } - bool isAmbient() const { return mAmbient; } + void setForcedPriority(const bool ambient) { mForcedPriority = ambient; } + bool isForcedPriority() const { return mForcedPriority; } void setLoop(const bool loop) { mLoop = loop; } bool isLoop() const { return mLoop; } @@ -326,7 +326,7 @@ protected: F32 mPriority; F32 mGain; bool mSourceMuted; - bool mAmbient; + bool mForcedPriority; // ignore mute, set high priority, researved for sound preview and UI bool mLoop; bool mSyncMaster; bool mSyncSlave; diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index b0c87b0208..e5752d3dad 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -519,9 +519,9 @@ void LLAudioChannelFMODSTUDIO::update3DPosition() return; } - if (mCurrentSourcep->isAmbient()) + if (mCurrentSourcep->isForcedPriority()) { - // Ambient sound, don't need to do any positional updates. + // Prioritized UI and preview sounds don't need to do any positional updates. set3DMode(false); } else diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index 3bdd0302ee..305aa1ecb5 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -297,7 +297,7 @@ void LLAudioChannelOpenAL::update3DPosition() { return; } - if (mCurrentSourcep->isAmbient()) + if (mCurrentSourcep->isForcedPriority()) { alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0); alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0); diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp index 1ad29a3f59..85577992a6 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp +++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp @@ -70,7 +70,11 @@ mRetryCount(0) // Must be larger than the usual Second Life frame stutter time. const U32 buffer_seconds = 10; //sec const U32 estimated_bitrate = 128; //kbit/sec - mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES); + FMOD_RESULT result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL; + } // Here's where we set the size of the network buffer and some buffering // parameters. In this case we want a network buffer of 16k, we want it @@ -134,7 +138,7 @@ void LLStreamingAudio_FMODSTUDIO::killDeadStreams() { LL_INFOS("FMOD") << "Closed dead stream" << LL_ENDL; delete streamp; - mDeadStreams.erase(iter++); + iter = mDeadStreams.erase(iter); } else { @@ -404,7 +408,11 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream() if (mStreamChannel) return mStreamChannel; //Already have a channel for this stream. - mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel); + FMOD_RESULT result = mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL; + } return mStreamChannel; } @@ -445,16 +453,29 @@ bool LLAudioStreamManagerFMODSTUDIO::stopStream() FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy) { FMOD_OPENSTATE state; - mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy); + FMOD_RESULT result = mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << FMOD_ErrorString(result) << LL_ENDL; + } return state; } void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime) { - mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES); + FMOD_RESULT result = mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL; + return; + } FMOD_ADVANCEDSETTINGS settings; memset(&settings, 0, sizeof(settings)); settings.cbSize = sizeof(settings); settings.defaultDecodeBufferSize = decodebuffertime;//ms - mSystem->setAdvancedSettings(&settings); + result = mSystem->setAdvancedSettings(&settings); + if (result != FMOD_OK) + { + LL_WARNS("FMOD") << "setAdvancedSettings error: " << FMOD_ErrorString(result) << LL_ENDL; + } } diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index e906d81ce1..c38614b0b4 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -44,6 +44,14 @@ using namespace std; #define INCHES_TO_METERS 0.02540005f +/// The .bvh does not have a formal spec, and different readers interpret things in their own way. +/// In OUR usage, frame 0 is used in optimization and is not considered to be part of the animation. +const S32 NUMBER_OF_IGNORED_FRAMES_AT_START = 1; +/// In our usage, the last frame is used only to indicate what the penultimate frame should be interpolated towards. +/// I.e., the animation only plays up to the start of the last frame. There is no hold or exptrapolation past that point.. +/// Thus there are two frame of the total that do not contribute to the total running time of the animation. +const S32 NUMBER_OF_UNPLAYED_FRAMES = NUMBER_OF_IGNORED_FRAMES_AT_START + 1; + const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f; const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f; @@ -865,7 +873,10 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & return E_ST_NO_FRAME_TIME; } - mDuration = (F32)mNumFrames * mFrameTime; + // If the user only supplies one animation frame (after the ignored reference frame 0), hold for mFrameTime. + // If the user supples exactly one total frame, it isn't clear if that is a pose or reference frame, and the + // behavior is not defined. In this case, retain historical undefined behavior. + mDuration = llmax((F32)(mNumFrames - NUMBER_OF_UNPLAYED_FRAMES), 1.0f) * mFrameTime; if (!mLoop) { mLoopOutPoint = mDuration; @@ -1355,12 +1366,13 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) LLQuaternion::Order order = bvhStringToOrder( joint->mOrder ); S32 outcount = 0; - S32 frame = 1; + S32 frame = 0; for ( ki = joint->mKeys.begin(); ki != joint->mKeys.end(); ++ki ) { - if ((frame == 1) && joint->mRelativeRotationKey) + + if ((frame == 0) && joint->mRelativeRotationKey) { first_frame_rot = mayaQ( ki->mRot[0], ki->mRot[1], ki->mRot[2], order); @@ -1373,7 +1385,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) continue; } - time = (F32)frame * mFrameTime; + time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts. if (mergeParent) { @@ -1433,12 +1445,12 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) LLVector3 relPos = joint->mRelativePosition; LLVector3 relKey; - frame = 1; + frame = 0; for ( ki = joint->mKeys.begin(); ki != joint->mKeys.end(); ++ki ) { - if ((frame == 1) && joint->mRelativePositionKey) + if ((frame == 0) && joint->mRelativePositionKey) { relKey.setVec(ki->mPos); } @@ -1449,7 +1461,7 @@ BOOL LLBVHLoader::serialize(LLDataPacker& dp) continue; } - time = (F32)frame * mFrameTime; + time = llmax((F32)(frame - NUMBER_OF_IGNORED_FRAMES_AT_START), 0.0f) * mFrameTime; // Time elapsed before this frame starts. LLVector3 inPos = (LLVector3(ki->mPos) - relKey) * ~first_frame_rot;// * fixup_rot; LLVector3 outPos = inPos * frameRot * offsetRot; diff --git a/indra/llcommon/llalignedarray.h b/indra/llcommon/llalignedarray.h index b68e9e0f82..da9d98c16c 100644 --- a/indra/llcommon/llalignedarray.h +++ b/indra/llcommon/llalignedarray.h @@ -116,14 +116,20 @@ void LLAlignedArray<T, alignment>::resize(U32 size) template <class T, U32 alignment> T& LLAlignedArray<T, alignment>::operator[](int idx) { - llassert(idx < mElementCount); + if(idx >= mElementCount || idx < 0) + { + LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL; + } return mArray[idx]; } template <class T, U32 alignment> const T& LLAlignedArray<T, alignment>::operator[](int idx) const { - llassert(idx < mElementCount); + if (idx >= mElementCount || idx < 0) + { + LL_ERRS() << "Out of bounds LLAlignedArray, requested: " << (S32)idx << " size: " << mElementCount << LL_ENDL; + } return mArray[idx]; } diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index c2d353b0fc..14bfb98629 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -35,6 +35,7 @@ // STL headers // std headers #include <atomic> +#include <stdexcept> // external library headers #include <boost/bind.hpp> #include <boost/fiber/fiber.hpp> @@ -214,6 +215,22 @@ std::string LLCoros::logname() return data.mName.empty()? data.getKey() : data.mName; } +void LLCoros::saveException(const std::string& name, std::exception_ptr exc) +{ + mExceptionQueue.emplace(name, exc); +} + +void LLCoros::rethrow() +{ + if (! mExceptionQueue.empty()) + { + ExceptionData front = mExceptionQueue.front(); + mExceptionQueue.pop(); + LL_WARNS("LLCoros") << "Rethrowing exception from coroutine " << front.name << LL_ENDL; + std::rethrow_exception(front.exception); + } +} + void LLCoros::setStackSize(S32 stacksize) { LL_DEBUGS("LLCoros") << "Setting coroutine stack size to " << stacksize << LL_ENDL; @@ -302,11 +319,11 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, } } -void LLCoros::winlevel(const std::string& name, const callable_t& callable) +void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable) { __try { - toplevelTryWrapper(name, callable); + LLCoros::toplevelTryWrapper(name, callable); } __except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name)) { @@ -321,7 +338,6 @@ void LLCoros::winlevel(const std::string& name, const callable_t& callable) throw std::exception(integer_string); } } - #endif void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable) @@ -350,11 +366,19 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call } catch (...) { +#if LL_WINDOWS // Any OTHER kind of uncaught exception will cause the viewer to - // crash, hopefully informatively. + // crash, SEH handling should catch it and report to bugsplat. LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name)); // to not modify callstack throw; +#else + // Stash any OTHER kind of uncaught exception in the rethrow() queue + // to be rethrown by the main fiber. + LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine " + << name << LL_ENDL; + LLCoros::instance().saveException(name, std::current_exception()); +#endif } } @@ -364,8 +388,9 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call void LLCoros::toplevel(std::string name, callable_t callable) { #if LL_WINDOWS - // Can not use __try in functions that require unwinding, so use one more wrapper - winlevel(name, callable); + // Because SEH can's have unwinding, need to call a wrapper + // 'try' is inside SEH handling to not catch LLContinue + sehHandle(name, callable); #else toplevelTryWrapper(name, callable); #endif diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index a94cfca19f..dbff921f16 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -38,6 +38,8 @@ #include "llinstancetracker.h" #include <boost/function.hpp> #include <string> +#include <exception> +#include <queue> // e.g. #include LLCOROS_MUTEX_HEADER #define LLCOROS_MUTEX_HEADER <boost/fiber/mutex.hpp> @@ -156,6 +158,19 @@ public: * LLCoros::launch()). */ static std::string getName(); + + /** + * rethrow() is called by the thread's main fiber to propagate an + * exception from any coroutine into the main fiber, where it can engage + * the normal unhandled-exception machinery, up to and including crash + * reporting. + * + * LLCoros maintains a queue of otherwise-uncaught exceptions from + * terminated coroutines. Each call to rethrow() pops the first of those + * and rethrows it. When the queue is empty (normal case), rethrow() is a + * no-op. + */ + void rethrow(); /** * This variation returns a name suitable for log messages: the explicit @@ -292,13 +307,27 @@ public: private: std::string generateDistinctName(const std::string& prefix) const; + void toplevelTryWrapper(const std::string& name, const callable_t& callable); #if LL_WINDOWS - void winlevel(const std::string& name, const callable_t& callable); + void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper #endif - void toplevelTryWrapper(const std::string& name, const callable_t& callable); - void toplevel(std::string name, callable_t callable); + void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper struct CoroData; static CoroData& get_CoroData(const std::string& caller); + void saveException(const std::string& name, std::exception_ptr exc); + + struct ExceptionData + { + ExceptionData(const std::string& nm, std::exception_ptr exc): + name(nm), + exception(exc) + {} + // name of coroutine that originally threw this exception + std::string name; + // the thrown exception + std::exception_ptr exception; + }; + std::queue<ExceptionData> mExceptionQueue; S32 mStackSize; diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 818df07bb2..4a1a81f083 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -118,7 +118,11 @@ namespace eMONTIOR_MWAIT=33, eCPLDebugStore=34, eThermalMonitor2=35, - eAltivec=36 + eAltivec=36, + eSSE3S_Features = 37, + eSSE4_1_Features = 38, + eSSE4_2_Features = 39, + eSSE4a_Features = 40, }; const char* cpu_feature_names[] = @@ -161,7 +165,11 @@ namespace "CPL Qualified Debug Store", "Thermal Monitor 2", - "Altivec" + "Altivec", + "SSE3S Instructions", + "SSE4.1 Instructions", + "SSE4.2 Instructions", + "SSE4a Instructions", }; std::string intel_CPUFamilyName(int composed_family) @@ -250,6 +258,31 @@ public: return hasExtension(cpu_feature_names[eSSE2_Ext]); } + bool hasSSE3() const + { + return hasExtension(cpu_feature_names[eSSE3_Features]); + } + + bool hasSSE3S() const + { + return hasExtension(cpu_feature_names[eSSE3S_Features]); + } + + bool hasSSE41() const + { + return hasExtension(cpu_feature_names[eSSE4_1_Features]); + } + + bool hasSSE42() const + { + return hasExtension(cpu_feature_names[eSSE4_2_Features]); + } + + bool hasSSE4a() const + { + return hasExtension(cpu_feature_names[eSSE4a_Features]); + } + bool hasAltivec() const { return hasExtension("Altivec"); @@ -473,6 +506,12 @@ private: *((int*)(cpu_vendor+4)) = cpu_info[3]; *((int*)(cpu_vendor+8)) = cpu_info[2]; setInfo(eVendor, cpu_vendor); + std::string cmp_vendor(cpu_vendor); + bool is_amd = false; + if (cmp_vendor == "AuthenticAMD") + { + is_amd = true; + } // Get the information associated with each valid Id for(unsigned int i=0; i<=ids; ++i) @@ -504,6 +543,7 @@ private: if(cpu_info[2] & 0x8) { + // intel specific SSE3 suplements setExtension(cpu_feature_names[eMONTIOR_MWAIT]); } @@ -516,7 +556,22 @@ private: { setExtension(cpu_feature_names[eThermalMonitor2]); } - + + if (cpu_info[2] & 0x200) + { + setExtension(cpu_feature_names[eSSE3S_Features]); + } + + if (cpu_info[2] & 0x80000) + { + setExtension(cpu_feature_names[eSSE4_1_Features]); + } + + if (cpu_info[2] & 0x100000) + { + setExtension(cpu_feature_names[eSSE4_2_Features]); + } + unsigned int feature_info = (unsigned int) cpu_info[3]; for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1) { @@ -543,8 +598,17 @@ private: __cpuid(cpu_info, i); // Interpret CPU brand string and cache information. - if (i == 0x80000002) - memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info)); + if (i == 0x80000001) + { + if (is_amd) + { + setExtension(cpu_feature_names[eSSE4a_Features]); + } + } + else if (i == 0x80000002) + { + memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info)); + } else if (i == 0x80000003) memcpy(cpu_brand_string + 16, cpu_info, sizeof(cpu_info)); else if (i == 0x80000004) @@ -690,6 +754,41 @@ private: uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits"); S32 *ext_feature_infos = (S32*)(&ext_feature_info); setConfig(eExtFeatureBits, ext_feature_infos[0]); + + + char cpu_features[1024]; + len = sizeof(cpu_features); + memset(cpu_features, 0, len); + sysctlbyname("machdep.cpu.features", (void*)cpu_features, &len, NULL, 0); + + std::string cpu_features_str(cpu_features); + cpu_features_str = " " + cpu_features_str + " "; + + if (cpu_features_str.find(" SSE3 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE3_Features]); + } + + if (cpu_features_str.find(" SSSE3 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE3S_Features]); + } + + if (cpu_features_str.find(" SSE4.1 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4_1_Features]); + } + + if (cpu_features_str.find(" SSE4.2 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4_2_Features]); + } + + if (cpu_features_str.find(" SSE4A ") != std::string::npos) + { + // Not supposed to happen? + setExtension(cpu_feature_names[eSSE4a_Features]); + } } }; @@ -800,6 +899,31 @@ private: { setExtension(cpu_feature_names[eSSE2_Ext]); } + + if (flags.find(" pni ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE3_Features]); + } + + if (flags.find(" ssse3 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE3S_Features]); + } + + if (flags.find(" sse4_1 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4_1_Features]); + } + + if (flags.find(" sse4_2 ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4_2_Features]); + } + + if (flags.find(" sse4a ") != std::string::npos) + { + setExtension(cpu_feature_names[eSSE4a_Features]); + } # endif // LL_X86 } @@ -860,6 +984,11 @@ LLProcessorInfo::~LLProcessorInfo() {} F64MegahertzImplicit LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); } bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); } +bool LLProcessorInfo::hasSSE3() const { return mImpl->hasSSE3(); } +bool LLProcessorInfo::hasSSE3S() const { return mImpl->hasSSE3S(); } +bool LLProcessorInfo::hasSSE41() const { return mImpl->hasSSE41(); } +bool LLProcessorInfo::hasSSE42() const { return mImpl->hasSSE42(); } +bool LLProcessorInfo::hasSSE4a() const { return mImpl->hasSSE4a(); } bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); } std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); } diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index b77eb22c3a..1a473ddc97 100644 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -54,6 +54,11 @@ public: F64MegahertzImplicit getCPUFrequency() const; bool hasSSE() const; bool hasSSE2() const; + bool hasSSE3() const; + bool hasSSE3S() const; + bool hasSSE41() const; + bool hasSSE42() const; + bool hasSSE4a() const; bool hasAltivec() const; std::string getCPUFamilyName() const; std::string getCPUBrandName() const; diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 45417bfa37..9346f391e6 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -597,6 +597,11 @@ LLCPUInfo::LLCPUInfo() // proc.WriteInfoTextFile("procInfo.txt"); mHasSSE = proc.hasSSE(); mHasSSE2 = proc.hasSSE2(); + mHasSSE3 = proc.hasSSE3(); + mHasSSE3S = proc.hasSSE3S(); + mHasSSE41 = proc.hasSSE41(); + mHasSSE42 = proc.hasSSE42(); + mHasSSE4a = proc.hasSSE4a(); mHasAltivec = proc.hasAltivec(); mCPUMHz = (F64)proc.getCPUFrequency(); mFamily = proc.getCPUFamilyName(); @@ -609,6 +614,35 @@ LLCPUInfo::LLCPUInfo() } mCPUString = out.str(); LLStringUtil::trim(mCPUString); + + if (mHasSSE) + { + mSSEVersions.append("1"); + } + if (mHasSSE2) + { + mSSEVersions.append("2"); + } + if (mHasSSE3) + { + mSSEVersions.append("3"); + } + if (mHasSSE3S) + { + mSSEVersions.append("3S"); + } + if (mHasSSE41) + { + mSSEVersions.append("4.1"); + } + if (mHasSSE42) + { + mSSEVersions.append("4.2"); + } + if (mHasSSE4a) + { + mSSEVersions.append("4a"); + } } bool LLCPUInfo::hasAltivec() const @@ -626,6 +660,31 @@ bool LLCPUInfo::hasSSE2() const return mHasSSE2; } +bool LLCPUInfo::hasSSE3() const +{ + return mHasSSE3; +} + +bool LLCPUInfo::hasSSE3S() const +{ + return mHasSSE3S; +} + +bool LLCPUInfo::hasSSE41() const +{ + return mHasSSE41; +} + +bool LLCPUInfo::hasSSE42() const +{ + return mHasSSE42; +} + +bool LLCPUInfo::hasSSE4a() const +{ + return mHasSSE4a; +} + F64 LLCPUInfo::getMHz() const { return mCPUMHz; @@ -636,6 +695,11 @@ std::string LLCPUInfo::getCPUString() const return mCPUString; } +const LLSD& LLCPUInfo::getSSEVersions() const +{ + return mSSEVersions; +} + void LLCPUInfo::stream(std::ostream& s) const { // gather machine information. @@ -645,6 +709,11 @@ void LLCPUInfo::stream(std::ostream& s) const // CPU's attributes regardless of platform s << "->mHasSSE: " << (U32)mHasSSE << std::endl; s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl; + s << "->mHasSSE3: " << (U32)mHasSSE3 << std::endl; + s << "->mHasSSE3S: " << (U32)mHasSSE3S << std::endl; + s << "->mHasSSE41: " << (U32)mHasSSE41 << std::endl; + s << "->mHasSSE42: " << (U32)mHasSSE42 << std::endl; + s << "->mHasSSE4a: " << (U32)mHasSSE4a << std::endl; s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl; s << "->mCPUMHz: " << mCPUMHz << std::endl; s << "->mCPUString: " << mCPUString << std::endl; diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 538e61c521..0f768938cb 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -80,10 +80,16 @@ public: void stream(std::ostream& s) const; std::string getCPUString() const; + const LLSD& getSSEVersions() const; bool hasAltivec() const; bool hasSSE() const; bool hasSSE2() const; + bool hasSSE3() const; + bool hasSSE3S() const; + bool hasSSE41() const; + bool hasSSE42() const; + bool hasSSE4a() const; F64 getMHz() const; // Family is "AMD Duron" or "Intel Pentium Pro" @@ -92,10 +98,16 @@ public: private: bool mHasSSE; bool mHasSSE2; + bool mHasSSE3; + bool mHasSSE3S; + bool mHasSSE41; + bool mHasSSE42; + bool mHasSSE4a; bool mHasAltivec; F64 mCPUMHz; std::string mFamily; std::string mCPUString; + LLSD mSSEVersions; }; //============================================================================= diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index 538446d732..022d206821 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -355,6 +355,38 @@ void LLDiskCache::clearCache() } } +void LLDiskCache::removeOldVFSFiles() +{ + //VFS files won't be created, so consider removing this code later + static const char CACHE_FORMAT[] = "inv.llsd"; + static const char DB_FORMAT[] = "db2.x"; + + boost::system::error_code ec; +#if LL_WINDOWS + std::wstring cache_path(utf8str_to_utf16str(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ""))); +#else + std::string cache_path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "")); +#endif + if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed()) + { + for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {})) + { + if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed()) + { + if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) || + (entry.path().string().find(DB_FORMAT) != std::string::npos)) + { + boost::filesystem::remove(entry, ec); + if (ec.failed()) + { + LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL; + } + } + } + } + } +} + uintmax_t LLDiskCache::dirFileSize(const std::string dir) { uintmax_t total_file_size = 0; diff --git a/indra/llfilesystem/lldiskcache.h b/indra/llfilesystem/lldiskcache.h index 1cbd2c58aa..b60e74f8c9 100644 --- a/indra/llfilesystem/lldiskcache.h +++ b/indra/llfilesystem/lldiskcache.h @@ -140,6 +140,8 @@ class LLDiskCache : */ const std::string getCacheInfo(); + void removeOldVFSFiles(); + private: /** * Utility function to gather the total size the files in a given diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index 675da65af2..d2c3b419ab 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -122,6 +122,7 @@ LLFolderDictionary::LLFolderDictionary() addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE, FALSE, FALSE)); addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", TRUE, FALSE, TRUE)); + addEntry(LLFolderType::FT_MATERIAL, new FolderEntry("material", TRUE, FALSE, TRUE)); addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE, FALSE, FALSE)); }; diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index e25dae8a90..134e783053 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -234,6 +234,8 @@ void LLParcel::init(const LLUUID &owner_id, setRegionAllowEnvironmentOverride(FALSE); setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION); + + setObscureMOAP(false); } void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned) @@ -540,6 +542,7 @@ void LLParcel::packMessage(LLSD& msg) msg["see_avs"] = (LLSD::Boolean) getSeeAVs(); msg["group_av_sounds"] = (LLSD::Boolean) getAllowGroupAVSounds(); msg["any_av_sounds"] = (LLSD::Boolean) getAllowAnyAVSounds(); + msg["obscure_moap"] = (LLSD::Boolean) getObscureMOAP(); } diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 5d08c1f4c6..f5ee1241ab 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -306,6 +306,7 @@ public: void setRestrictPushObject(BOOL b) { setParcelFlag(PF_RESTRICT_PUSHOBJECT, b); } void setAllowGroupAVSounds(BOOL b) { mAllowGroupAVSounds = b; } void setAllowAnyAVSounds(BOOL b) { mAllowAnyAVSounds = b; } + void setObscureMOAP(bool b) { mObscureMOAP = b; } void setDrawDistance(F32 dist) { mDrawDistance = dist; } void setSalePrice(S32 price) { mSalePrice = price; } @@ -517,6 +518,8 @@ public: BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; } BOOL getAllowAnyAVSounds() const { return mAllowAnyAVSounds; } + + bool getObscureMOAP() const { return mObscureMOAP; } F32 getDrawDistance() const { return mDrawDistance; } S32 getSalePrice() const { return mSalePrice; } @@ -670,6 +673,7 @@ protected: BOOL mRegionAllowEnvironmentOverride; BOOL mAllowGroupAVSounds; BOOL mAllowAnyAVSounds; + bool mObscureMOAP; S32 mCurrentEnvironmentVersion; bool mIsDefaultDayCycle; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 539db9d0e1..454969b912 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -56,6 +56,8 @@ #include "mikktspace/mikktspace.h" #include "mikktspace/mikktspace.c" // insert mikktspace implementation into llvolume object file +#include "meshoptimizer/meshoptimizer.h" + #define DEBUG_SILHOUETTE_BINORMALS 0 #define DEBUG_SILHOUETTE_NORMALS 0 // TomY: Use this to display normals using the silhouette #define DEBUG_SILHOUETTE_EDGE_MAP 0 // DaveP: Use this to display edge map using the silhouette @@ -688,7 +690,7 @@ LLProfile::Face* LLProfile::addHole(const LLProfileParams& params, BOOL flat, F3 Face *face = addFace(mTotalOut, mTotal-mTotalOut,0,LL_FACE_INNER_SIDE, flat); - static LLAlignedArray<LLVector4a,64> pt; + static thread_local LLAlignedArray<LLVector4a,64> pt; pt.resize(mTotal) ; for (S32 i=mTotalOut;i<mTotal;i++) @@ -2102,7 +2104,12 @@ void LLVolume::regen() void LLVolume::genTangents(S32 face, bool mikktspace) { - mVolumeFaces[face].createTangents(mikktspace); + // generate legacy tangents for the specified face + // if mikktspace is true, only generate tangents if mikktspace tangents are not present (handles the case for non-mesh prims) + if (!mikktspace || mVolumeFaces[face].mMikktSpaceTangents == nullptr) + { + mVolumeFaces[face].createTangents(); + } } LLVolume::~LLVolume() @@ -2424,11 +2431,10 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLSD::Binary pos = mdl[i]["Position"]; LLSD::Binary norm = mdl[i]["Normal"]; + LLSD::Binary tangent = mdl[i]["Tangent"]; LLSD::Binary tc = mdl[i]["TexCoord0"]; LLSD::Binary idx = mdl[i]["TriangleList"]; - - //copy out indices S32 num_indices = idx.size() / 2; face.resizeIndices(num_indices); @@ -2477,6 +2483,24 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); + //unpack normalized scale/translation + if (mdl[i].has("NormalizedScale")) + { + face.mNormalizedScale.setValue(mdl[i]["NormalizedScale"]); + } + else + { + face.mNormalizedScale.set(1, 1, 1); + } + if (mdl[i].has("NormalizedTranslation")) + { + face.mNormalizedTranslation.setValue(mdl[i]["NormalizedTranslation"]); + } + else + { + face.mNormalizedTranslation.set(1, 1, 1); + } + LLVector4a pos_range; pos_range.setSub(max_pos, min_pos); LLVector2 tc_range2 = max_tc - min_tc; @@ -2527,6 +2551,35 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } +#if 0 + { + if (!tangent.empty()) + { + face.allocateTangents(face.mNumVertices, true); + U16* t = (U16*)&(tangent[0]); + + // store incoming tangents in mMikktSpaceTangents + // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the CLTF shaders to + // maintain compliance with the GLTF spec + LLVector4a* t_out = face.mMikktSpaceTangents; + + for (U32 j = 0; j < num_verts; ++j) + { + t_out->set((F32)t[0], (F32)t[1], (F32)t[2], (F32) t[3]); + t_out->div(65535.f); + t_out->mul(2.f); + t_out->sub(1.f); + + F32* tp = t_out->getF32ptr(); + tp[3] = tp[3] < 0.f ? -1.f : 1.f; + + t_out++; + t += 4; + } + } + } +#endif + { if (!tc.empty()) { @@ -2730,7 +2783,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } - if (!cacheOptimize()) + if (!cacheOptimize(true)) { // Out of memory? LL_WARNS() << "Failed to optimize!" << LL_ENDL; @@ -2771,11 +2824,11 @@ void LLVolume::copyVolumeFaces(const LLVolume* volume) mSculptLevel = 0; } -bool LLVolume::cacheOptimize() +bool LLVolume::cacheOptimize(bool gen_tangents) { for (S32 i = 0; i < mVolumeFaces.size(); ++i) { - if (!mVolumeFaces[i].cacheOptimize()) + if (!mVolumeFaces[i].cacheOptimize(gen_tangents)) { return false; } @@ -4855,7 +4908,9 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } mOptimized = src.mOptimized; - + mNormalizedScale = src.mNormalizedScale; + mNormalizedTranslation = src.mNormalizedTranslation; + //delete return *this; } @@ -5373,251 +5428,200 @@ public: } }; +// data structures for tangent generation -bool LLVolumeFace::cacheOptimize() -{ //optimize for vertex cache according to Forsyth method: - // http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html - - llassert(!mOptimized); - mOptimized = TRUE; +struct MikktData +{ + LLVolumeFace* face; + std::vector<LLVector3> p; + std::vector<LLVector3> n; + std::vector<LLVector2> tc; + std::vector<LLVector4> w; + std::vector<LLVector4> t; + + MikktData(LLVolumeFace* f) + : face(f) + { + U32 count = face->mNumIndices; - LLVCacheLRU cache; - - if (mNumVertices < 3 || mNumIndices < 3) - { //nothing to do - return true; - } + p.resize(count); + n.resize(count); + tc.resize(count); + t.resize(count); - //mapping of vertices to triangles and indices - std::vector<LLVCacheVertexData> vertex_data; + if (face->mWeights) + { + w.resize(count); + } - //mapping of triangles do vertices - std::vector<LLVCacheTriangleData> triangle_data; - try - { - triangle_data.resize(mNumIndices / 3); - vertex_data.resize(mNumVertices); + LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]); + - for (U32 i = 0; i < mNumIndices; i++) - { //populate vertex data and triangle data arrays - U16 idx = mIndices[i]; - U32 tri_idx = i / 3; + for (int i = 0; i < face->mNumIndices; ++i) + { + U32 idx = face->mIndices[i]; + + p[i].set(face->mPositions[idx].getF32ptr()); + p[i].scaleVec(face->mNormalizedScale); //put mesh in original coordinate frame when reconstructing tangents + n[i].set(face->mNormals[idx].getF32ptr()); + n[i].scaleVec(inv_scale); + n[i].normalize(); + tc[i].set(face->mTexCoords[idx]); - vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx])); - vertex_data[idx].mIdx = idx; - triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]); + if (face->mWeights) + { + w[i].set(face->mWeights[idx].getF32ptr()); + } } } - catch (std::bad_alloc&) - { - // resize or push_back failed - LL_WARNS("LLVOLUME") << "Resize for " << mNumVertices << " vertices failed" << LL_ENDL; - return false; - } +}; - /*F32 pre_acmr = 1.f; - //measure cache misses from before rebuild - { - LLVCacheFIFO test_cache; - for (U32 i = 0; i < mNumIndices; ++i) - { - test_cache.addVertex(&vertex_data[mIndices[i]]); - } - for (U32 i = 0; i < mNumVertices; i++) - { - vertex_data[i].mCacheTag = -1; - } +bool LLVolumeFace::cacheOptimize(bool gen_tangents) +{ //optimize for vertex cache according to Forsyth method: + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + llassert(!mOptimized); + mOptimized = TRUE; - pre_acmr = (F32) test_cache.mMisses/(mNumIndices/3); - }*/ + if (mMikktSpaceTangents == nullptr && gen_tangents && mNormals && mTexCoords) + { // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change + allocateTangents(mNumVertices, true); - for (U32 i = 0; i < mNumVertices; i++) - { //initialize score values (no cache -- might try a fifo cache here) - LLVCacheVertexData& data = vertex_data[i]; + SMikkTSpaceInterface ms; - data.mScore = find_vertex_score(data); - data.mActiveTriangles = data.mTriangles.size(); + ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + return face->mNumIndices / 3; + }; - for (U32 j = 0; j < data.mActiveTriangles; ++j) - { - data.mTriangles[j]->mScore += data.mScore; - } - } + ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) + { + return 3; + }; - //sort triangle data by score - std::sort(triangle_data.begin(), triangle_data.end()); + ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + F32* v = data->p[iFace * 3 + iVert].mV; + fvPosOut[0] = v[0]; + fvPosOut[1] = v[1]; + fvPosOut[2] = v[2]; + }; + + ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + F32* n = data->n[iFace * 3 + iVert].mV; + fvNormOut[0] = n[0]; + fvNormOut[1] = n[1]; + fvNormOut[2] = n[2]; + }; + + ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + F32* tc = data->tc[iFace * 3 + iVert].mV; + fvTexcOut[0] = tc[0]; + fvTexcOut[1] = tc[1]; + }; - std::vector<U16> new_indices; + ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + S32 i = iFace * 3 + iVert; + + data->t[i].set(fvTangent); + data->t[i].mV[3] = fSign; + }; - LLVCacheTriangleData* tri; + ms.m_setTSpace = nullptr; - //prime pump by adding first triangle to cache; - tri = &(triangle_data[0]); - cache.addTriangle(tri); - new_indices.push_back(tri->mVertex[0]->mIdx); - new_indices.push_back(tri->mVertex[1]->mIdx); - new_indices.push_back(tri->mVertex[2]->mIdx); - tri->complete(); + MikktData data(this); - U32 breaks = 0; - for (U32 i = 1; i < mNumIndices/3; ++i) - { - cache.updateScores(); - tri = cache.mBestTriangle; - if (!tri) - { - breaks++; - for (U32 j = 0; j < triangle_data.size(); ++j) - { - if (triangle_data[j].mActive) - { - tri = &(triangle_data[j]); - break; - } - } - } - - cache.addTriangle(tri); - new_indices.push_back(tri->mVertex[0]->mIdx); - new_indices.push_back(tri->mVertex[1]->mIdx); - new_indices.push_back(tri->mVertex[2]->mIdx); - tri->complete(); - } + SMikkTSpaceContext ctx = { &ms, &data }; - for (U32 i = 0; i < mNumIndices; ++i) - { - mIndices[i] = new_indices[i]; - } + genTangSpaceDefault(&ctx); - /*F32 post_acmr = 1.f; - //measure cache misses from after rebuild - { - LLVCacheFIFO test_cache; - for (U32 i = 0; i < mNumVertices; i++) - { - vertex_data[i].mCacheTag = -1; - } + //re-weld + meshopt_Stream mos[] = + { + { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, + { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, + { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } + }; - for (U32 i = 0; i < mNumIndices; ++i) - { - test_cache.addVertex(&vertex_data[mIndices[i]]); - } - - post_acmr = (F32) test_cache.mMisses/(mNumIndices/3); - }*/ + std::vector<U32> remap; + remap.resize(data.p.size()); - //optimize for pre-TnL cache - - //allocate space for new buffer - S32 num_verts = mNumVertices; - S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; - LLVector4a* pos = (LLVector4a*) ll_aligned_malloc<64>(sizeof(LLVector4a)*2*num_verts+size); - if (pos == NULL) - { - LL_WARNS("LLVOLUME") << "Allocation of positions vector[" << sizeof(LLVector4a) * 2 * num_verts + size << "] failed. " << LL_ENDL; - return false; - } - LLVector4a* norm = pos + num_verts; - LLVector2* tc = (LLVector2*) (norm + num_verts); + U32 stream_count = data.w.empty() ? 4 : 5; - LLVector4a* wght = NULL; - if (mWeights) - { - wght = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - if (wght == NULL) - { - ll_aligned_free<64>(pos); - LL_WARNS("LLVOLUME") << "Allocation of weights[" << sizeof(LLVector4a) * num_verts << "] failed" << LL_ENDL; - return false; - } - } + U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); - llassert(mTangents == nullptr); // cache optimize called too late, tangents already generated - llassert(mMikktSpaceTangents == nullptr); + std::vector<U32> indices; + indices.resize(mNumIndices); - // ===================================================================================== - // DEPRECATED -- cacheOptimize should always be called before tangents are generated - // ===================================================================================== - LLVector4a* binorm = NULL; - if (mTangents) - { - binorm = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - if (binorm == NULL) - { - ll_aligned_free<64>(pos); - ll_aligned_free_16(wght); - LL_WARNS("LLVOLUME") << "Allocation of binormals[" << sizeof(LLVector4a)*num_verts << "] failed" << LL_ENDL; - return false; - } - } - // ===================================================================================== + //copy results back into volume + resizeVertices(vert_count); - //allocate mapping of old indices to new indices - std::vector<S32> new_idx; - try - { - new_idx.resize(mNumVertices, -1); - } - catch (std::bad_alloc&) - { - ll_aligned_free<64>(pos); - ll_aligned_free_16(wght); - ll_aligned_free_16(binorm); - LL_WARNS("LLVOLUME") << "Resize failed: " << mNumVertices << LL_ENDL; - return false; - } + if (!data.w.empty()) + { + allocateWeights(vert_count); + } - S32 cur_idx = 0; - for (U32 i = 0; i < mNumIndices; ++i) - { - U16 idx = mIndices[i]; - if (new_idx[idx] == -1) - { //this vertex hasn't been added yet - new_idx[idx] = cur_idx; + allocateTangents(mNumVertices, true); - //copy vertex data - pos[cur_idx] = mPositions[idx]; - norm[cur_idx] = mNormals[idx]; - tc[cur_idx] = mTexCoords[idx]; - if (mWeights) - { - wght[cur_idx] = mWeights[idx]; - } - if (mTangents) - { - binorm[cur_idx] = mTangents[idx]; - } + for (int i = 0; i < mNumIndices; ++i) + { + U32 src_idx = i; + U32 dst_idx = remap[i]; + mIndices[i] = dst_idx; - cur_idx++; - } - } + mPositions[dst_idx].load3(data.p[src_idx].mV); + mNormals[dst_idx].load3(data.n[src_idx].mV); + mTexCoords[dst_idx] = data.tc[src_idx]; - for (U32 i = 0; i < mNumIndices; ++i) - { - mIndices[i] = new_idx[mIndices[i]]; - } - - ll_aligned_free<64>(mPositions); - // DO NOT free mNormals and mTexCoords as they are part of mPositions buffer - ll_aligned_free_16(mWeights); - ll_aligned_free_16(mTangents); -#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS - ll_aligned_free_16(mJointIndices); - ll_aligned_free_16(mJustWeights); - mJustWeights = NULL; - mJointIndices = NULL; // filled in later as necessary by skinning code for acceleration -#endif + mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); - mPositions = pos; - mNormals = norm; - mTexCoords = tc; - mWeights = wght; - mTangents = binorm; + if (mWeights) + { + mWeights[dst_idx].loadua(data.w[src_idx].mV); + } + } + + + // put back in normalized coordinate frame + LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]); + LLVector4a scale; + scale.load3(mNormalizedScale.mV); + scale.getF32ptr()[3] = 1.f; - //std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks); - //LL_INFOS() << result << LL_ENDL; + for (int i = 0; i < mNumVertices; ++i) + { + mPositions[i].mul(inv_scale); + mNormals[i].mul(scale); + mNormals[i].normalize3(); + F32 w = mMikktSpaceTangents[i].getF32ptr()[3]; + mMikktSpaceTangents[i].mul(scale); + mMikktSpaceTangents[i].normalize3(); + mMikktSpaceTangents[i].getF32ptr()[3] = w; + } + } + + // cache optimize index buffer + + // meshopt needs scratch space, do some pointer shuffling to avoid an extra index buffer copy + U16* src_indices = mIndices; + mIndices = nullptr; + resizeIndices(mNumIndices); + + meshopt_optimizeVertexCache<U16>(mIndices, src_indices, mNumIndices, mNumVertices); + + ll_aligned_free_16(src_indices); return true; } @@ -6407,209 +6411,25 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build) void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent); - -// data structures for tangent generation - -// key for summing tangents -// We will blend tangents wherever a common position and normal is found -struct MikktKey -{ - // Position - LLVector3 p; - // Normal - LLVector3 n; - - bool operator==(const MikktKey& rhs) const { return p == rhs.p && n == rhs.n; } -}; - -// sum of tangents and list of signs and index array indices for a given position and normal combination -// sign must be kept separate from summed tangent because a single position and normal may have a different -// tangent facing where UV seams exist -struct MikktTangent -{ - // tangent vector - LLVector3 t; - // signs - std::vector<F32> s; - // indices (in index array) - std::vector<S32> i; -}; - -// hash function for MikktTangent -namespace boost -{ - template <> - struct hash<LLVector3> - { - std::size_t operator()(LLVector3 const& k) const - { - size_t seed = 0; - boost::hash_combine(seed, k.mV[0]); - boost::hash_combine(seed, k.mV[1]); - boost::hash_combine(seed, k.mV[2]); - return seed; - } - }; - - template <> - struct hash<MikktKey> - { - std::size_t operator()(MikktKey const& k) const - { - size_t seed = 0; - boost::hash_combine(seed, k.p); - boost::hash_combine(seed, k.n); - return seed; - } - }; -} - -// boost adapter -namespace std -{ - template<> - struct hash<MikktKey> - { - std::size_t operator()(MikktKey const& k) const - { - return boost::hash<MikktKey>()(k); - } - }; -} - -struct MikktData -{ - LLVolumeFace* face; - std::unordered_map<MikktKey, MikktTangent > tangents; -}; - - -void LLVolumeFace::createTangents(bool mikktspace) +void LLVolumeFace::createTangents() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - auto& tangents = mikktspace ? mMikktSpaceTangents : mTangents; - - if (!tangents) + + if (!mTangents) { - allocateTangents(mNumVertices, mikktspace); + allocateTangents(mNumVertices); + + //generate tangents + LLVector4a* ptr = (LLVector4a*)mTangents; - if (mikktspace) + LLVector4a* end = mTangents + mNumVertices; + while (ptr < end) { - LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("mikktspace"); - SMikkTSpaceInterface ms; - - ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - return face->mNumIndices / 3; - }; - - ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) - { - return 3; - }; - - ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& vert = face->mPositions[idx]; - F32* v = vert.getF32ptr(); - fvPosOut[0] = v[0]; - fvPosOut[1] = v[1]; - fvPosOut[2] = v[2]; - }; - - ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& norm = face->mNormals[idx]; - F32* n = norm.getF32ptr(); - fvNormOut[0] = n[0]; - fvNormOut[1] = n[1]; - fvNormOut[2] = n[2]; - }; - - ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& tc = face->mTexCoords[idx]; - fvTexcOut[0] = tc.mV[0]; - fvTexcOut[1] = tc.mV[1]; - }; - - ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 i = iFace * 3 + iVert; - S32 idx = face->mIndices[i]; - - LLVector3 p(face->mPositions[idx].getF32ptr()); - LLVector3 n(face->mNormals[idx].getF32ptr()); - LLVector3 t(fvTangent); - - MikktKey key = { p, n }; - - MikktTangent& mt = data->tangents[key]; - mt.t += t; - mt.s.push_back(fSign); - mt.i.push_back(i); - }; - - ms.m_setTSpace = nullptr; - - MikktData data; - data.face = this; - - SMikkTSpaceContext ctx = { &ms, &data }; - - genTangSpaceDefault(&ctx); - - for (U32 i = 0; i < mNumVertices; ++i) - { - MikktKey key = { LLVector3(mPositions[i].getF32ptr()), LLVector3(mNormals[i].getF32ptr()) }; - MikktTangent& t = data.tangents[key]; - - //set tangent - mMikktSpaceTangents[i].load3(t.t.mV); - mMikktSpaceTangents[i].normalize3fast(); - - //set sign - F32 sign = 0.f; - for (int j = 0; j < t.i.size(); ++j) - { - if (mIndices[t.i[j]] == i) - { - sign = t.s[j]; - break; - } - } - - llassert(sign != 0.f); - mMikktSpaceTangents[i].getF32ptr()[3] = sign; - } + (*ptr++).clear(); } - else - { - //generate tangents - LLVector4a* ptr = (LLVector4a*)tangents; - LLVector4a* end = mTangents + mNumVertices; - while (ptr < end) - { - (*ptr++).clear(); - } - - CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, tangents); - } + CalculateTangentArray(mNumVertices, mPositions, mNormals, mTexCoords, mNumIndices / 3, mIndices, mTangents); //normalize normals for (U32 i = 0; i < mNumVertices; i++) @@ -6618,6 +6438,7 @@ void LLVolumeFace::createTangents(bool mikktspace) mNormals[i].normalize3fast(); } } + } void LLVolumeFace::resizeVertices(S32 num_verts) @@ -6882,13 +6703,19 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) else { // Get s value for tex-coord. - if (!flat) + S32 index = mBeginS + s; + if (index >= profile.size()) + { + // edge? + ss = flat ? 1.f - begin_stex : 1.f; + } + else if (!flat) { - ss = profile[mBeginS + s][2]; + ss = profile[index][2]; } else { - ss = profile[mBeginS + s][2] - begin_stex; + ss = profile[index][2] - begin_stex; } } @@ -7074,7 +6901,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) LLVector4a* norm = mNormals; - static LLAlignedArray<LLVector4a, 64> triangle_normals; + static thread_local LLAlignedArray<LLVector4a, 64> triangle_normals; try { triangle_normals.resize(count); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 8c604c5d1a..6ea12c6920 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -870,7 +870,7 @@ private: public: BOOL create(LLVolume* volume, BOOL partial_build = FALSE); - void createTangents(bool mikktspace = false); + void createTangents(); void resizeVertices(S32 num_verts); void allocateTangents(S32 num_verts, bool mikktspace = false); @@ -907,7 +907,7 @@ public: void remap(); void optimize(F32 angle_cutoff = 2.f); - bool cacheOptimize(); + bool cacheOptimize(bool gen_tangents = false); void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); @@ -957,10 +957,6 @@ public: // indexes for mPositions/mNormals/mTexCoords U16* mIndices; - // vertex buffer filled in by LLFace to cache this volume face geometry in vram - // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer) - mutable LLPointer<LLRefCount> mVertexBuffer; - std::vector<S32> mEdge; //list of skin weights for rigged volumes @@ -984,6 +980,12 @@ public: //whether or not face has been cache optimized BOOL mOptimized; + // if this is a mesh asset, scale and translation that were applied + // when encoding the source mesh into a unit cube + // used for regenerating tangents + LLVector3 mNormalizedScale = LLVector3(1,1,1); + LLVector3 mNormalizedTranslation; + private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); @@ -1083,7 +1085,10 @@ public: void copyVolumeFaces(const LLVolume* volume); void copyFacesTo(std::vector<LLVolumeFace> &faces) const; void copyFacesFrom(const std::vector<LLVolumeFace> &faces); - bool cacheOptimize(); + + // use meshoptimizer to optimize index buffer for vertex shader cache + // gen_tangents - if true, generate MikkTSpace tangents if needed before optimizing index buffer + bool cacheOptimize(bool gen_tangents = false); private: void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index ae066112c1..33a0b6abdb 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -194,6 +194,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults); } } + catch (const LLCoros::Stop&) + { + LL_DEBUGS("AvNameCache") << "Received a shutdown exception" << LL_ENDL; + } catch (...) { LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName() diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 2d460826ff..c5bc37dd0e 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -32,7 +32,6 @@ #include "llcoros.h" #include "llcorehttputil.h" #include "lluuid.h" -#include <boost/smart_ptr/shared_ptr.hpp> class LLCoprocedurePool; @@ -84,7 +83,7 @@ public: private: - typedef boost::shared_ptr<LLCoprocedurePool> poolPtr_t; + typedef std::shared_ptr<LLCoprocedurePool> poolPtr_t; typedef std::map<std::string, poolPtr_t> poolMap_t; poolMap_t mPoolMap; diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 219b1855d2..57ea954054 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -666,7 +666,6 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance() char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock"); char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID"); char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel"); -char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage"); char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats"); char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos"); char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit"); @@ -1047,7 +1046,6 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter"); char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity"); char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket"); -char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket"); char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal"); char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel"); char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing"); @@ -1236,7 +1234,6 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease"); char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType"); char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply"); -char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData"); char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage"); char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation"); char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection"); @@ -1386,6 +1383,7 @@ char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getIns char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride"); char const* const _PREHASH_ParcelEnvironmentBlock = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentBlock"); char const* const _PREHASH_ParcelEnvironmentVersion = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentVersion"); +char const* const _PREHASH_ParcelExtendedFlags = LLMessageStringTable::getInstance()->getString("ParcelExtendedFlags"); char const* const _PREHASH_RegionAllowEnvironmentOverride = LLMessageStringTable::getInstance()->getString("RegionAllowEnvironmentOverride"); char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord"); char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 8f6ee5a327..572dadd408 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -666,7 +666,6 @@ extern char const* const _PREHASH_GroupRolesCount; extern char const* const _PREHASH_SimulatorBlock; extern char const* const _PREHASH_GroupID; extern char const* const _PREHASH_AgentVel; -extern char const* const _PREHASH_RequestImage; extern char const* const _PREHASH_NetStats; extern char const* const _PREHASH_AgentPos; extern char const* const _PREHASH_AgentSit; @@ -1047,7 +1046,6 @@ extern char const* const _PREHASH_SortOrder; extern char const* const _PREHASH_Hunter; extern char const* const _PREHASH_SunAngVelocity; extern char const* const _PREHASH_BinaryBucket; -extern char const* const _PREHASH_ImagePacket; extern char const* const _PREHASH_StartGroupProposal; extern char const* const _PREHASH_EnergyLevel; extern char const* const _PREHASH_PriceForListing; @@ -1386,6 +1384,7 @@ extern char const* const _PREHASH_RegionAllowAccessBlock; extern char const* const _PREHASH_RegionAllowAccessOverride; extern char const* const _PREHASH_ParcelEnvironmentBlock; extern char const* const _PREHASH_ParcelEnvironmentVersion; +extern char const* const _PREHASH_ParcelExtendedFlags; extern char const* const _PREHASH_RegionAllowEnvironmentOverride; extern char const* const _PREHASH_UCoord; extern char const* const _PREHASH_VCoord; diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 6f88232c1d..3e72710366 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -1549,6 +1549,7 @@ void LLPluginClassMedia::seek(float time) LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek"); message.setValueReal("time", time); + mCurrentTime = time; // assume that it worked and we will receive an update later sendMessage(message); } diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index eef22156bc..1fbbad06d4 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -999,7 +999,7 @@ void LLPluginProcessParent::poll(F64 timeout) while (itClean != sInstances.end()) { if ((*itClean).second->isDone()) - sInstances.erase(itClean++); + itClean = sInstances.erase(itClean); else ++itClean; } diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 50f4a4306e..dbb34ab60b 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2561,6 +2561,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& mo ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder); + // remove unused/redundant vertices after normalizing if (!mNoOptimize) { ret->remapVolumeFaces(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 285c5f656b..a6492f43d4 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -296,6 +296,7 @@ void LLModel::normalizeVolumeFaces() // the positions to fit within the unit cube. LLVector4a* pos = (LLVector4a*) face.mPositions; LLVector4a* norm = (LLVector4a*) face.mNormals; + LLVector4a* t = (LLVector4a*)face.mMikktSpaceTangents; for (U32 j = 0; j < face.mNumVertices; ++j) { @@ -306,6 +307,14 @@ void LLModel::normalizeVolumeFaces() norm[j].mul(inv_scale); norm[j].normalize3(); } + + if (t) + { + F32 w = t[j].getF32ptr()[3]; + t[j].mul(inv_scale); + t[j].normalize3(); + t[j].getF32ptr()[3] = w; + } } } @@ -319,6 +328,12 @@ void LLModel::normalizeVolumeFaces() mNormalizedScale.set(normalized_scale.getF32ptr()); mNormalizedTranslation.set(trans.getF32ptr()); mNormalizedTranslation *= -1.f; + + for (auto& face : mVolumeFaces) + { + face.mNormalizedScale = mNormalizedScale; + face.mNormalizedTranslation = mNormalizedTranslation; + } } } @@ -726,10 +741,12 @@ LLSD LLModel::writeModel( LLSD::Binary verts(face.mNumVertices*3*2); LLSD::Binary tc(face.mNumVertices*2*2); LLSD::Binary normals(face.mNumVertices*3*2); + LLSD::Binary tangents(face.mNumVertices * 4 * 2); LLSD::Binary indices(face.mNumIndices*2); U32 vert_idx = 0; U32 norm_idx = 0; + //U32 tan_idx = 0; U32 tc_idx = 0; LLVector2* ftc = (LLVector2*) face.mTexCoords; @@ -782,6 +799,24 @@ LLSD LLModel::writeModel( normals[norm_idx++] = buff[1]; } } + +#if 0 + if (face.mMikktSpaceTangents) + { //normals + F32* tangent = face.mMikktSpaceTangents[j].getF32ptr(); + + for (U32 k = 0; k < 4; ++k) + { //for each component + //convert to 16-bit normalized + U16 val = (U16)((tangent[k] + 1.f) * 0.5f * 65535); + U8* buff = (U8*)&val; + + //write to binary buffer + tangents[tan_idx++] = buff[0]; + tangents[tan_idx++] = buff[1]; + } + } +#endif //texcoord if (face.mTexCoords) @@ -812,6 +847,9 @@ LLSD LLModel::writeModel( //write out face data mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); + mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue(); + mdl[model_names[idx]][i]["NormalizedTranslation"] = face.mNormalizedTranslation.getValue(); + mdl[model_names[idx]][i]["Position"] = verts; if (face.mNormals) @@ -819,6 +857,11 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["Normal"] = normals; } + if (face.mMikktSpaceTangents) + { + mdl[model_names[idx]][i]["Tangent"] = tangents; + } + if (face.mTexCoords) { mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); @@ -843,7 +886,7 @@ LLSD LLModel::writeModel( { LLVector3 pos(face.mPositions[j].getF32ptr()); - weight_list& weights = high->getJointInfluences(pos); + weight_list& weights = model[idx]->getJointInfluences(pos); S32 count = 0; for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) @@ -1553,6 +1596,25 @@ void LLMeshSkinInfo::updateHash() mHash = digest[0]; } +U32 LLMeshSkinInfo::sizeBytes() const +{ + U32 res = sizeof(LLUUID); // mMeshID + + res += sizeof(std::vector<std::string>) + sizeof(std::string) * mJointNames.size(); + for (U32 i = 0; i < mJointNames.size(); ++i) + { + res += mJointNames[i].size(); // actual size, not capacity + } + + res += sizeof(std::vector<S32>) + sizeof(S32) * mJointNums.size(); + res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mInvBindMatrix.size(); + res += sizeof(std::vector<LLMatrix4>) + 16 * sizeof(float) * mAlternateBindMatrix.size(); + res += 16 * sizeof(float); //mBindShapeMatrix + res += sizeof(float) + 3 * sizeof(bool); + + return res; +} + LLModel::Decomposition::Decomposition(LLSD& data) { fromLLSD(data); @@ -1659,6 +1721,30 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp) } } +U32 LLModel::Decomposition::sizeBytes() const +{ + U32 res = sizeof(LLUUID); // mMeshID + + res += sizeof(LLModel::convex_hull_decomposition) + sizeof(std::vector<LLVector3>) * mHull.size(); + for (U32 i = 0; i < mHull.size(); ++i) + { + res += mHull[i].size() * sizeof(LLVector3); + } + + res += sizeof(LLModel::hull) + sizeof(LLVector3) * mBaseHull.size(); + + res += sizeof(std::vector<LLModel::PhysicsMesh>) + sizeof(std::vector<LLModel::PhysicsMesh>) * mMesh.size(); + for (U32 i = 0; i < mMesh.size(); ++i) + { + res += mMesh[i].sizeBytes(); + } + + res += sizeof(std::vector<LLModel::PhysicsMesh>) * 2; + res += mBaseHullMesh.sizeBytes() + mPhysicsShapeMesh.sizeBytes(); + + return res; +} + bool LLModel::Decomposition::hasHullList() const { return !mHull.empty() ; diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 354ceb26b7..a6ab96ab18 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -50,6 +50,7 @@ public: void fromLLSD(LLSD& data); LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; void updateHash(); + U32 sizeBytes() const; LLUUID mMeshID; std::vector<std::string> mJointNames; @@ -112,6 +113,14 @@ public: { return mPositions.empty(); } + + U32 sizeBytes() const + { + U32 res = sizeof(std::vector<LLVector3>) * 2; + res += sizeof(LLVector3) * mPositions.size(); + res += sizeof(LLVector3) * mNormals.size(); + return res; + } }; class Decomposition @@ -122,6 +131,7 @@ public: void fromLLSD(LLSD& data); LLSD asLLSD() const; bool hasHullList() const; + U32 sizeBytes() const; void merge(const Decomposition* rhs); diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index e41765622f..254288a86e 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -67,7 +67,7 @@ void LLCubeMap::initGL() { llassert(gGLManager.mInited); - if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (LLCubeMap::sUseCubeMaps) { // Not initialized, do stuff. if (mImages[0].isNull()) @@ -252,7 +252,7 @@ void LLCubeMap::enable(S32 stage) void LLCubeMap::enableTexture(S32 stage) { mTextureStage = stage; - if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps) + if (stage >= 0 && LLCubeMap::sUseCubeMaps) { gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP); } @@ -265,7 +265,7 @@ void LLCubeMap::disable(void) void LLCubeMap::disableTexture(void) { - if (gGLManager.mHasCubeMap && mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) + if (mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) { gGL.getTexUnit(mTextureStage)->disable(); if (mTextureStage == 0) diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index 08ff7c9414..bb4bd58121 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -107,18 +107,18 @@ LLCubeMapArray::~LLCubeMapArray() { } -void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count) +void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL use_mips) { U32 texname = 0; LLImageGL::generateTextures(1, &texname); - mImage = new LLImageGL(resolution, resolution, components, TRUE); + mImage = new LLImageGL(resolution, resolution, components, use_mips); mImage->setTexName(texname); mImage->setTarget(sTargets[0], LLTexUnit::TT_CUBE_MAP_ARRAY); - mImage->setUseMipMaps(TRUE); - mImage->setHasMipMaps(TRUE); + mImage->setUseMipMaps(use_mips); + mImage->setHasMipMaps(use_mips); bind(0); @@ -127,9 +127,15 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count) mImage->setAddressMode(LLTexUnit::TAM_CLAMP); - mImage->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); - - glGenerateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY); + if (use_mips) + { + mImage->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); + glGenerateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY); + } + else + { + mImage->setFilteringOption(LLTexUnit::TFO_BILINEAR); + } unbind(); } @@ -137,7 +143,7 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count) void LLCubeMapArray::bind(S32 stage) { mTextureStage = stage; - gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_CUBE_MAP_ARRAY, getGLName(), TRUE); + gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_CUBE_MAP_ARRAY, getGLName(), mImage->getUseMipMaps()); } void LLCubeMapArray::unbind() diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h index cbc0692afb..19c86278a1 100644 --- a/indra/llrender/llcubemaparray.h +++ b/indra/llrender/llcubemaparray.h @@ -51,7 +51,8 @@ public: // res - resolution of each cube face // components - number of components per pixel // count - number of cube maps in the array - void allocate(U32 res, U32 components, U32 count); + // use_mips - if TRUE, mipmaps will be allocated for this cube map array and anisotropic filtering will be used + void allocate(U32 res, U32 components, U32 count, BOOL use_mips = TRUE); void bind(S32 stage); void unbind(); diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 5253ed3d51..71303b0517 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -86,15 +86,15 @@ void APIENTRY gl_debug_callback(GLenum source, const GLchar* message, GLvoid* userParam) { - /*if (severity != GL_DEBUG_SEVERITY_HIGH_ARB // && - severity != GL_DEBUG_SEVERITY_MEDIUM_ARB && - severity != GL_DEBUG_SEVERITY_LOW_ARB + /*if (severity != GL_DEBUG_SEVERITY_HIGH // && + severity != GL_DEBUG_SEVERITY_MEDIUM && + severity != GL_DEBUG_SEVERITY_LOW ) { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints) return; }*/ - if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) + if (severity == GL_DEBUG_SEVERITY_HIGH) { LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; } @@ -107,7 +107,15 @@ void APIENTRY gl_debug_callback(GLenum source, LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; LL_WARNS() << "Message: " << message << LL_ENDL; LL_WARNS() << "-----------------------" << LL_ENDL; - if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) + + GLint vao = 0; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao); + GLint vbo = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vbo); + GLint ibo = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo); + + if (severity == GL_DEBUG_SEVERITY_HIGH) { LL_ERRS() << "Halting on GL Error" << LL_ENDL; } @@ -931,44 +939,12 @@ LLGLManager gGLManager; LLGLManager::LLGLManager() : mInited(FALSE), mIsDisabled(FALSE), - - mHasMultitexture(FALSE), - mHasATIMemInfo(FALSE), - mHasAMDAssociations(FALSE), - mHasNVXMemInfo(FALSE), - mNumTextureUnits(1), - mHasMipMapGeneration(FALSE), - mHasCompressedTextures(FALSE), - mHasFramebufferObject(FALSE), mMaxSamples(0), - mHasBlendFuncSeparate(FALSE), - mHasSync(FALSE), - mHasVertexBufferObject(FALSE), - mHasVertexArrayObject(FALSE), - mHasMapBufferRange(FALSE), - mHasFlushBufferRange(FALSE), - mHasPBuffer(FALSE), - mNumTextureImageUnits(0), - mHasOcclusionQuery(FALSE), - mHasTimerQuery(FALSE), - mHasOcclusionQuery2(FALSE), - mHasPointParameters(FALSE), - mHasDrawBuffers(FALSE), - mHasTextureRectangle(FALSE), - mHasTextureMultisample(FALSE), - mHasTransformFeedback(FALSE), - mHasUniformBufferObject(FALSE), + mNumTextureImageUnits(1), mMaxSampleMaskWords(0), mMaxColorTextureSamples(0), mMaxDepthTextureSamples(0), mMaxIntegerSamples(0), - - mHasAnisotropic(FALSE), - mHasARBEnvCombine(FALSE), - mHasCubeMap(FALSE), - mHasCubeMapArray(FALSE), - mHasDebugOutput(FALSE), - mIsAMD(FALSE), mIsNVIDIA(FALSE), mIsIntel(FALSE), @@ -976,9 +952,6 @@ LLGLManager::LLGLManager() : mIsMobileGF(FALSE), #endif mHasRequirements(TRUE), - - mHasSeparateSpecularColor(FALSE), - mDriverVersionMajor(1), mDriverVersionMinor(0), mDriverVersionRelease(0), @@ -996,7 +969,6 @@ LLGLManager::LLGLManager() : //--------------------------------------------------------------------- void LLGLManager::initWGL() { - mHasPBuffer = FALSE; #if LL_WINDOWS && !LL_MESA_HEADLESS if (!glh_init_extensions("WGL_ARB_pixel_format")) { @@ -1035,10 +1007,6 @@ void LLGLManager::initWGL() { LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL; } - - mHasPBuffer = ExtensionExists("WGL_ARB_pbuffer", gGLHExts.mSysExts) && - ExtensionExists("WGL_ARB_render_texture", gGLHExts.mSysExts) && - ExtensionExists("WGL_ARB_pixel_format", gGLHExts.mSysExts); #endif } @@ -1052,7 +1020,7 @@ bool LLGLManager::initGL() stop_glerror(); -#if LL_WINDOWS +#if 0 && LL_WINDOWS if (!glGetStringi) { glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi"); @@ -1199,23 +1167,6 @@ bool LLGLManager::initGL() } #endif - if (mHasATIMemInfo && mVRAM == 0) - { //ask the gl how much vram is free at startup and attempt to use no more than half of that - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - - mVRAM = meminfo[0] / 1024; - LL_WARNS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL; - } - - if (mHasNVXMemInfo && mVRAM == 0) - { - S32 dedicated_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory); - mVRAM = dedicated_memory/1024; - LL_WARNS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL; - } - #if LL_WINDOWS if (mVRAM < 256) { @@ -1243,62 +1194,22 @@ bool LLGLManager::initGL() stop_glerror(); - GLint num_tex_image_units; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units); - mNumTextureImageUnits = llmin(num_tex_image_units, 32); - - if (mHasMultitexture) + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits); + stop_glerror(); + glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); + stop_glerror(); + glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); + stop_glerror(); + if (mGLVersion >= 4.59f) { - if (LLRender::sGLCoreProfile) - { - mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS); - } - else - { - GLint num_tex_units; - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units); - mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS); - if (mIsIntel) - { - mNumTextureUnits = llmin(mNumTextureUnits, 2); - } - } + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxAnisotropy); } - else - { - mHasRequirements = FALSE; - - // We don't support cards that don't support the GL_ARB_multitexture extension - LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL; - return false; - } - - stop_glerror(); - - if (mHasTextureMultisample) - { - glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); - glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); - glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); - glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); - } - - stop_glerror(); - - //HACK always disable texture multisample, use FXAA instead - mHasTextureMultisample = FALSE; -#if LL_WINDOWS - if (mIsIntel && mGLVersion <= 3.f) - { //never try to use framebuffer objects on older intel drivers (crashy) - mHasFramebufferObject = FALSE; - } -#endif - - if (mHasFramebufferObject) - { - glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); - } - stop_glerror(); initGLStates(); @@ -1406,62 +1317,22 @@ void LLGLManager::asLLSD(LLSD& info) info["vram"] = mVRAM; - // Extensions used by everyone - info["has_multitexture"] = mHasMultitexture; - info["has_ati_mem_info"] = mHasATIMemInfo; - info["has_nvx_mem_info"] = mHasNVXMemInfo; - info["num_texture_units"] = mNumTextureUnits; - info["has_mip_map_generation"] = mHasMipMapGeneration; - info["has_compressed_textures"] = mHasCompressedTextures; - info["has_framebuffer_object"] = mHasFramebufferObject; + // OpenGL limits info["max_samples"] = mMaxSamples; - info["has_blend_func_separate"] = mHasBlendFuncSeparate || LLRender::sGLCoreProfile; - - // ARB Extensions - info["has_vertex_buffer_object"] = mHasVertexBufferObject; - info["has_vertex_array_object"] = mHasVertexArrayObject; - info["has_sync"] = mHasSync; - info["has_map_buffer_range"] = mHasMapBufferRange; - info["has_flush_buffer_range"] = mHasFlushBufferRange; - info["has_pbuffer"] = mHasPBuffer; - info["has_shader_objects"] = std::string("Assumed TRUE"); // was mHasShaderObjects; - info["has_vertex_shader"] = std::string("Assumed TRUE"); // was mHasVertexShader; - info["has_fragment_shader"] = std::string("Assumed TRUE"); // was mHasFragmentShader; info["num_texture_image_units"] = mNumTextureImageUnits; - info["has_occlusion_query"] = mHasOcclusionQuery; - info["has_timer_query"] = mHasTimerQuery; - info["has_occlusion_query2"] = mHasOcclusionQuery2; - info["has_point_parameters"] = mHasPointParameters; - info["has_draw_buffers"] = mHasDrawBuffers; - info["has_depth_clamp"] = mHasDepthClamp; - info["has_texture_rectangle"] = mHasTextureRectangle; - info["has_texture_multisample"] = mHasTextureMultisample; - info["has_transform_feedback"] = mHasTransformFeedback; info["max_sample_mask_words"] = mMaxSampleMaskWords; info["max_color_texture_samples"] = mMaxColorTextureSamples; info["max_depth_texture_samples"] = mMaxDepthTextureSamples; info["max_integer_samples"] = mMaxIntegerSamples; + info["max_vertex_range"] = mGLMaxVertexRange; + info["max_index_range"] = mGLMaxIndexRange; + info["max_texture_size"] = mGLMaxTextureSize; - // Other extensions. - info["has_anisotropic"] = mHasAnisotropic; - info["has_arb_env_combine"] = mHasARBEnvCombine; - info["has_cube_map"] = mHasCubeMap; - info["has_debug_output"] = mHasDebugOutput; - info["has_srgb_texture"] = mHassRGBTexture; - info["has_srgb_framebuffer"] = mHassRGBFramebuffer; - info["has_texture_srgb_decode"] = mHasTexturesRGBDecode; - - // Vendor-specific extensions + // Which vendor info["is_ati"] = mIsAMD; // note, do not rename is_ati to is_amd without coordinating with DW info["is_nvidia"] = mIsNVIDIA; info["is_intel"] = mIsIntel; - // Other fields - info["has_requirements"] = mHasRequirements; - info["has_separate_specular_color"] = mHasSeparateSpecularColor; - info["max_vertex_range"] = mGLMaxVertexRange; - info["max_index_range"] = mGLMaxIndexRange; - info["max_texture_size"] = mGLMaxTextureSize; info["gl_renderer"] = mGLRenderer; } @@ -1480,60 +1351,6 @@ void LLGLManager::shutdownGL() void LLGLManager::initExtensions() { -#if LL_MESA_HEADLESS -# ifdef GL_ARB_multitexture - mHasMultitexture = TRUE; -# else - mHasMultitexture = FALSE; -# endif // GL_ARB_multitexture -# ifdef GL_ARB_texture_env_combine - mHasARBEnvCombine = TRUE; -# else - mHasARBEnvCombine = FALSE; -# endif // GL_ARB_texture_env_combine -# ifdef GL_ARB_texture_compression - mHasCompressedTextures = TRUE; -# else - mHasCompressedTextures = FALSE; -# endif // GL_ARB_texture_compression -# ifdef GL_ARB_vertex_buffer_object - mHasVertexBufferObject = TRUE; -# else - mHasVertexBufferObject = FALSE; -# endif // GL_ARB_vertex_buffer_object -# ifdef GL_EXT_framebuffer_object - mHasFramebufferObject = TRUE; -# else - mHasFramebufferObject = FALSE; -# endif // GL_EXT_framebuffer_object -# ifdef GL_ARB_draw_buffers - mHasDrawBuffers = TRUE; -#else - mHasDrawBuffers = FALSE; -# endif // GL_ARB_draw_buffers -# if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp) - mHasDepthClamp = TRUE; -#else - mHasDepthClamp = FALSE; -#endif // defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp) -# if GL_EXT_blend_func_separate - mHasBlendFuncSeparate = TRUE; -#else - mHasBlendFuncSeparate = FALSE; -# endif // GL_EXT_blend_func_separate - mHasMipMapGeneration = FALSE; - mHasSeparateSpecularColor = FALSE; - mHasAnisotropic = FALSE; - mHasCubeMap = FALSE; - mHasOcclusionQuery = FALSE; - mHasPointParameters = FALSE; - mHasTextureRectangle = FALSE; -#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called - - mHasMultitexture = TRUE; - mHasCubeMap = TRUE; - mHasCompressedTextures = TRUE; - #if LL_DARWIN GLint num_extensions = 0; std::string all_extensions{""}; @@ -1550,173 +1367,12 @@ void LLGLManager::initExtensions() } #endif - mHasSeparateSpecularColor = ExtensionExists("GL_EXT_separate_specular_color", gGLHExts.mSysExts); - mHasAnisotropic = ExtensionExists("GL_EXT_texture_filter_anisotropic", gGLHExts.mSysExts); - - // In core profile - mHasARBEnvCombine = TRUE; //ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts); - mHasTimerQuery = FALSE; //FIXME //ExtensionExists("GL_ARB_timer_query", gGLHExts.mSysExts); - mHasOcclusionQuery = TRUE; //ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); - mHasOcclusionQuery2 = TRUE; // ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts); - mHasVertexBufferObject = TRUE; //ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); - mHasVertexArrayObject = TRUE; //ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts); - mHasMapBufferRange = TRUE; ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts); - mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts); // Apple has mHasMapBufferRange now - mHasSync = TRUE; //ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts); - mHasFramebufferObject = TRUE; //ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts); - mHassRGBFramebuffer = TRUE; //ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts); - mHasDrawBuffers = TRUE; //ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); - mHasTextureRectangle = TRUE; //ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); - mHasTextureMultisample = TRUE; //ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts); - mHasUniformBufferObject = TRUE; //ExtensionExists("GL_ARB_uniform_buffer_object", gGLHExts.mSysExts); - mHasCubeMapArray = TRUE; //ExtensionExists("GL_ARB_texture_cube_map_array", gGLHExts.mSysExts); - mHasPointParameters = TRUE; //ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); - - mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations - mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts); - // NOTE: Using extensions breaks reflections when Shadows are set to projector. See: SL-16727 - //mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); - mHasDepthClamp = FALSE; - // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad - -#ifdef GL_EXT_texture_sRGB - mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts); -#endif - - -#ifdef GL_EXT_texture_sRGB_decode - mHasTexturesRGBDecode = ExtensionExists("GL_EXT_texture_sRGB_decode", gGLHExts.mSysExts); -#else - mHasTexturesRGBDecode = ExtensionExists("GL_ARB_texture_sRGB_decode", gGLHExts.mSysExts); -#endif - - mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f; + // OpenGL 4.x capabilities + mHasCubeMapArray = mGLVersion >= 3.99f; + mHasTransformFeedback = mGLVersion >= 3.99f; + mHasDebugOutput = mGLVersion >= 4.29f; - mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); - mHasDebugOutput = mGLVersion >= 4.3f ? TRUE : FALSE; - mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE; -#endif - -#if LL_LINUX - LL_INFOS() << "initExtensions() checking shell variables to adjust features..." << LL_ENDL; - // Our extension support for the Linux Client is very young with some - // potential driver gotchas, so offer a semi-secret way to turn it off. - if (getenv("LL_GL_NOEXT")) - { - //mHasMultitexture = FALSE; // NEEDED! - mHasDepthClamp = FALSE; - mHasARBEnvCombine = FALSE; - mHasCompressedTextures = FALSE; - mHasVertexBufferObject = FALSE; - mHasFramebufferObject = FALSE; - mHasDrawBuffers = FALSE; - mHasBlendFuncSeparate = FALSE; - mHasMipMapGeneration = FALSE; - mHasSeparateSpecularColor = FALSE; - mHasAnisotropic = FALSE; - mHasCubeMap = FALSE; - mHasOcclusionQuery = FALSE; - mHasPointParameters = FALSE; - LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL; - } - else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */ - { - // This switch attempts to turn off all support for exotic - // extensions which I believe correspond to fatal driver - // bug reports. This should be the default until we get a - // proper blacklist/whitelist on Linux. - mHasMipMapGeneration = FALSE; - mHasAnisotropic = FALSE; - //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar - //mHasOcclusionQuery = FALSE; // source of many ATI system hangs - mHasBlendFuncSeparate = FALSE; - LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL; - } - if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */ - { - // This lets advanced troubleshooters disable specific - // GL extensions to isolate problems with their hardware. - // SL-28126 - const char *const blacklist = getenv("LL_GL_BLACKLIST"); /* Flawfinder: ignore */ - LL_WARNS("RenderInit") << "GL extension support partially disabled via LL_GL_BLACKLIST: " << blacklist << LL_ENDL; - if (strchr(blacklist,'a')) mHasARBEnvCombine = FALSE; - if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE; - if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE; - if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S -// if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S -// if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S - if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE; - if (strchr(blacklist,'i')) mHasAnisotropic = FALSE;//S - if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S -// if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S - if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE; - if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S - if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S - if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S - if (strchr(blacklist,'s')) mHasTextureRectangle = FALSE; - if (strchr(blacklist,'t')) mHasBlendFuncSeparate = FALSE;//S - if (strchr(blacklist,'u')) mHasDepthClamp = FALSE; - - } -#endif // LL_LINUX - - if (!mHasMultitexture) - { - LL_INFOS("RenderInit") << "Couldn't initialize multitexturing" << LL_ENDL; - } - if (!mHasMipMapGeneration) - { - LL_INFOS("RenderInit") << "Couldn't initialize mipmap generation" << LL_ENDL; - } - if (!mHasARBEnvCombine) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL; - } - if (!mHasSeparateSpecularColor) - { - LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL; - } - if (!mHasAnisotropic) - { - LL_INFOS("RenderInit") << "Couldn't initialize anisotropic filtering" << LL_ENDL; - } - if (!mHasCompressedTextures) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_compression" << LL_ENDL; - } - if (!mHasOcclusionQuery) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL; - } - if (!mHasOcclusionQuery2) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL; - } - if (!mHasPointParameters) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL; - } - if (!mHasBlendFuncSeparate && !LLRender::sGLCoreProfile) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL; - } - if (!mHasDrawBuffers) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL; - } - if (!mHasCubeMapArray) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_cube_map_array" << LL_ENDL; - } - - // Disable certain things due to known bugs - if (mIsIntel && mHasMipMapGeneration) - { - LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL; - mHasMipMapGeneration = FALSE; - } - - // Misc + // Misc glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange); glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange); glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize); @@ -2795,7 +2451,7 @@ void LLGLState::checkTextureChannels(const std::string& msg) glh::matrix4f identity; identity.identity(); - for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++) + for (GLint i = 1; i < gGLManager.mNumTextureImageUnits; i++) { gGL.getTexUnit(i)->activate(); @@ -2833,12 +2489,6 @@ void LLGLState::checkTextureChannels(const std::string& msg) for (S32 j = (i == 0 ? 1 : 0); j < 9; j++) { - if (j == 8 && !gGLManager.mHasTextureRectangle || - j == 9 && !gGLManager.mHasTextureMultisample) - { - continue; - } - if (glIsEnabled(value[j])) { error = TRUE; @@ -3329,36 +2979,29 @@ LLGLSquashToFarClip::~LLGLSquashToFarClip() LLGLSyncFence::LLGLSyncFence() { -#ifdef GL_ARB_sync mSync = 0; -#endif } LLGLSyncFence::~LLGLSyncFence() { -#ifdef GL_ARB_sync if (mSync) { glDeleteSync(mSync); } -#endif } void LLGLSyncFence::placeFence() { -#ifdef GL_ARB_sync if (mSync) { glDeleteSync(mSync); } mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -#endif } bool LLGLSyncFence::isCompleted() { bool ret = true; -#ifdef GL_ARB_sync if (mSync) { GLenum status = glClientWaitSync(mSync, 0, 1); @@ -3367,13 +3010,11 @@ bool LLGLSyncFence::isCompleted() ret = false; } } -#endif return ret; } void LLGLSyncFence::wait() { -#ifdef GL_ARB_sync if (mSync) { while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED) @@ -3382,7 +3023,6 @@ void LLGLSyncFence::wait() waits++; } } -#endif } LLGLSPipelineSkyBox::LLGLSPipelineSkyBox() diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 3c40f85654..e3c07604aa 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -76,52 +76,27 @@ public: BOOL mInited; BOOL mIsDisabled; - // Extensions used by everyone - BOOL mHasMultitexture; - BOOL mHasATIMemInfo; - BOOL mHasAMDAssociations; - BOOL mHasNVXMemInfo; - S32 mNumTextureUnits; - BOOL mHasMipMapGeneration; - BOOL mHasCompressedTextures; - BOOL mHasFramebufferObject; + // OpenGL limits S32 mMaxSamples; - BOOL mHasBlendFuncSeparate; - - // ARB Extensions - BOOL mHasVertexBufferObject; - BOOL mHasVertexArrayObject; - BOOL mHasSync; - BOOL mHasMapBufferRange; - BOOL mHasFlushBufferRange; - BOOL mHasPBuffer; - S32 mNumTextureImageUnits; - BOOL mHasOcclusionQuery; - BOOL mHasTimerQuery; - BOOL mHasOcclusionQuery2; - BOOL mHasPointParameters; - BOOL mHasDrawBuffers; - BOOL mHasDepthClamp; - BOOL mHasTextureRectangle; - BOOL mHasTextureMultisample; - BOOL mHasTransformFeedback; - BOOL mHasUniformBufferObject; + S32 mNumTextureImageUnits; S32 mMaxSampleMaskWords; S32 mMaxColorTextureSamples; S32 mMaxDepthTextureSamples; S32 mMaxIntegerSamples; - - // Other extensions. - BOOL mHasAnisotropic; - BOOL mHasARBEnvCombine; - BOOL mHasCubeMap; - BOOL mHasCubeMapArray; - BOOL mHasDebugOutput; - BOOL mHassRGBTexture; - BOOL mHassRGBFramebuffer; - BOOL mHasTexturesRGBDecode; - + S32 mGLMaxVertexRange; + S32 mGLMaxIndexRange; + S32 mGLMaxTextureSize; + F32 mMaxAnisotropy = 0.f; + + // GL 4.x capabilities + bool mHasCubeMapArray = false; + bool mHasDebugOutput = false; + bool mHasTransformFeedback = false; + bool mHasAnisotropic = false; + // Vendor-specific extensions + bool mHasAMDAssociations = false; + BOOL mIsAMD; BOOL mIsNVIDIA; BOOL mIsIntel; @@ -134,9 +109,6 @@ public: // Whether this version of GL is good enough for SL to use BOOL mHasRequirements; - // Misc extensions - BOOL mHasSeparateSpecularColor; - S32 mDriverVersionMajor; S32 mDriverVersionMinor; S32 mDriverVersionRelease; @@ -147,9 +119,6 @@ public: std::string mGLVersionString; S32 mVRAM; // VRAM in MB - S32 mGLMaxVertexRange; - S32 mGLMaxIndexRange; - S32 mGLMaxTextureSize; void getPixelFormat(); // Get the best pixel format @@ -415,9 +384,7 @@ public: class LLGLSyncFence : public LLGLFence { public: -#ifdef GL_ARB_sync GLsync mSync; -#endif LLGLSyncFence(); virtual ~LLGLSyncFence(); diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index f2b51fbafb..b80680a3d2 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -41,277 +41,6 @@ # include "GL/glh_extensions.h" # undef __APPLE__ -#elif LL_LINUX -//---------------------------------------------------------------------------- -// LL_LINUX - -//---------------------------------------------------------------------------- -// Linux, MESA headers, but not necessarily assuming MESA runtime. -// quotes so we get libraries/.../GL/ version -#include "GL/gl.h" -#include "GL/glext.h" -#include "GL/glu.h" - - -#if LL_LINUX && !LL_MESA_HEADLESS -// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly -# define __APPLE__ -# include "GL/glh_extensions.h" -# undef __APPLE__ - -/* Although SDL very likely ends up calling glXGetProcAddress() itself, - if we use SDL_GL_GetProcAddress() then we get bogus addresses back on - some systems. Weird. */ -/*# include "SDL/SDL.h" - # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */ -#define GLX_GLXEXT_PROTOTYPES 1 -# include "GL/glx.h" -# include "GL/glxext.h" -// Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol -// is considered 'legacy' but works on more machines. -# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddress((const GLubyte*)(p)) -#endif // LL_LINUX && !LL_MESA_HEADLESS - -#if LL_LINUX && defined(WINGDIAPI) -// WINGDIAPI gets set if we are using the linux nvidia gl.h header which needs -// the functions below setting up. -# define LL_LINUX_NV_GL_HEADERS 1 -#else -# define LL_LINUX_NV_GL_HEADERS 0 -#endif // LL_LINUX && defined(WINGDIAPI) - - -#if LL_LINUX_NV_GL_HEADERS -// Missing functions when using nvidia headers: -extern PFNGLACTIVETEXTUREPROC glActiveTexture; -extern PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture; -extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; -#endif // LL_LINUX_NV_GL_HEADERS - -// GL_ARB_vertex_array_object -extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; -extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; -extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; -extern PFNGLISVERTEXARRAYPROC glIsVertexArray; - -// GL_ARB_vertex_buffer_object -extern PFNGLBINDBUFFERPROC glBindBuffer; -extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; -extern PFNGLGENBUFFERSPROC glGenBuffers; -extern PFNGLISBUFFERPROC glIsBuffer; -extern PFNGLBUFFERDATAPROC glBufferData; -extern PFNGLBUFFERSUBDATAPROC glBufferSubData; -extern PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData; -extern PFNGLMAPBUFFERPROC glMapBuffer; -extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; -extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv; -extern PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv; - -// GL_ARB_sync -extern PFNGLFENCESYNCPROC glFenceSync; -extern PFNGLISSYNCPROC glIsSync; -extern PFNGLDELETESYNCPROC glDeleteSync; -extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync; -extern PFNGLWAITSYNCPROC glWaitSync; -extern PFNGLGETINTEGER64VPROC glGetInteger64v; -extern PFNGLGETSYNCIVPROC glGetSynciv; - -// GL_APPLE_flush_buffer_range -extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE; -extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; - -// GL_ARB_map_buffer_range -extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; -extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; - -// GL_ATI_vertex_array_object -extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI; -extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI; -extern PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI; -extern PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI; -extern PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI; -extern PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI; -extern PFNGLARRAYOBJECTATIPROC glArrayObjectATI; -extern PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI; -extern PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI; -extern PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI; -extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI; -extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI; -extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI; - -// GL_ARB_occlusion_query -extern PFNGLGENQUERIESPROC glGenQueries; -extern PFNGLDELETEQUERIESPROC glDeleteQueries; -extern PFNGLISQUERYPROC glIsQuery; -extern PFNGLBEGINQUERYPROC glBeginQuery; -extern PFNGLENDQUERYPROC glEndQuery; -extern PFNGLGETQUERYIVPROC glGetQueryiv; -extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv; -extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv; - -// GL_ARB_timer_query -extern PFNGLQUERYCOUNTERPROC glQueryCounter; -extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; -extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; - -// GL_ARB_point_parameters -extern PFNGLPOINTPARAMETERFPROC glPointParameterf; -extern PFNGLPOINTPARAMETERFVPROC glPointParameterfv; - -// GL_ARB_shader_objects -extern PFNGLDELETEOBJECTPROC glDeleteObject; -extern PFNGLGETHANDLEPROC glGetHandle; -extern PFNGLDETACHOBJECTPROC glDetachObject; -extern PFNGLCREATESHADEROBJECTPROC glCreateShaderObject; -extern PFNGLSHADERSOURCEPROC glShaderSource; -extern PFNGLCOMPILESHADERPROC glCompileShader; -extern PFNGLCREATEPROGRAMOBJECTPROC glCreateProgramObject; -extern PFNGLATTACHOBJECTPROC glAttachObject; -extern PFNGLLINKPROGRAMPROC glLinkProgram; -extern PFNGLUSEPROGRAMOBJECTPROC glUseProgramObject; -extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; -extern PFNGLUNIFORM1FPROC glUniform1f; -extern PFNGLUNIFORM2FPROC glUniform2f; -extern PFNGLUNIFORM3FPROC glUniform3f; -extern PFNGLUNIFORM4FPROC glUniform4f; -extern PFNGLUNIFORM1IPROC glUniform1i; -extern PFNGLUNIFORM2IPROC glUniform2i; -extern PFNGLUNIFORM3IPROC glUniform3i; -extern PFNGLUNIFORM4IPROC glUniform4i; -extern PFNGLUNIFORM1FVPROC glUniform1fv; -extern PFNGLUNIFORM2FVPROC glUniform2fv; -extern PFNGLUNIFORM3FVPROC glUniform3fv; -extern PFNGLUNIFORM4FVPROC glUniform4fv; -extern PFNGLUNIFORM1IVPROC glUniform1iv; -extern PFNGLUNIFORM2IVPROC glUniform2iv; -extern PFNGLUNIFORM3IVPROC glUniform3iv; -extern PFNGLUNIFORM4IVPROC glUniform4iv; -extern PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv; -extern PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; -extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; -extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -extern PFNGLGETOBJECTPARAMETERFVPROC glGetObjectParameterfv; -extern PFNGLGETOBJECTPARAMETERIVPROC glGetObjectParameteriv; -extern PFNGLGETINFOLOGPROC glGetInfoLog; -extern PFNGLGETATTACHEDOBJECTSPROC glGetAttachedObjects; -extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; -extern PFNGLGETUNIFORMFVPROC glGetUniformfv; -extern PFNGLGETUNIFORMIVPROC glGetUniformiv; -extern PFNGLGETSHADERSOURCEPROC glGetShaderSource; - -// GL_ARB_vertex_shader -extern PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d; -extern PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv; -extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; -extern PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv; -extern PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s; -extern PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv; -extern PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d; -extern PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv; -extern PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; -extern PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; -extern PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s; -extern PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv; -extern PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d; -extern PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv; -extern PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; -extern PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; -extern PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s; -extern PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv; -extern PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4nbv; -extern PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4niv; -extern PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4nsv; -extern PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4nub; -extern PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4nubv; -extern PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4nuiv; -extern PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4nusv; -extern PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv; -extern PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d; -extern PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv; -extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; -extern PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; -extern PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv; -extern PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s; -extern PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv; -extern PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv; -extern PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv; -extern PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv; -extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; -extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -extern PFNGLPROGRAMSTRINGPROC glProgramString; -extern PFNGLBINDPROGRAMPROC glBindProgram; -extern PFNGLDELETEPROGRAMSPROC glDeletePrograms; -extern PFNGLGENPROGRAMSPROC glGenPrograms; -extern PFNGLPROGRAMENVPARAMETER4DPROC glProgramEnvParameter4d; -extern PFNGLPROGRAMENVPARAMETER4DVPROC glProgramEnvParameter4dv; -extern PFNGLPROGRAMENVPARAMETER4FPROC glProgramEnvParameter4f; -extern PFNGLPROGRAMENVPARAMETER4FVPROC glProgramEnvParameter4fv; -extern PFNGLPROGRAMLOCALPARAMETER4DPROC glProgramLocalParameter4d; -extern PFNGLPROGRAMLOCALPARAMETER4DVPROC glProgramLocalParameter4dv; -extern PFNGLPROGRAMLOCALPARAMETER4FPROC glProgramLocalParameter4f; -extern PFNGLPROGRAMLOCALPARAMETER4FVPROC glProgramLocalParameter4fv; -extern PFNGLGETPROGRAMENVPARAMETERDVPROC glGetProgramEnvParameterdv; -extern PFNGLGETPROGRAMENVPARAMETERFVPROC glGetProgramEnvParameterfv; -extern PFNGLGETPROGRAMLOCALPARAMETERDVPROC glGetProgramLocalParameterdv; -extern PFNGLGETPROGRAMLOCALPARAMETERFVPROC glGetProgramLocalParameterfv; -extern PFNGLGETPROGRAMIVPROC glGetProgramiv; -extern PFNGLGETPROGRAMSTRINGPROC glGetProgramString; -extern PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv; -extern PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv; -extern PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv; -extern PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv; -extern PFNGLISPROGRAMPROC glIsProgram; -extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; -extern PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; -extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; - -extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; -extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage; - -//GL_EXT_blend_func_separate -extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; - -//GL_ARB_framebuffer_object -extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer; -extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; -extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; -extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; -extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; -extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; -extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer; -extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; -extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; -extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; -extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; -extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; -extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; -extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; -extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; -extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; -extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; -extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; - -//GL_ARB_draw_buffers -extern PFNGLDRAWBUFFERSPROC glDrawBuffers; - -//GL_ARB_texture_multisample -extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; -extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; -extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; -extern PFNGLSAMPLEMASKIPROC glSampleMaski; - -//transform feedback (4.0 core) -extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; -extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; -extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; -extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; -extern PFNGLBINDBUFFERBASEPROC glBindBufferBase; - #elif LL_WINDOWS //---------------------------------------------------------------------------- // LL_WINDOWS @@ -345,12 +74,6 @@ extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; // WGL_ARB_create_context extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; -// GL_VERSION_1_2 -//extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; -//extern PFNGLTEXIMAGE3DPROC glTexImage3D; -//extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D; -//extern PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D; - // GL_VERSION_1_3 extern PFNGLACTIVETEXTUREPROC glActiveTexture; extern PFNGLSAMPLECOVERAGEPROC glSampleCoverage; @@ -1338,13 +1061,6 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #endif #if defined(TRACY_ENABLE) && LL_PROFILER_ENABLE_TRACY_OPENGL - // Tracy uses the following: - // glGenQueries - // glGetQueryiv - // glGetQueryObjectiv - #define glGenQueries glGenQueriesARB - #define glGetQueryiv glGetQueryivARB - #define glGetQueryObjectiv glGetQueryObjectivARB #include <tracy/TracyOpenGL.hpp> #endif diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index bc349c2015..55713eea80 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -227,7 +227,6 @@ void LLGLSLShader::stopProfile(U32 count, U32 mode) void LLGLSLShader::placeProfileQuery() { -#if 1 || !LL_DARWIN if (mTimerQuery == 0) { glGenQueries(1, &mSamplesQuery); @@ -269,12 +268,10 @@ void LLGLSLShader::placeProfileQuery() glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery); glBeginQuery(GL_TIME_ELAPSED, mTimerQuery); -#endif } void LLGLSLShader::readProfileQuery(U32 count, U32 mode) { -#if !LL_DARWIN glEndQuery(GL_TIME_ELAPSED); glEndQuery(GL_SAMPLES_PASSED); @@ -304,7 +301,6 @@ void LLGLSLShader::readProfileQuery(U32 count, U32 mode) sTotalDrawCalls++; mDrawCalls++; -#endif } @@ -676,7 +672,6 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * glGetActiveUniform(mProgramObject, index, 1024, &length, &size, &type, (GLchar *)name); -#if !LL_DARWIN if (size > 0) { switch(type) @@ -718,7 +713,6 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> * } mTotalUniformSize += size; } -#endif S32 location = glGetUniformLocation(mProgramObject, name); if (location != -1) @@ -977,8 +971,11 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) static const GLuint BLOCKBINDING = 1; //picked by us //Get the index, similar to a uniform location GLuint UBOBlockIndex = glGetUniformBlockIndex(mProgramObject, "ReflectionProbes"); - //Set this index to a binding index - glUniformBlockBinding(mProgramObject, UBOBlockIndex, BLOCKBINDING); + if (UBOBlockIndex != GL_INVALID_INDEX) + { + //Set this index to a binding index + glUniformBlockBinding(mProgramObject, UBOBlockIndex, BLOCKBINDING); + } } unbind(); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index d8e312106c..01bd4aba26 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -352,7 +352,7 @@ void LLImageGL::updateStats(F32 current_time) //static void LLImageGL::destroyGL(BOOL save_state) { - for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++) + for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++) { gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } @@ -520,7 +520,6 @@ void LLImageGL::init(BOOL usemipmaps) mPickMaskHeight = 0; mUseMipMaps = usemipmaps; mHasExplicitFormat = FALSE; - mAutoGenMips = FALSE; mIsMask = FALSE; mNeedsAlphaAndPickMask = TRUE ; @@ -1069,30 +1068,12 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image) mFormatType = GL_UNSIGNED_BYTE; break; case 3: -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8; - } - else -#endif - { - mFormatInternal = GL_RGB8; - } + mFormatInternal = GL_RGB8; mFormatPrimary = GL_RGB; mFormatType = GL_UNSIGNED_BYTE; break; case 4: -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8_ALPHA8; - } - else -#endif - { - mFormatInternal = GL_RGBA8; - } + mFormatInternal = GL_RGBA8; mFormatPrimary = GL_RGBA; mFormatType = GL_UNSIGNED_BYTE; break; @@ -1303,7 +1284,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt if (pixels != nullptr) { use_scratch = true; - scratch = new U32[width * height]; + scratch = new(std::nothrow) U32[width * height]; + if (!scratch) + { + LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) + << " bytes for a manual image W" << width << " H" << height << LL_ENDL; + } U32 pixel_count = (U32)(width * height); for (U32 i = 0; i < pixel_count; i++) @@ -1323,7 +1309,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt if (pixels != nullptr) { use_scratch = true; - scratch = new U32[width * height]; + scratch = new(std::nothrow) U32[width * height]; + if (!scratch) + { + LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) + << " bytes for a manual image W" << width << " H" << height << LL_ENDL; + } U32 pixel_count = (U32)(width * height); for (U32 i = 0; i < pixel_count; i++) @@ -1346,7 +1337,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt if (pixels != nullptr) { use_scratch = true; - scratch = new U32[width * height]; + scratch = new(std::nothrow) U32[width * height]; + if (!scratch) + { + LL_ERRS() << "Failed to allocate " << (U32)(width * height * sizeof(U32)) + << " bytes for a manual image W" << width << " H" << height << LL_ENDL; + } U32 pixel_count = (U32)(width * height); for (U32 i = 0; i < pixel_count; i++) @@ -1525,30 +1521,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S mFormatType = GL_UNSIGNED_BYTE; break; case 3: - #if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8; - } - else - #endif - { - mFormatInternal = GL_RGB8; - } + mFormatInternal = GL_RGB8; mFormatPrimary = GL_RGB; mFormatType = GL_UNSIGNED_BYTE; break; case 4: - #if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8_ALPHA8; - } - else - #endif - { - mFormatInternal = GL_RGBA8; - } + mFormatInternal = GL_RGBA8; mFormatPrimary = GL_RGBA; mFormatType = GL_UNSIGNED_BYTE; break; @@ -1637,7 +1615,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ if (mUseMipMaps) { - mAutoGenMips = gGLManager.mHasMipMapGeneration; + mAutoGenMips = true; } mCurrentDiscardLevel = discard_level; @@ -1694,44 +1672,37 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name) { LL_PROFILE_ZONE_NAMED("cglt - sync"); - if (gGLManager.mHasSync) + if (gGLManager.mIsNVIDIA) { - if (gGLManager.mIsNVIDIA) - { - // wait for texture upload to finish before notifying main thread - // upload is complete - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glFlush(); - glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED); - glDeleteSync(sync); - } - else - { - // post a sync to the main thread (will execute before tex name swap lambda below) - // glFlush calls here are partly superstitious and partly backed by observation - // on AMD hardware - glFlush(); - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glFlush(); - LL::WorkQueue::postMaybe( - mMainQueue, - [=]() - { - LL_PROFILE_ZONE_NAMED("cglt - wait sync"); - { - LL_PROFILE_ZONE_NAMED("glWaitSync"); - glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); - } - { - LL_PROFILE_ZONE_NAMED("glDeleteSync"); - glDeleteSync(sync); - } - }); - } + // wait for texture upload to finish before notifying main thread + // upload is complete + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + glDeleteSync(sync); } else { - glFinish(); + // post a sync to the main thread (will execute before tex name swap lambda below) + // glFlush calls here are partly superstitious and partly backed by observation + // on AMD hardware + glFlush(); + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + LL::WorkQueue::postMaybe( + mMainQueue, + [=]() + { + LL_PROFILE_ZONE_NAMED("cglt - wait sync"); + { + LL_PROFILE_ZONE_NAMED("glWaitSync"); + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + } + { + LL_PROFILE_ZONE_NAMED("glDeleteSync"); + glDeleteSync(sync); + } + }); } } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index b4618fd35c..bbd024abd9 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -219,7 +219,7 @@ private: U16 mPickMaskHeight; S8 mUseMipMaps; BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents) - S8 mAutoGenMips; + bool mAutoGenMips = false; BOOL mIsMask; BOOL mNeedsAlphaAndPickMask; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 471dbce1dd..6e659641fe 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -335,7 +335,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap) if (mCurrTexture != cubeMap->mImages[0]->getTexName()) { - if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (LLCubeMap::sUseCubeMaps) { activate(); enable(LLTexUnit::TT_CUBE_MAP); @@ -516,22 +516,15 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio } } - if (gGLManager.mHasAnisotropic) + if (gGLManager.mGLVersion >= 4.59f) { if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) { - if (gGL.mMaxAnisotropy < 1.f) - { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy); - - LL_INFOS() << "gGL.mMaxAnisotropy: " << gGL.mMaxAnisotropy << LL_ENDL ; - gGL.mMaxAnisotropy = llmax(1.f, gGL.mMaxAnisotropy) ; - } - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); } else { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); } } } @@ -650,29 +643,6 @@ void LLTexUnit::debugTextureUnit(void) void LLTexUnit::setTextureColorSpace(eTextureColorSpace space) { mTexColorSpace = space; - -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - if (space == TCS_SRGB) - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); - } - - if (gDebugGL) - { - assert_glerror(); - } - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); - } -#endif } LLLightState::LLLightState(S32 index) @@ -735,6 +705,24 @@ void LLLightState::setSunPrimary(bool v) } } +void LLLightState::setSize(F32 v) +{ + if (mSize != v) + { + ++gGL.mLightHash; + mSize = v; + } +} + +void LLLightState::setFalloff(F32 v) +{ + if (mFalloff != v) + { + ++gGL.mLightHash; + mFalloff = v; + } +} + void LLLightState::setAmbient(const LLColor4& ambient) { if (mAmbient != ambient) @@ -828,8 +816,7 @@ LLRender::LLRender() mCount(0), mQuadCycle(0), mMode(LLRender::TRIANGLES), - mCurrTextureUnitIndex(0), - mMaxAnisotropy(0.f) + mCurrTextureUnitIndex(0) { mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS); for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) @@ -894,11 +881,9 @@ void LLRender::init() if (sGLCoreProfile && !LLVertexBuffer::sUseVAO) { //bind a dummy vertex array object so we're core profile compliant -#ifdef GL_ARB_vertex_array_object U32 ret; glGenVertexArrays(1, &ret); glBindVertexArray(ret); -#endif } @@ -969,6 +954,7 @@ void LLRender::syncLightState() LLVector3 diffuse[LL_NUM_LIGHT_UNITS]; LLVector3 diffuse_b[LL_NUM_LIGHT_UNITS]; bool sun_primary[LL_NUM_LIGHT_UNITS]; + LLVector2 size[LL_NUM_LIGHT_UNITS]; for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; i++) { @@ -980,11 +966,13 @@ void LLRender::syncLightState() diffuse[i].set(light->mDiffuse.mV); diffuse_b[i].set(light->mDiffuseB.mV); sun_primary[i] = light->mSunIsPrimary; + size[i].set(light->mSize, light->mFalloff); } shader->uniform4fv(LLShaderMgr::LIGHT_POSITION, LL_NUM_LIGHT_UNITS, position[0].mV); shader->uniform3fv(LLShaderMgr::LIGHT_DIRECTION, LL_NUM_LIGHT_UNITS, direction[0].mV); shader->uniform4fv(LLShaderMgr::LIGHT_ATTENUATION, LL_NUM_LIGHT_UNITS, attenuation[0].mV); + shader->uniform2fv(LLShaderMgr::LIGHT_DEFERRED_ATTENUATION, LL_NUM_LIGHT_UNITS, size[0].mV); shader->uniform3fv(LLShaderMgr::LIGHT_DIFFUSE, LL_NUM_LIGHT_UNITS, diffuse[0].mV); shader->uniform4fv(LLShaderMgr::LIGHT_AMBIENT, 1, mAmbientLightColor.mV); shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_primary[0] ? 1 : 0); @@ -1471,12 +1459,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, llassert(color_dfactor < BF_UNDEF); llassert(alpha_sfactor < BF_UNDEF); llassert(alpha_dfactor < BF_UNDEF); - if (!LLRender::sGLCoreProfile && !gGLManager.mHasBlendFuncSeparate) - { - LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << LL_ENDL; - blendFunc(color_sfactor, color_dfactor); - return; - } + if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 095ed400f4..3e4a1fe933 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -246,6 +246,8 @@ public: void setSpotCutoff(const F32& cutoff); void setSpotDirection(const LLVector3& direction); void setSunPrimary(bool v); + void setSize(F32 size); + void setFalloff(F32 falloff); protected: friend class LLRender; @@ -266,6 +268,8 @@ protected: F32 mSpotExponent; F32 mSpotCutoff; + F32 mSize = 0.f; + F32 mFalloff = 0.f; }; class LLRender @@ -489,8 +493,6 @@ private: eBlendFactor mCurrBlendAlphaSFactor; eBlendFactor mCurrBlendAlphaDFactor; - F32 mMaxAnisotropy; - std::vector<LLVector3> mUIOffset; std::vector<LLVector3> mUIScale; diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 5cb1dc6b25..3d32d3ca31 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -1516,7 +1516,15 @@ void LLRender2D::loadIdentity() void LLRender2D::setLineWidth(F32 width) { gGL.flush(); - glLineWidth(width * lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f)); + // If outside the allowed range, glLineWidth fails with "invalid value". + // On Darwin, the range is [1, 1]. + static GLfloat range[2]{0.0}; + if (range[1] == 0) + { + glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, range); + } + width *= lerp(LLRender::sUIGLScaleFactor.mV[VX], LLRender::sUIGLScaleFactor.mV[VY], 0.5f); + glLineWidth(llclamp(width, range[0], range[1])); } LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority) diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index fa23654978..b0da054d76 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -134,7 +134,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo mUsage = usage; mUseDepth = depth; - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) + if ((sUseFBO || use_fbo)) { if (depth) { @@ -234,11 +234,9 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) llassert( offset < 4 ); return false; } - if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) ) + if( offset > 0 && (mFBO == 0) ) { - LL_WARNS() << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << LL_ENDL; llassert( mFBO != 0 ); - llassert( gGLManager.mHasDrawBuffers ); return false; } @@ -303,13 +301,11 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) mTex.push_back(tex); mInternalFormat.push_back(color_fmt); -#if !LL_DARWIN if (gDebugGL) { //bind and unbind to validate target bindTarget(); flush(); } -#endif return true; @@ -473,6 +469,7 @@ void LLRenderTarget::release() void LLRenderTarget::bindTarget() { + LL_PROFILE_GPU_ZONE("bindTarget"); llassert(mFBO); if (mFBO) @@ -484,14 +481,12 @@ void LLRenderTarget::bindTarget() sCurFBO = mFBO; stop_glerror(); - if (gGLManager.mHasDrawBuffers) - { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3}; - glDrawBuffers(mTex.size(), drawbuffers); - } + //setup multiple render targets + GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3}; + glDrawBuffers(mTex.size(), drawbuffers); if (mTex.empty()) { //no color buffer to draw to @@ -581,6 +576,7 @@ void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilt void LLRenderTarget::flush(bool fetch_depth) { + LL_PROFILE_GPU_ZONE("rt flush"); gGL.flush(); llassert(mFBO); if (!mFBO) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 5293166ec3..b609a74e32 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1180,6 +1180,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("light_position"); mReservedUniforms.push_back("light_direction"); mReservedUniforms.push_back("light_attenuation"); + mReservedUniforms.push_back("light_deferred_attenuation"); mReservedUniforms.push_back("light_diffuse"); mReservedUniforms.push_back("light_ambient"); mReservedUniforms.push_back("light_count"); @@ -1323,6 +1324,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("diffuseRect"); mReservedUniforms.push_back("specularRect"); mReservedUniforms.push_back("emissiveRect"); + mReservedUniforms.push_back("brdfLut"); mReservedUniforms.push_back("noiseMap"); mReservedUniforms.push_back("lightFunc"); mReservedUniforms.push_back("lightMap"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 008e3dafa6..aa002014a7 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -55,6 +55,7 @@ public: LIGHT_POSITION, // "light_position" LIGHT_DIRECTION, // "light_direction" LIGHT_ATTENUATION, // "light_attenuation" + LIGHT_DEFERRED_ATTENUATION, // "light_deferred_attenuation" LIGHT_DIFFUSE, // "light_diffuse" LIGHT_AMBIENT, // "light_ambient" MULTI_LIGHT_COUNT, // "light_count" @@ -176,6 +177,7 @@ public: DEFERRED_DIFFUSE, // "diffuseRect" DEFERRED_SPECULAR, // "specularRect" DEFERRED_EMISSIVE, // "emissiveRect" + DEFERRED_BRDF_LUT, // "brdfLut" DEFERRED_NOISE, // "noiseMap" DEFERRED_LIGHTFUNC, // "lightFunc" DEFERRED_LIGHT, // "lightMap" diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index a40ea2eb1e..981175d845 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -744,7 +744,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const //static void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { - sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject; + sEnableVBOs = use_vbo; sDisableVBOMapping = sEnableVBOs && no_vbo_mapping; } @@ -753,9 +753,7 @@ void LLVertexBuffer::unbind() { if (sGLRenderArray) { -#if GL_ARB_vertex_array_object glBindVertexArray(0); -#endif sGLRenderArray = 0; sGLRenderIndices = 0; sIBOActive = false; @@ -923,9 +921,7 @@ LLVertexBuffer::~LLVertexBuffer() if (mGLArray) { -#if GL_ARB_vertex_array_object releaseVAOName(mGLArray); -#endif } sCount--; @@ -956,10 +952,7 @@ void LLVertexBuffer::placeFence() const { /*if (!mFence && useVBOs()) { - if (gGLManager.mHasSync) - { - mFence = new LLGLSyncFence(); - } + mFence = new LLGLSyncFence(); } if (mFence) @@ -1234,11 +1227,9 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) //actually allocate space for the vertex buffer if using VBO mapping flush(); //unmap - if (gGLManager.mHasVertexArrayObject && useVBOs() && sUseVAO) + if (useVBOs() && sUseVAO) { -#if GL_ARB_vertex_array_object mGLArray = getVAOName(); -#endif setupVertexArray(); } } @@ -1254,9 +1245,7 @@ void LLVertexBuffer::setupVertexArray() } LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; -#if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); -#endif sGLRenderArray = mGLArray; static const U32 attrib_size[] = @@ -1338,7 +1327,6 @@ void LLVertexBuffer::setupVertexArray() if (attrib_integer[i]) { -#if !LL_DARWIN //glVertexattribIPointer requires GLSL 1.30 or later if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30) { @@ -1347,9 +1335,8 @@ void LLVertexBuffer::setupVertexArray() // Cast via intptr_t to make it painfully obvious to the // compiler that we're doing this intentionally. glVertexAttribIPointer(i, attrib_size[i], attrib_type[i], sTypeSize[i], - reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i]))); + reinterpret_cast<const GLvoid*>(intptr_t(mOffsets[i]))); } -#endif } else { @@ -1443,7 +1430,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (useVBOs()) { - if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappable) { if (count == -1) { @@ -1492,58 +1479,34 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran { U8* src = NULL; waitFence(); - if (gGLManager.mHasMapBufferRange) + if (map_range) { - if (map_range) - { -#ifdef GL_ARB_map_buffer_range - S32 offset = mOffsets[type] + sTypeSize[type]*index; - S32 length = (sTypeSize[type]*count+0xF) & ~0xF; - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); -#endif - } - else + S32 offset = mOffsets[type] + sTypeSize[type]*index; + S32 length = (sTypeSize[type]*count+0xF) & ~0xF; + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_INVALIDATE_RANGE_BIT); + } + else + { + if (gDebugGL) { -#ifdef GL_ARB_map_buffer_range + GLint size = 0; + glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - if (gDebugGL) + if (size < mSize) { - GLint size = 0; - glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - - if (size < mSize) - { - LL_ERRS() << "Invalid buffer size." << LL_ENDL; - } + LL_ERRS() << "Invalid buffer size." << LL_ENDL; } - - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT); -#endif } - } - else if (gGLManager.mHasFlushBufferRange) - { - if (map_range) - { - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - } - else - { - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - } - } - else - { - map_range = false; - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT); } - llassert(src != NULL); + llassert(src != NULL); mMappedData = LL_NEXT_ALIGNED_ADDRESS<U8>(src); mAlignedOffset = mMappedData - src; @@ -1569,7 +1532,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran //-------------------- GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLBuffer) { LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL; @@ -1590,7 +1553,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran map_range = false; } - if (map_range && gGLManager.mHasMapBufferRange && mMappable) + if (map_range && mMappable) { return mMappedData; } @@ -1616,7 +1579,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (useVBOs()) { - if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappable) { if (count == -1) { @@ -1657,7 +1620,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (gDebugGL && useVBOs()) { GLint elem = 0; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elem); if (elem != mGLIndices) { @@ -1673,48 +1636,24 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { U8* src = NULL; waitFence(); - if (gGLManager.mHasMapBufferRange) - { - if (map_range) - { -#ifdef GL_ARB_map_buffer_range - S32 offset = sizeof(U16)*index; - S32 length = sizeof(U16)*count; - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); -#endif - } - else - { -#ifdef GL_ARB_map_buffer_range - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT); -#endif - } - } - else if (gGLManager.mHasFlushBufferRange) + if (map_range) { - if (map_range) - { - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - } - else - { - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - } + S32 offset = sizeof(U16)*index; + S32 length = sizeof(U16)*count; + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_INVALIDATE_RANGE_BIT); } else { - map_range = false; - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT); } - + llassert(src != NULL); - mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src); mAlignedIndexOffset = mMappedIndexData - src; stop_glerror(); @@ -1729,7 +1668,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if(mMappable) { GLint buff; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLIndices) { LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL; @@ -1748,7 +1687,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) map_range = false; } - if (map_range && gGLManager.mHasMapBufferRange && mMappable) + if (map_range && mMappable) { return mMappedIndexData; } @@ -1812,25 +1751,20 @@ void LLVertexBuffer::unmapBuffer() } else { - if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappedVertexRegions.empty()) { - if (!mMappedVertexRegions.empty()) + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex"); + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex"); - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) - { - const MappedRegion& region = mMappedVertexRegions[i]; - S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; - S32 length = sTypeSize[region.mType]*region.mCount; - if (gGLManager.mHasMapBufferRange) - { - glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length); - } - } - - mMappedVertexRegions.clear(); + const MappedRegion& region = mMappedVertexRegions[i]; + S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; + S32 length = sTypeSize[region.mType]*region.mCount; + glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length); } + + mMappedVertexRegions.clear(); } + stop_glerror(); glUnmapBuffer(GL_ARRAY_BUFFER); stop_glerror(); @@ -1884,25 +1818,19 @@ void LLVertexBuffer::unmapBuffer() } else { - if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappedIndexRegions.empty()) { - if (!mMappedIndexRegions.empty()) + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) { - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index"); - const MappedRegion& region = mMappedIndexRegions[i]; - S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; - S32 length = sizeof(U16)*region.mCount; - if (gGLManager.mHasMapBufferRange) - { - glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length); - } - stop_glerror(); - } - - mMappedIndexRegions.clear(); + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index"); + const MappedRegion& region = mMappedIndexRegions[i]; + S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; + S32 length = sizeof(U16)*region.mCount; + glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length); + stop_glerror(); } + + mMappedIndexRegions.clear(); } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); @@ -2034,9 +1962,7 @@ bool LLVertexBuffer::bindGLArray() { { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; -#if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); -#endif sGLRenderArray = mGLArray; } @@ -2228,7 +2154,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (gDebugGL && !mGLArray) { GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLBuffer) { if (gDebugSession) @@ -2243,7 +2169,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (mGLIndices) { - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLIndices) { if (gDebugSession) @@ -2264,9 +2190,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { if (sGLRenderArray) { -#if GL_ARB_vertex_array_object glBindVertexArray(0); -#endif sGLRenderArray = 0; sGLRenderIndices = 0; sIBOActive = false; @@ -2438,11 +2362,9 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) if (data_mask & MAP_TEXTURE_INDEX && (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later { -#if !LL_DARWIN S32 loc = TYPE_TEXTURE_INDEX; void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); -#endif } if (data_mask & MAP_VERTEX) { @@ -2533,11 +2455,9 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) } if (data_mask & MAP_TEXTURE_INDEX) { -#if !LL_DARWIN S32 loc = TYPE_TEXTURE_INDEX; void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); -#endif } if (data_mask & MAP_VERTEX) { diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index c6a3ada777..d413fab270 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -762,17 +762,13 @@ void LLFloater::closeFloater(bool app_quitting) for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ) { - LLFloater* floaterp = dependent_it->get(); - if (floaterp) - { - ++dependent_it; - floaterp->closeFloater(app_quitting); - } - else - { - mDependents.erase(dependent_it++); - } + dependent_it = mDependents.erase(dependent_it); + if (floaterp) + { + floaterp->mDependeeHandle = LLHandle<LLFloater>(); + floaterp->closeFloater(app_quitting); + } } cleanupHandles(); @@ -1443,7 +1439,7 @@ void LLFloater::cleanupHandles() LLFloater* floaterp = dependent_it->get(); if (!floaterp) { - mDependents.erase(dependent_it++); + dependent_it = mDependents.erase(dependent_it); } else { diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 8f00d1274e..4264028338 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -3960,8 +3960,8 @@ void LLTearOffMenu::draw() { // animate towards target height reshape(getRect().getWidth(), llceil(lerp((F32)getRect().getHeight(), (F32)mTargetHeight, LLSmoothInterpolation::getInterpolant(0.05f)))); - mMenu->needsArrange(); } + mMenu->needsArrange(); LLFloater::draw(); } diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 5cfa8ea973..3e5978eb59 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -100,7 +100,10 @@ void LLModalDialog::onOpen(const LLSD& key) if (!sModalStack.empty()) { LLModalDialog* front = sModalStack.front(); - front->setVisible(FALSE); + if (front != this) + { + front->setVisible(FALSE); + } } // This is a modal dialog. It sucks up all mouse and keyboard operations. @@ -108,7 +111,14 @@ void LLModalDialog::onOpen(const LLSD& key) LLUI::getInstance()->addPopup(this); setFocus(TRUE); - sModalStack.push_front( this ); + std::list<LLModalDialog*>::iterator iter = std::find(sModalStack.begin(), sModalStack.end(), this); + if (iter != sModalStack.end()) + { + // if already present, we want to move it to front. + sModalStack.erase(iter); + } + + sModalStack.push_front(this); } } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 11b0eb9f80..65c7b420ce 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1388,6 +1388,84 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen return found; } +U32 LLScrollListCtrl::searchItems(const std::string& substring, bool case_sensitive, bool focus) +{ + return searchItems(utf8str_to_wstring(substring), case_sensitive, focus); +} + +U32 LLScrollListCtrl::searchItems(const LLWString& substring, bool case_sensitive, bool focus) +{ + U32 found = 0; + + LLWString substring_trimmed(substring); + S32 len = substring_trimmed.size(); + + if (0 == len) + { + // at the moment search for empty element is not supported + return 0; + } + else + { + deselectAllItems(TRUE); + if (!case_sensitive) + { + // do comparisons in lower case + LLWStringUtil::toLower(substring_trimmed); + } + + for (item_list::iterator iter = mItemList.begin(); iter != mItemList.end(); iter++) + { + LLScrollListItem* item = *iter; + // Only select enabled items with matching names + if (!item->getEnabled()) + { + continue; + } + LLScrollListCell* cellp = item->getColumn(getSearchColumn()); + if (!cellp) + { + continue; + } + LLWString item_label = utf8str_to_wstring(cellp->getValue().asString()); + if (!case_sensitive) + { + LLWStringUtil::toLower(item_label); + } + // remove extraneous whitespace from searchable label + LLWStringUtil::trim(item_label); + + size_t found_iter = item_label.find(substring_trimmed); + + if (found_iter != std::string::npos) + { + // find offset of matching text + cellp->highlightText(found_iter, substring_trimmed.size()); + selectItem(item, -1, FALSE); + + found++; + + if (!mAllowMultipleSelection) + { + break; + } + } + } + } + + if (focus && found != 0) + { + mNeedsScroll = true; + } + + if (mCommitOnSelectionChange) + { + commitIfChanged(); + } + + return found; +} + const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const { LLScrollListItem* item; @@ -1912,6 +1990,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id)); registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id)); registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id)); + registrar.add("Url.ReportAbuse", boost::bind(&LLScrollListCtrl::reportAbuse, id, is_group)); registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group)); registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group)); registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group)); @@ -1975,6 +2054,15 @@ void LLScrollListCtrl::removeFriend(std::string id) LLUrlAction::removeFriend(slurl); } +void LLScrollListCtrl::reportAbuse(std::string id, bool is_group) +{ + if (!is_group) + { + std::string slurl = "secondlife:///app/agent/" + id + "/about"; + LLUrlAction::reportAbuse(slurl); + } +} + void LLScrollListCtrl::showNameDetails(std::string id, bool is_group) { // open the resident's details or the group details diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 08134bbfc8..77d10fdec7 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -267,6 +267,14 @@ public: const std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); + // If multi select is on, select all element that include substring, + // otherwise select first match only. + // If focus is true will scroll to selection. + // Returns number of results. + // Note: at the moment search happens in one go and is expensive + U32 searchItems(const std::string& substring, bool case_sensitive = false, bool focus = true); + U32 searchItems(const LLWString& substring, bool case_sensitive = false, bool focus = true); + // DEPRECATED: Use LLSD versions of setCommentText() and getSelectedValue(). // "StringUUID" interface: use this when you're creating a list that contains non-unique strings each of which // has an associated, unique UUID, and only one of which can be selected at a time. @@ -325,6 +333,7 @@ public: // support right-click context menus for avatar/group lists enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP }; void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; } + ContextMenuType getContextMenuType() { return mContextMenuType; } // Overridden from LLView /*virtual*/ void draw(); @@ -460,6 +469,7 @@ private: static void sendIM(std::string id); static void addFriend(std::string id); static void removeFriend(std::string id); + static void reportAbuse(std::string id, bool is_group); static void showNameDetails(std::string id, bool is_group); static void copyNameToClipboard(std::string id, bool is_group); static void copySLURLToClipboard(std::string id, bool is_group); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index c4a529e4ad..7e4aaa53bf 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2049,6 +2049,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url)); registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url)); registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url)); + registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url)); registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url)); registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url)); registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url)); diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 26702b2412..1a10d2fd1e 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -196,6 +196,7 @@ public: const LLUUID& getSourceID() const { return mSourceID; } const LLTextSegmentPtr getPreviousSegment() const; + const LLTextSegmentPtr getLastSegment() const; void getSelectedSegments(segment_vec_t& segments) const; void setShowContextMenu(bool show) { mShowContextMenu = show; } diff --git a/indra/llui/lltextutil.cpp b/indra/llui/lltextutil.cpp index 538508b856..78049319bc 100644 --- a/indra/llui/lltextutil.cpp +++ b/indra/llui/lltextutil.cpp @@ -76,22 +76,6 @@ void LLTextUtil::textboxSetGreyedVal(LLTextBox *txtbox, const LLStyle::Params& n txtbox->appendText(text.substr(greyed_begin + greyed_len), false, normal_style); } -const std::string& LLTextUtil::formatPhoneNumber(const std::string& phone_str) -{ - static const std::string PHONE_SEPARATOR = LLUI::getInstance()->mSettingGroups["config"]->getString("AvalinePhoneSeparator"); - static const S32 PHONE_PART_LEN = 2; - - static std::string formatted_phone_str; - formatted_phone_str = phone_str; - S32 separator_pos = (S32)(formatted_phone_str.size()) - PHONE_PART_LEN; - for (; separator_pos >= PHONE_PART_LEN; separator_pos -= PHONE_PART_LEN) - { - formatted_phone_str.insert(separator_pos, PHONE_SEPARATOR); - } - - return formatted_phone_str; -} - bool LLTextUtil::processUrlMatch(LLUrlMatch* match,LLTextBase* text_base, bool is_content_trusted) { if (match == 0 || text_base == 0) diff --git a/indra/llui/lltextutil.h b/indra/llui/lltextutil.h index a9c143e445..1adc3516f7 100644 --- a/indra/llui/lltextutil.h +++ b/indra/llui/lltextutil.h @@ -59,18 +59,6 @@ namespace LLTextUtil const std::string& greyed); /** - * Formats passed phone number to be more human readable. - * - * It just divides the number on parts by two digits from right to left. The first left part - * can have 2 or 3 digits, i.e. +44-33-33-44-55-66 or 12-34-56-78-90. Separator is set in - * application settings (AvalinePhoneSeparator) - * - * @param[in] phone_str string with original phone number - * @return reference to string with formatted phone number - */ - const std::string& formatPhoneNumber(const std::string& phone_str); - - /** * Adds icon before url if need. * * @param[in] match an object with results of matching diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index 84ea770a8d..8216046174 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -222,6 +222,15 @@ void LLUrlAction::removeFriend(std::string url) } } +void LLUrlAction::reportAbuse(std::string url) +{ + std::string id_str = getUserID(url); + if (LLUUID::validate(id_str)) + { + executeSLURL("secondlife:///app/agent/" + id_str + "/reportAbuse"); + } +} + void LLUrlAction::blockObject(std::string url) { std::string object_id = getObjectId(url); diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index 2d2a8dfef1..c2c576254d 100644 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -82,6 +82,7 @@ public: static void sendIM(std::string url); static void addFriend(std::string url); static void removeFriend(std::string url); + static void reportAbuse(std::string url); static void blockObject(std::string url); static void unblockObject(std::string url); diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 5404ac50e5..e65cc7563e 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -148,6 +148,22 @@ void LLKeyboard::addKeyName(KEY key, const std::string& name) sNamesToKeys[nameuc] = key; } +void LLKeyboard::resetKeyDownAndHandle() +{ + MASK mask = currentMask(FALSE); + for (S32 i = 0; i < KEY_COUNT; i++) + { + if (mKeyLevel[i]) + { + mKeyDown[i] = FALSE; + mKeyLevel[i] = FALSE; + mKeyUp[i] = TRUE; + mCurTranslatedKey = (KEY)i; + mCallbacks->handleTranslatedKeyUp(i, mask); + } + } +} + // BUG this has to be called when an OS dialog is shown, otherwise modifier key state // is wrong because the keyup event is never received by the main window. JC void LLKeyboard::resetKeys() diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 36bd8bcbed..fb1ae10f50 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -58,7 +58,8 @@ public: LLKeyboard(); virtual ~LLKeyboard(); - void resetKeys(); + void resetKeyDownAndHandle(); + void resetKeys(); F32 getCurKeyElapsedTime() { return getKeyDown(mCurScanKey) ? getKeyElapsedTime( mCurScanKey ) : 0.f; } diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index ceb80ed349..9fed57ba53 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -501,14 +501,14 @@ attributedStringInfo getSegments(NSAttributedString *str) // e.g. OS Window for upload something or Input Window... // mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit) mModifiers = [theEvent modifierFlags]; + unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; + bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch); - bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, [[theEvent characters] characterAtIndex:0]); - unichar ch; if (acceptsText && !mMarkedTextAllowed && !(mModifiers & (NSControlKeyMask | NSCommandKeyMask)) && // commands don't invoke InputWindow ![(LLAppDelegate*)[NSApp delegate] romanScript] && - (ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]) > ' ' && + ch > ' ' && ch != NSDeleteCharacter && (ch < 0xF700 || ch > 0xF8FF)) // 0xF700-0xF8FF: reserved for function keys on the keyboard(from NSEvent.h) { diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index f895c17643..5ec9b017cf 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -100,13 +100,13 @@ const unsigned short *copyFromPBoard() CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - + // extra retain on the NSCursor since we want it to live for the lifetime of the app. NSCursor *cursor = [[[NSCursor alloc] initWithImage: [[[NSImage alloc] initWithContentsOfFile: - [NSString stringWithFormat:@"%s", fullpath] + [NSString stringWithUTF8String:fullpath] ]autorelease] hotSpot:NSMakePoint(hotspotX, hotspotY) ]retain]; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 4bcb9b3aef..3a5287f907 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1676,7 +1676,7 @@ void LLWindowMacOSX::hideCursor() void LLWindowMacOSX::showCursor() { - if(mCursorHidden) + if(mCursorHidden || !isCGCursorVisible()) { // LL_INFOS() << "showCursor: showing" << LL_ENDL; mCursorHidden = FALSE; diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index ea70e21414..43d3a32e64 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -34,6 +34,7 @@ #include "llplugininstance.h" #include "llpluginmessage.h" #include "llpluginmessageclasses.h" +#include "llstring.h" #include "volume_catcher.h" #include "media_plugin_base.h" @@ -55,7 +56,7 @@ private: bool init(); void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height); - void onCustomSchemeURLCallback(std::string url); + void onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect); void onConsoleMessageCallback(std::string message, std::string source, int line); void onStatusMessageCallback(std::string value); void onTitleChangeCallback(std::string title); @@ -299,11 +300,18 @@ void MediaPluginCEF::onOpenPopupCallback(std::string url, std::string target) //////////////////////////////////////////////////////////////////////////////// // -void MediaPluginCEF::onCustomSchemeURLCallback(std::string url) +void MediaPluginCEF::onCustomSchemeURLCallback(std::string url, bool user_gesture, bool is_redirect) { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "click_nofollow"); - message.setValue("uri", url); - message.setValue("nav_type", "clicked"); // TODO: differentiate between click and navigate to + message.setValue("uri", url); + + // indicate if this interaction was from a user click (okay on a SLAPP) or + // via a navigation (e.g. a data URL - see SL-18151) (not okay on a SLAPP) + const std::string nav_type = user_gesture ? "clicked" : "navigated"; + + message.setValue("nav_type", nav_type); + message.setValueBoolean("is_redirect", is_redirect); + sendMessage(message); } @@ -592,7 +600,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) { // event callbacks from Dullahan mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); - mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1)); + mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1)); mCEFLib->setOnTitleChangeCallback(std::bind(&MediaPluginCEF::onTitleChangeCallback, this, std::placeholders::_1)); @@ -616,9 +624,9 @@ void MediaPluginCEF::receiveMessage(const char* message_string) // dir as the executable that loaded it (SLPlugin.exe). The code in // Dullahan that tried to figure out the location automatically uses // the location of the exe which isn't helpful so we tell it explicitly. - char cur_dir_str[MAX_PATH]; - GetCurrentDirectoryA(MAX_PATH, cur_dir_str); - settings.host_process_path = std::string(cur_dir_str); + std::vector<wchar_t> buffer(MAX_PATH + 1); + GetCurrentDirectoryW(MAX_PATH, &buffer[0]); + settings.host_process_path = ll_convert_wide_to_string(&buffer[0]); #endif settings.accept_language_list = mHostLanguage; diff --git a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp index 1afe25e9a1..89144922cc 100644 --- a/indra/media_plugins/libvlc/media_plugin_libvlc.cpp +++ b/indra/media_plugins/libvlc/media_plugin_libvlc.cpp @@ -73,6 +73,7 @@ private: static void display(void* data, void* id); /*virtual*/ void setDirty(int left, int top, int right, int bottom) /* override, but that is not supported in gcc 4.6 */; + void setDurationDirty(); static void eventCallbacks(const libvlc_event_t* event, void* ptr); @@ -93,8 +94,8 @@ private: bool mIsLooping; - float mCurTime; - float mDuration; + F64 mCurTime; + F64 mDuration; EStatus mVlcStatus; }; @@ -214,6 +215,19 @@ void MediaPluginLibVLC::setDirty(int left, int top, int right, int bottom) } //////////////////////////////////////////////////////////////////////////////// +// *virtual* +void MediaPluginLibVLC::setDurationDirty() +{ + LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "updated"); + + message.setValueReal("current_time", mCurTime); + message.setValueReal("duration", mDuration); + message.setValueReal("current_rate", 1.0f); + + sendMessage(message); +} + +//////////////////////////////////////////////////////////////////////////////// // void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) { @@ -233,6 +247,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) parent->mDuration = (float)(libvlc_media_get_duration(parent->mLibVLCMedia)) / 1000.0f; parent->mVlcStatus = STATUS_PLAYING; parent->setVolumeVLC(); + parent->setDurationDirty(); break; case libvlc_MediaPlayerPaused: @@ -245,6 +260,8 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) case libvlc_MediaPlayerEndReached: parent->mVlcStatus = STATUS_DONE; + parent->mCurTime = parent->mDuration; + parent->setDurationDirty(); break; case libvlc_MediaPlayerEncounteredError: @@ -253,6 +270,11 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) case libvlc_MediaPlayerTimeChanged: parent->mCurTime = (float)libvlc_media_player_get_time(parent->mLibVLCMediaPlayer) / 1000.0f; + if (parent->mVlcStatus == STATUS_DONE && libvlc_media_player_is_playing(parent->mLibVLCMediaPlayer)) + { + parent->mVlcStatus = STATUS_PLAYING; + } + parent->setDurationDirty(); break; case libvlc_MediaPlayerPositionChanged: @@ -260,6 +282,7 @@ void MediaPluginLibVLC::eventCallbacks(const libvlc_event_t* event, void* ptr) case libvlc_MediaPlayerLengthChanged: parent->mDuration = (float)libvlc_media_get_duration(parent->mLibVLCMedia) / 1000.0f; + parent->setDurationDirty(); break; case libvlc_MediaPlayerTitleChanged: @@ -562,7 +585,24 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string) mTextureWidth = texture_width; mTextureHeight = texture_height; + libvlc_time_t time = 1000.0 * mCurTime; + playMedia(); + + if (mLibVLCMediaPlayer) + { + libvlc_media_player_set_time(mLibVLCMediaPlayer, time); + time = libvlc_media_player_get_time(mLibVLCMediaPlayer); + if (time < 0) + { + // -1 if there is no media + mCurTime = 0; + } + else + { + mCurTime = (F64)time / 1000.0; + } + } }; }; @@ -594,6 +634,13 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string) { if (mLibVLCMediaPlayer) { + if (mVlcStatus == STATUS_DONE && !libvlc_media_player_is_playing(mLibVLCMediaPlayer)) + { + // stop or vlc will ignore 'play', it will just + // make an MediaPlayerEndReached event even if + // seek was used + libvlc_media_player_stop(mLibVLCMediaPlayer); + } libvlc_media_player_play(mLibVLCMediaPlayer); } } @@ -606,15 +653,32 @@ void MediaPluginLibVLC::receiveMessage(const char* message_string) } else if (message_name == "seek") { - if (mDuration > 0) - { - F64 normalized_offset = message_in.getValueReal("time") / mDuration; - libvlc_media_player_set_position(mLibVLCMediaPlayer, normalized_offset); - } + if (mLibVLCMediaPlayer) + { + libvlc_time_t time = 1000.0 * message_in.getValueReal("time"); + libvlc_media_player_set_time(mLibVLCMediaPlayer, time); + time = libvlc_media_player_get_time(mLibVLCMediaPlayer); + if (time < 0) + { + // -1 if there is no media + mCurTime = 0; + } + else + { + mCurTime = (F64)time / 1000.0; + } + + if (!libvlc_media_player_is_playing(mLibVLCMediaPlayer)) + { + // if paused, won't trigger update, update now + setDurationDirty(); + } + } } else if (message_name == "set_loop") { - mIsLooping = true; + bool loop = message_in.getValueBoolean("loop"); + mIsLooping = loop; } else if (message_name == "set_volume") { diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9508c1dc2d..a1f5e90730 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -544,17 +544,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>AvalinePhoneSeparator</key> - <map> - <key>Comment</key> - <string>Separator of phone parts to have Avaline numbers human readable in Voice Control Panel</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>-</string> - </map> <key>AvatarAxisDeadZone0</key> <map> <key>Comment</key> @@ -4792,7 +4781,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> + <string>https://search.[GRID]/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> </map> <key>GuidebookURL</key> <map> @@ -5840,6 +5829,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DiskCacheVersion</key> + <map> + <key>Comment</key> + <string>Version number of disk cache</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>LocalFileSystemBrowsingEnabled</key> <map> <key>Comment</key> @@ -9924,7 +9924,7 @@ <key>RenderGLContextCoreProfile</key> <map> <key>Comment</key> - <string>Don't use a compatibility profile OpenGL context. Requires restart. Basic shaders MUST be enabled.</string> + <string>Don't use a compatibility profile OpenGL context. Requires restart.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -10784,18 +10784,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderUseTransformFeedback</key> - <map> - <key>Comment</key> - <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> - <key>RenderVBOMappingDisable</key> <map> <key>Comment</key> @@ -15742,6 +15730,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>AllowSelectAvatar</key> + <map> + <key>Comment</key> + <string>Allows user to select and move avatars, move is viewer sided, does not propagate to server, also supresses avatar position updates while avatars are selected</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>WebProfileFloaterRect</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 537744b44c..eb3528b9b7 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -370,6 +370,17 @@ <key>Value</key> <string></string> </map> + <key>PBRUploadFolder</key> + <map> + <key>Comment</key> + <string>All pbr uploads will be stored in this directory (UUID)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string></string> + </map> <key>TextureUploadFolder</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 02b2daf0ac..fc1cee1f59 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -262,27 +262,15 @@ void main() vec3 sun_contrib = min(final_da, shadow) * sunlit; -#if !defined(AMBIENT_KILL) color.rgb = amblit; color.rgb *= ambient; -#endif // !defined(AMBIENT_KILL) -vec3 post_ambient = color.rgb; - -#if !defined(SUNLIGHT_KILL) color.rgb += sun_contrib; -#endif // !defined(SUNLIGHT_KILL) - -vec3 post_sunlight = color.rgb; color.rgb *= diffuse_srgb.rgb; -vec3 post_diffuse = color.rgb; - color.rgb = atmosFragLighting(color.rgb, additive, atten); -vec3 post_atmo = color.rgb; - vec4 light = vec4(0,0,0,0); color.rgb = scaleSoftClipFrag(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl index c64b6ba240..c2372fcbc0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl @@ -58,7 +58,7 @@ void main() frag_color = vec4(1,1,1,1); -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); #endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl index b54c580ce9..d0a049d372 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl @@ -35,7 +35,7 @@ uniform sampler2D diffuseMap; VARYING float pos_w; VARYING float target_pos_x; -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) VARYING vec4 post_pos; #endif @@ -61,7 +61,7 @@ void main() frag_color = vec4(1,1,1,1); -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl index 31b93dc36a..a7bf4d7780 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl @@ -1,5 +1,5 @@ /** - * @file attachmentShadowV.glsl + * @file attachmentAlphaShadowV.glsl * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2007, Linden Research, Inc. @@ -35,7 +35,7 @@ ATTRIBUTE vec2 texcoord0; mat4 getObjectSkinnedTransform(); void passTextureIndex(); -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) VARYING vec4 post_pos; #endif VARYING vec2 vary_texcoord0; @@ -61,7 +61,7 @@ void main() vertex_color = diffuse_color; -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) p.z = max(p.z, -p.w+0.01); post_pos = p; gl_Position = p; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl index b8ce54bcb1..f231213ac8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl @@ -1,5 +1,5 @@ /** - * @file treeShadowF.glsl + * @file avatarAlphaMaskShadowF.glsl * * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code @@ -32,7 +32,7 @@ out vec4 frag_color; uniform float minimum_alpha; uniform sampler2D diffuseMap; -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) VARYING vec4 post_pos; #endif @@ -59,7 +59,7 @@ void main() frag_color = vec4(1,1,1,1); -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); #endif } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl index 1b16e4eb09..0e66c722b6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl @@ -33,7 +33,7 @@ uniform float minimum_alpha; uniform sampler2D diffuseMap; -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) VARYING vec4 post_pos; #endif @@ -61,7 +61,7 @@ void main() frag_color = vec4(1,1,1,1); -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); #endif diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl index 1c5b142ebd..40ac7b1f95 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl @@ -1,5 +1,5 @@ /** - * @file avatarShadowV.glsl + * @file avatarAlphaShadowV.glsl * * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code @@ -34,7 +34,7 @@ ATTRIBUTE vec3 position; ATTRIBUTE vec3 normal; ATTRIBUTE vec2 texcoord0; -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) VARYING vec4 post_pos; #endif VARYING float pos_w; @@ -66,7 +66,7 @@ void main() vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; -#if !DEPTH_CLAMP +#if !defined(DEPTH_CLAMP) post_pos = pos; gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 449cbeaa28..49f85af53b 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -23,9 +23,35 @@ * $/LicenseInfo$ */ + +/* Parts of this file are taken from Sascha Willem's Vulkan GLTF refernce implementation +MIT License + +Copyright (c) 2018 Sascha Willems + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + uniform sampler2DRect normalMap; uniform sampler2DRect depthMap; uniform sampler2D projectionMap; // rgba +uniform sampler2D brdfLut; // projected lighted params uniform mat4 proj_mat; //screen space to light space projector @@ -322,162 +348,150 @@ vec3 hue_to_rgb(float hue) // PBR Utils -// ior Index of Refraction, normally 1.5 -// returns reflect0 -float calcF0(float ior) -{ - float f0 = (1.0 - ior) / (1.0 + ior); - return f0 * f0; -} - -vec3 fresnel(float vh, vec3 f0, vec3 f90 ) -{ - float x = 1.0 - abs(vh); - float x2 = x*x; - float x5 = x2*x2*x; - vec3 fr = f0 + (f90 - f0)*x5; - return fr; -} - -vec3 fresnelSchlick( vec3 reflect0, vec3 reflect90, float vh) -{ - return reflect0 + (reflect90 - reflect0) * pow(clamp(1.0 - vh, 0.0, 1.0), 5.0); -} - -// Approximate Environment BRDF -vec2 getGGXApprox( vec2 uv ) -{ - // Reference: Physically Based Shading on Mobile - // https://www.unrealengine.com/en-US/blog/physically-based-shading-on-mobile - // EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV ) - float nv = uv.x; - float roughness = uv.y; - - const vec4 c0 = vec4( -1, -0.0275, -0.572, 0.022 ); - const vec4 c1 = vec4( 1, 0.0425, 1.04 , -0.04 ); - vec4 r = roughness * c0 + c1; - float a004 = min( r.x * r.x, exp2( -9.28 * nv ) ) * r.x + r.y; - vec2 ScaleBias = vec2( -1.04, 1.04 ) * a004 + r.zw; - return ScaleBias; -} - -#define PBR_USE_GGX_APPROX 1 -vec2 getGGX( vec2 brdfPoint ) -{ -#if PBR_USE_GGX_APPROX - return getGGXApprox( brdfPoint); -#else - return texture2D(GGXLUT, brdfPoint).rg; // TODO: use GGXLUT -#endif -} - - -// Reference: float getRangeAttenuation(float range, float distance) -float getLightAttenuationPointSpot(float range, float distance) -{ -#if 1 - return distance; -#else - float range2 = pow(range, 2.0); - - // support negative range as unlimited - if (range <= 0.0) - { - return 1.0 / range2; - } - - return max(min(1.0 - pow(distance / range, 4.0), 1.0), 0.0) / range2; -#endif -} - -vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance) +vec2 BRDF(float NoV, float roughness) { - float rangeAttenuation = getLightAttenuationPointSpot(lightRange, lightDistance); - return rangeAttenuation * lightColor; + return texture(brdfLut, vec2(NoV, roughness)).rg; } -float getLightAttenuationSpot(vec3 spotDirection) +// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL +vec3 pbrIbl(vec3 diffuseColor, + vec3 specularColor, + vec3 radiance, // radiance map sample + vec3 irradiance, // irradiance map sample + float ao, // ambient occlusion factor + float nv, // normal dot view vector + float perceptualRough) { - return 1.0; -} - -vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v) -{ - float spotAttenuation = getLightAttenuationSpot(-v); - return spotAttenuation * getLightIntensityPoint( lightColor, lightRange, lightDistance ); -} + // retrieve a scale and bias to F0. See [1], Figure 3 + vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough); + vec3 diffuseLight = irradiance; + vec3 specularLight = radiance; + + vec3 diffuse = diffuseLight * diffuseColor; + vec3 specular = specularLight * (specularColor * brdf.x + brdf.y); -// NOTE: This is different from the GGX texture -float D_GGX( float nh, float alphaRough ) -{ - float rough2 = alphaRough * alphaRough; - float f = (nh * nh) * (rough2 - 1.0) + 1.0; - return rough2 / (M_PI * f * f); -} - -// NOTE: This is different from the GGX texture -// See: -// Real Time Rendering, 4th Edition -// Page 341 -// Equation 9.43 -// Also see: -// https://google.github.io/filament/Filament.md.html#materialsystem/specularbrdf/geometricshadowing(specularg) -// 4.4.2 Geometric Shadowing (specular G) -float V_GGX( float nl, float nv, float alphaRough ) -{ -#if 1 - // Note: When roughness is zero, has discontuinity in the bottom hemisphere - float rough2 = alphaRough * alphaRough; - float ggxv = nl * sqrt(nv * nv * (1.0 - rough2) + rough2); - float ggxl = nv * sqrt(nl * nl * (1.0 - rough2) + rough2); - - float ggx = ggxv + ggxl; - if (ggx > 0.0) - { - return 0.5 / ggx; - } - return 0.0; -#else - // See: smithVisibility_GGXCorrelated, V_SmithCorrelated, etc. - float rough2 = alphaRough * alphaRough; - float ggxv = nl * sqrt(nv * (nv - rough2 * nv) + rough2); - float ggxl = nv * sqrt(nl * (nl - rough2 * nl) + rough2); - return 0.5 / (ggxv + ggxl); -#endif - -} - -// NOTE: Assumes a hard-coded IOR = 1.5 -void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ) -{ - float metal = packedORM.b; - c_diff = mix(diffuse, vec3(0), metal); - float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics) - reflect0 = vec3(0.04); // -> incidence reflectance 0.04 -// reflect0 = vec3(calcF0(IOR)); - reflect0 = mix(reflect0, diffuse, metal); // reflect at 0 degrees - reflect90 = vec3(1); // reflect at 90 degrees - specWeight = 1.0; - - // When roughness is zero blender shows a tiny specular - float perceptualRough = max(packedORM.g, 0.1); - alphaRough = perceptualRough * perceptualRough; -} - -vec3 BRDFDiffuse(vec3 color) -{ - return color * ONE_OVER_PI; -} - -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ) -{ - return (1.0 - specWeight * fresnelSchlick( reflect0, reflect90, vh)) * BRDFDiffuse(c_diff); -} - -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRough, float specWeight, float vh, float nl, float nv, float nh ) -{ - vec3 fresnel = fresnelSchlick( reflect0, reflect90, vh ); // Fresnel - float vis = V_GGX( nl, nv, alphaRough ); // Visibility - float d = D_GGX( nh, alphaRough ); // Distribution - return specWeight * fresnel * vis * d; + //specular *= 1.5; + + return (diffuse + specular) * ao; +} + +// Encapsulate the various inputs used by the various functions in the shading equation +// We store values in this struct to simplify the integration of alternative implementations +// of the shading terms, outlined in the Readme.MD Appendix. +struct PBRInfo +{ + float NdotL; // cos angle between normal and light direction + float NdotV; // cos angle between normal and view direction + float NdotH; // cos angle between normal and half vector + float LdotH; // cos angle between light direction and half vector + float VdotH; // cos angle between view direction and half vector + float perceptualRoughness; // roughness value, as authored by the model creator (input to shader) + float metalness; // metallic value at the surface + vec3 reflectance0; // full reflectance color (normal incidence angle) + vec3 reflectance90; // reflectance color at grazing angle + float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2]) + vec3 diffuseColor; // color contribution from diffuse lighting + vec3 specularColor; // color contribution from specular lighting +}; + +// Basic Lambertian diffuse +// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog +// See also [1], Equation 1 +vec3 diffuse(PBRInfo pbrInputs) +{ + return pbrInputs.diffuseColor / M_PI; +} + +// The following equation models the Fresnel reflectance term of the spec equation (aka F()) +// Implementation of fresnel from [4], Equation 15 +vec3 specularReflection(PBRInfo pbrInputs) +{ + return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); +} + +// This calculates the specular geometric attenuation (aka G()), +// where rougher material will reflect less light back to the viewer. +// This implementation is based on [1] Equation 4, and we adopt their modifications to +// alphaRoughness as input as originally proposed in [2]. +float geometricOcclusion(PBRInfo pbrInputs) +{ + float NdotL = pbrInputs.NdotL; + float NdotV = pbrInputs.NdotV; + float r = pbrInputs.alphaRoughness; + + float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); + float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); + return attenuationL * attenuationV; +} + +// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D()) +// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz +// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3. +float microfacetDistribution(PBRInfo pbrInputs) +{ + float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; + float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0; + return roughnessSq / (M_PI * f * f); +} + +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 v, // surface point to camera + vec3 l) //surface point to light +{ + // make sure specular highlights from punctual lights don't fall off of polished surfaces + perceptualRoughness = max(perceptualRoughness, 8.0/255.0); + + float alphaRoughness = perceptualRoughness * perceptualRoughness; + + // Compute reflectance. + float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b); + + // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect. + // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%. + float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0); + vec3 specularEnvironmentR0 = specularColor.rgb; + vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90; + + vec3 h = normalize(l+v); // Half vector between both l and v + vec3 reflection = -normalize(reflect(v, n)); + reflection.y *= -1.0f; + + float NdotL = clamp(dot(n, l), 0.001, 1.0); + float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0); + float NdotH = clamp(dot(n, h), 0.0, 1.0); + float LdotH = clamp(dot(l, h), 0.0, 1.0); + float VdotH = clamp(dot(v, h), 0.0, 1.0); + + PBRInfo pbrInputs = PBRInfo( + NdotL, + NdotV, + NdotH, + LdotH, + VdotH, + perceptualRoughness, + metallic, + specularEnvironmentR0, + specularEnvironmentR90, + alphaRoughness, + diffuseColor, + specularColor + ); + + // Calculate the shading terms for the microfacet specular shading model + vec3 F = specularReflection(pbrInputs); + float G = geometricOcclusion(pbrInputs); + float D = microfacetDistribution(pbrInputs); + + const vec3 u_LightColor = vec3(1.0); + + // Calculation of analytical lighting contribution + vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs); + vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV); + // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law) + vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib); + + return color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl new file mode 100644 index 0000000000..73a70d8dc5 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl @@ -0,0 +1,141 @@ +/** + * @file class1/deferred/genbrdflut.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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$ + */ + +/* Taken from Sascha Willem's Vulkan GLTF refernce implementation +MIT License + +Copyright (c) 2018 Sascha Willems + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/*[EXTRA_CODE_HERE]*/ + +VARYING vec2 vary_uv; + +out vec4 outColor; + +#define NUM_SAMPLES 1024 + +const float PI = 3.1415926536; + +// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +float random(vec2 co) +{ + float a = 12.9898; + float b = 78.233; + float c = 43758.5453; + float dt= dot(co.xy ,vec2(a,b)); + float sn= mod(dt,3.14); + return fract(sin(sn) * c); +} + +vec2 hammersley2d(uint i, uint N) +{ + // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + uint bits = (i << 16u) | (i >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + float rdi = float(bits) * 2.3283064365386963e-10; + return vec2(float(i) /float(N), rdi); +} + +// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf +vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal) +{ + // Maps a 2D point to a hemisphere with spread based on roughness + float alpha = roughness * roughness; + float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); + + // Tangent space + vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + vec3 tangentX = normalize(cross(up, normal)); + vec3 tangentY = normalize(cross(normal, tangentX)); + + // Convert to world Space + return normalize(tangentX * H.x + tangentY * H.y + normal * H.z); +} + +// Geometric Shadowing function +float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness) +{ + float k = (roughness * roughness) / 2.0; + float GL = dotNL / (dotNL * (1.0 - k) + k); + float GV = dotNV / (dotNV * (1.0 - k) + k); + return GL * GV; +} + +vec2 BRDF(float NoV, float roughness) +{ + // Normal always points along z-axis for the 2D lookup + const vec3 N = vec3(0.0, 0.0, 1.0); + vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV); + + vec2 LUT = vec2(0.0); + for(uint i = 0u; i < NUM_SAMPLES; i++) { + vec2 Xi = hammersley2d(i, NUM_SAMPLES); + vec3 H = importanceSample_GGX(Xi, roughness, N); + vec3 L = 2.0 * dot(V, H) * H - V; + + float dotNL = max(dot(N, L), 0.0); + float dotNV = max(dot(N, V), 0.0); + float dotVH = max(dot(V, H), 0.0); + float dotNH = max(dot(H, N), 0.0); + + if (dotNL > 0.0) { + float G = G_SchlicksmithGGX(dotNL, dotNV, roughness); + float G_Vis = (G * dotVH) / (dotNH * dotNV); + float Fc = pow(1.0 - dotVH, 5.0); + LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis); + } + } + return LUT / float(NUM_SAMPLES); +} + +void main() +{ + outColor = vec4(BRDF(vary_uv.s, 1.0-vary_uv.t), 0.0, 1.0); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl new file mode 100644 index 0000000000..682244478b --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl @@ -0,0 +1,39 @@ +/** + * @file class3\deferred\genbrdflutV.glsl + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +VARYING vec2 vary_uv; + +void main() +{ + //transform vertex + vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0); + vary_uv = position.xy*0.5+0.5; + + gl_Position = vec4(position.xyz, 1.0); +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 6f087632a5..e87d90aa9e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -345,35 +345,6 @@ void main() if (spec.a > 0.0) // specular reflection { - /* // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020 - // Preserving the refactored version as a comment for potential reconsideration, - // overriding the general rule to avoid pollutiong the source with commented code. - // - // If you're reading this in 2021+, feel free to obliterate. - - vec3 npos = -normalize(pos.xyz); - - //vec3 ref = dot(pos+lv, norm); - vec3 h = normalize(light_dir.xyz + npos); - float nh = dot(norm.xyz, h); - float nv = dot(norm.xyz, npos); - float vh = dot(npos, h); - float sa = nh; - float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5; - - float gtdenom = 2 * nh; - float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh)); - - if (nh > 0.0) - { - float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da); - vec3 sp = sun_contrib*scol / 6.0f; - sp = clamp(sp, vec3(0), vec3(1)); - bloom = dot(sp, sp) / 4.0; - color += sp * spec.rgb; - } - */ - float sa = dot(refnormpersp, sun_dir.xyz); vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl index bde015d109..1caf2b2b1a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl @@ -25,24 +25,11 @@ /*[EXTRA_CODE_HERE]*/ -#define PBR_USE_IBL 1 -#define PBR_USE_SUN 1 -#define PBR_USE_IRRADIANCE_HACK 1 - #define DIFFUSE_ALPHA_MODE_NONE 0 #define DIFFUSE_ALPHA_MODE_BLEND 1 #define DIFFUSE_ALPHA_MODE_MASK 2 #define DIFFUSE_ALPHA_MODE_EMISSIVE 3 -#define DEBUG_PBR_LIGHT_TYPE 0 // Output Diffuse=0.75, Emissive=0, ORM=0,0,0 - -#define DEBUG_BASIC 0 -#define DEBUG_VERTEX 0 -#define DEBUG_NORMAL_MAP 0 // Output packed normal map "as is" to diffuse -#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse -#define DEBUG_ORM 0 // Output Occlusion Roughness Metal "as is" to diffuse -#define DEBUG_POSITION 0 - uniform sampler2D diffuseMap; //always in sRGB space uniform sampler2D bumpMap; uniform sampler2D emissiveMap; @@ -56,8 +43,6 @@ uniform vec3 emissiveColor; uniform sampler2DRect lightMap; #endif -uniform samplerCube environmentMap; -uniform mat3 env_mat; uniform int sun_up_factor; uniform vec3 sun_dir; uniform vec3 moon_dir; @@ -84,18 +69,12 @@ uniform vec3 moon_dir; VARYING vec3 vary_position; VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; - -#ifdef HAS_NORMAL_MAP -VARYING vec3 vary_normal; -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; VARYING vec2 vary_texcoord1; -#endif +VARYING vec2 vary_texcoord2; +VARYING vec3 vary_normal; +VARYING vec3 vary_tangent; +flat in float vary_sign; -#ifdef HAS_SPECULAR_MAP - VARYING vec2 vary_texcoord2; -#endif #ifdef HAS_ALPHA_MASK uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() @@ -107,67 +86,74 @@ uniform vec4 light_position[8]; uniform vec3 light_direction[8]; // spot direction uniform vec4 light_attenuation[8]; // linear, quadratic, is omni, unused, See: LLPipeline::setupHWLights() and syncLightState() uniform vec3 light_diffuse[8]; +uniform vec2 light_deferred_attenuation[8]; // light size and falloff -vec2 encode_normal(vec3 n); vec3 srgb_to_linear(vec3 c); vec3 linear_to_srgb(vec3 c); // These are in deferredUtil.glsl but we can't set: mFeatures.isDeferred to include it -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); +vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); +vec3 scaleSoftClipFrag(vec3 l); + void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); float calcLegacyDistanceAttenuation(float distance, float falloff); -vec2 getGGX( vec2 brdfPoint ); -void initMaterial( vec3 diffuse, vec3 packedORM, - out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen); void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyEnv, vec3 pos, vec3 norm, float glossiness, float envIntensity); -vec3 hue_to_rgb(float hue); - -// lp = light position -// la = linear attenuation, light radius -// fa = falloff -// See: LLRender::syncLightState() -vec3 calcPointLightOrSpotLight(vec3 reflect0, vec3 c_diff, - vec3 lightColor, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, - float la, float fa, float is_pointlight, float ambiance) +// PBR interface +vec3 pbrIbl(vec3 diffuseColor, + vec3 specularColor, + vec3 radiance, // radiance map sample + vec3 irradiance, // irradiance map sample + float ao, // ambient occlusion factor + float nv, // normal dot view vector + float perceptualRoughness); + +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 v, // surface point to camera + vec3 l); //surface point to light + +vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 p, // pixel position + vec3 v, // view vector (negative normalized pixel position) + vec3 lp, // light position + vec3 ld, // light direction (for spotlights) + vec3 lightColor, + float lightSize, float falloff, float is_pointlight, float ambiance) { - vec3 intensity = vec3(0); + vec3 color = vec3(0,0,0); - vec3 lv = lp.xyz - v; - vec3 h, l; - float nh, nl, nv, vh, lightDist; - calcHalfVectors(lv,n,v,h,l,nh,nl,nv,vh,lightDist); + vec3 lv = lp.xyz - p; - if (lightDist > 0.0) - { - float falloff_factor = (12.0 * fa) - 9.0; - float inverted_la = falloff_factor / la; - - float dist = lightDist / inverted_la; + float lightDist = length(lv); - float dist_atten = calcLegacyDistanceAttenuation(dist,fa); - if (dist_atten <= 0.0) - return intensity; + float dist = lightDist / lightSize; + if (dist <= 1.0) + { + lv /= lightDist; - vec3 reflect90 = vec3(1); - float specWeight = 1.0; + float dist_atten = calcLegacyDistanceAttenuation(dist, falloff); - lv = normalize(lv); - float spot = max(dot(-ln, lv), is_pointlight); - nl *= spot * spot; + vec3 intensity = dist_atten * lightColor * 3.0; - if (nl > 0.0) - intensity = dist_atten * nl * lightColor * BRDFLambertian(reflect0, reflect90, c_diff, specWeight, vh); + color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv); } - return intensity; + + return color; } void main() { + vec3 color = vec3(0,0,0); + vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; vec3 pos = vary_position; @@ -180,10 +166,11 @@ void main() vec3 atten; calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); + // IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; // vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; // else - vec4 albedo = texture2D(diffuseMap, vary_texcoord0.xy).rgba; + vec4 albedo = texture(diffuseMap, vary_texcoord0.xy).rgba; albedo.rgb = srgb_to_linear(albedo.rgb); #ifdef HAS_ALPHA_MASK if (albedo.a < minimum_alpha) @@ -192,128 +179,61 @@ void main() } #endif -// vec3 base = vertex_color.rgb * albedo.rgb * albedo.a; - vec3 base = vertex_color.rgb * albedo.rgb; + vec3 baseColor = vertex_color.rgb * albedo.rgb; -#ifdef HAS_NORMAL_MAP - vec4 norm = texture2D(bumpMap, vary_texcoord1.xy); - norm.xyz = normalize(norm.xyz * 2 - 1); + vec3 vNt = texture(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0; + float sign = vary_sign; + vec3 vN = vary_normal; + vec3 vT = vary_tangent.xyz; + + vec3 vB = sign * cross(vN, vT); + vec3 norm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); - vec3 tnorm = vec3(dot(norm.xyz,vary_mat0), - dot(norm.xyz,vary_mat1), - dot(norm.xyz,vary_mat2)); -#else - vec4 norm = vec4(0,0,0,1.0); -// vec3 tnorm = vary_normal; - vec3 tnorm = vec3(0,0,1); -#endif - - tnorm = normalize(tnorm.xyz); - norm.xyz = tnorm.xyz; + norm *= gl_FrontFacing ? 1.0 : -1.0; -#if HAS_SHADOW +#ifdef HAS_SHADOW vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag); #endif - // RGB = Occlusion, Roughness, Metal - // default values, see LLViewerFetchedTexture::sWhiteImagep since roughnessFactor and metallicFactor are multiplied in - // occlusion 1.0 - // roughness 0.0 - // metal 0.0 -#ifdef HAS_SPECULAR_MAP - vec3 packedORM = texture2D(specularMap, vary_texcoord2.xy).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: lldrawpoolapha.cpp -#else - vec3 packedORM = vec3(1,0,0); -#endif + vec3 orm = texture(specularMap, vary_texcoord2.xy).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space - packedORM.g *= roughnessFactor; - packedORM.b *= metallicFactor; + float perceptualRoughness = orm.g * roughnessFactor; + float metallic = orm.b * metallicFactor; + float ao = orm.r; + // emissiveColor is the emissive color factor from GLTF and is already in linear space vec3 colorEmissive = emissiveColor; -#ifdef HAS_EMISSIVE_MAP - colorEmissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb; -#endif - - vec3 colorDiffuse = vec3(0); - vec3 colorSpec = vec3(0); - - float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics) - float ao = packedORM.r; - float perceptualRough = packedORM.g; - float metal = packedORM.b; - - vec3 v = -normalize(vary_position.xyz); - vec3 n = norm.xyz; - vec3 t = vec3(1,0,0); - vec3 b = normalize(cross(n,t)); - vec3 reflectVN = normalize(reflect(-v,n)); - - vec3 h, l; - float nh, nl, nv, vh, lightDist; - calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist); - - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - - // Common to RadianceGGX and RadianceLambertian - vec2 brdfPoint = clamp(vec2(nv, perceptualRough), vec2(0,0), vec2(1,1)); - vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0 - vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel - vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0); - - vec3 legacyenv; + // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear + colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb); + // PBR IBL + float gloss = 1.0 - perceptualRoughness; vec3 irradiance = vec3(0); - vec3 specLight = vec3(0); - float gloss = 1.0 - perceptualRough; - sampleReflectionProbes(irradiance, specLight, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); -#if PBR_USE_IRRADIANCE_HACK - irradiance = max(amblit,irradiance) * ambocc; -#else -irradiance = vec3(amblit); -#endif + vec3 radiance = vec3(0); + vec3 legacyenv = vec3(0); + sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); + irradiance = max(srgb_to_linear(amblit),irradiance) * ambocc*4.0; - vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; -#if PBR_USE_IBL - colorSpec += specWeight * specLight * FssEssGGX; -#endif + vec3 f0 = vec3(0.04); + + vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0); + diffuseColor *= 1.0 - metallic; - vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term - float Ems = 1.0 - (vScaleBias.x + vScaleBias.y); - vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0); - vec3 AvgEms = avg * Ems; - vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms); - vec3 kDiffuse = c_diff * (1.0 - FssEssLambert + FmsEms); -#if PBR_USE_IBL - colorDiffuse += (FmsEms + kDiffuse) * irradiance; -#endif + vec3 specularColor = mix(f0, baseColor.rgb, metallic); - colorDiffuse *= ao; - colorSpec *= ao; + vec3 v = -normalize(pos.xyz); + float NdotV = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0); - // Sun/Moon Lighting - if (nl > 0.0 || nv > 0.0) - { - float scale = 4.9; - vec3 sunColor = srgb_to_linear(sunlit * scale); // NOTE: Midday should have strong sunlight - - // scol = sun shadow - vec3 intensity = ambocc * sunColor * nl * scol; - vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#if PBR_USE_SUN - colorDiffuse += sunDiffuse; - colorSpec += sunSpec; -#endif - } - vec3 col = colorDiffuse + colorEmissive + colorSpec; + color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness); + color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, v, light_dir) * sunlit*8.0 * scol; + color += colorEmissive; + vec3 light = vec3(0); // Punctual lights -#define LIGHT_LOOP(i) light += srgb_to_linear(vec3(scol)) * calcPointLightOrSpotLight( reflect0, c_diff, srgb_to_linear(2.2*light_diffuse[i].rgb), albedo.rgb, pos.xyz, n, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w ); +#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w); LIGHT_LOOP(1) LIGHT_LOOP(2) @@ -323,42 +243,12 @@ irradiance = vec3(amblit); LIGHT_LOOP(6) LIGHT_LOOP(7) -#if !defined(LOCAL_LIGHT_KILL) - col += light; -#endif // !defined(LOCAL_LIGHT_KILL) + color.rgb += light.rgb; -#if DEBUG_PBR_LIGHT_TYPE - col.rgb = vec3(0.75); - emissive = vec3(0); - spec.rgb = vec3(0); -#endif -#if DEBUG_BASIC - col.rgb = vec3( 1, 0, 1 ); -#endif -#if DEBUG_VERTEX - col.rgb = vertex_color.rgb; -#endif -#if DEBUG_NORMAL_MAP - col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb; -#endif -#if DEBUG_NORMAL_OUT - col.rgb = vary_normal; -#endif -#if DEBUG_ORM - col.rgb = linear_to_srgb(spec); -#endif -#if DEBUG_POSITION - col.rgb = vary_position.xyz; -#endif + color.rgb = linear_to_srgb(color.rgb); + color *= atten.r; + color += 2.0*additive; + color = scaleSoftClipFrag(color); -// col.rgb = linear_to_srgb(col.rgb); -// frag_color = vec4(albedo.rgb,albedo.a); -// frag_color = vec4(base.rgb,albedo.a); -// frag_color = vec4(irradiance,albedo.a); -// frag_color = vec4(colorDiffuse,albedo.a); -// frag_color = vec4(colorEmissive,albedo.a); -// frag_color = vec4(sun_dir,albedo.a); -// frag_color = vec4(sunlit,albedo.a); - col = linear_to_srgb(col.rgb); - frag_color = vec4(col,albedo.a); + frag_color = vec4(color,albedo.a * vertex_color.a); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl index e0672f09e4..b3880ab178 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl @@ -54,29 +54,20 @@ uniform float near_clip; ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 normal; -ATTRIBUTE vec2 texcoord0; - - -#ifdef HAS_NORMAL_MAP ATTRIBUTE vec4 tangent; +ATTRIBUTE vec2 texcoord0; ATTRIBUTE vec2 texcoord1; +ATTRIBUTE vec2 texcoord2; -VARYING vec3 vary_mat0; -VARYING vec3 vary_mat1; -VARYING vec3 vary_mat2; +VARYING vec4 vertex_color; +VARYING vec2 vary_texcoord0; VARYING vec2 vary_texcoord1; -#else +VARYING vec2 vary_texcoord2; VARYING vec3 vary_normal; -#endif +VARYING vec3 vary_tangent; +flat out float vary_sign; -#ifdef HAS_SPECULAR_MAP -ATTRIBUTE vec2 texcoord2; -VARYING vec2 vary_texcoord2; -#endif - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; void main() { @@ -94,46 +85,26 @@ void main() #endif gl_Position = vert; -#if HAS_SHADOW +#ifdef HAS_SHADOW vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip); #endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - -#ifdef HAS_NORMAL_MAP vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; -#endif - -#ifdef HAS_SPECULAR_MAP vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; -#endif #ifdef HAS_SKIN - vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); - #ifdef HAS_NORMAL_MAP - vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); - vec3 b = cross(n, t)*tangent.w; - - vary_mat0 = vec3(t.x, b.x, n.x); - vary_mat1 = vec3(t.y, b.y, n.y); - vary_mat2 = vec3(t.z, b.z, n.z); - #else //HAS_NORMAL_MAP - vary_normal = n; - #endif //HAS_NORMAL_MAP + vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; + vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz; #else //HAS_SKIN - vec3 n = normalize(normal_matrix * normal); - #ifdef HAS_NORMAL_MAP - vec3 t = normalize(normal_matrix * tangent.xyz); - vec3 b = cross(n,t)*tangent.w; - - vary_mat0 = vec3(t.x, b.x, n.x); - vary_mat1 = vec3(t.y, b.y, n.y); - vary_mat2 = vec3(t.z, b.z, n.z); - #else //HAS_NORMAL_MAP - vary_normal = n; - #endif //HAS_NORMAL_MAP + vec3 n = normal_matrix * normal; + vec3 t = normal_matrix * tangent.xyz; #endif //HAS_SKIN - + + vary_tangent = normalize(t); + vary_sign = tangent.w; + vary_normal = normalize(n); + vertex_color = diffuse_color; #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index 69019667de..ea28cca0cb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -25,60 +25,34 @@ /*[EXTRA_CODE_HERE]*/ -#define DEBUG_PBR_LIGHT_TYPE 0 // Output Diffuse=0.75, Emissive=0, ORM=0,0,0 - -#define DEBUG_BASIC 0 -#define DEBUG_VERTEX 0 -#define DEBUG_NORMAL_MAP 0 // Output packed normal map "as is" to diffuse -#define DEBUG_NORMAL_OUT 0 // Output unpacked normal to diffuse -#define DEBUG_ORM 0 // Output Occlusion Roughness Metal "as is" to diffuse -#define DEBUG_POSITION 0 - uniform sampler2D diffuseMap; //always in sRGB space uniform float metallicFactor; uniform float roughnessFactor; uniform vec3 emissiveColor; +uniform sampler2D bumpMap; +uniform sampler2D emissiveMap; +uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness -#ifdef HAS_NORMAL_MAP - uniform sampler2D bumpMap; - VARYING vec3 vary_tangent; - flat in float vary_sign; -#endif - -#ifdef HAS_EMISSIVE_MAP - uniform sampler2D emissiveMap; -#endif - -#ifdef HAS_SPECULAR_MAP - uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness -#endif - -uniform samplerCube environmentMap; -uniform mat3 env_mat; - -#ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[4]; -#else -#define frag_data gl_FragData -#endif VARYING vec3 vary_position; VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -#ifdef HAS_NORMAL_MAP VARYING vec3 vary_normal; -VARYING vec2 vary_texcoord1; -#endif +VARYING vec3 vary_tangent; +flat in float vary_sign; -#ifdef HAS_SPECULAR_MAP - VARYING vec2 vary_texcoord2; -#endif +VARYING vec2 vary_texcoord0; +VARYING vec2 vary_texcoord1; +VARYING vec2 vary_texcoord2; uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() vec2 encode_normal(vec3 n); vec3 linear_to_srgb(vec3 c); +vec3 srgb_to_linear(vec3 c); + +uniform mat3 normal_matrix; void main() { @@ -91,14 +65,14 @@ void main() discard; } - vec3 col = vertex_color.rgb * albedo.rgb; + vec3 col = vertex_color.rgb * srgb_to_linear(albedo.rgb); // from mikktspace.com - vec4 vNt = texture2D(bumpMap, vary_texcoord1.xy)*2.0-1.0; + vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0; float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; - + vec3 vB = sign * cross(vN, vT); vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN ); @@ -107,52 +81,25 @@ void main() // occlusion 1.0 // roughness 0.0 // metal 0.0 -#ifdef HAS_SPECULAR_MAP vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb; -#else - vec3 spec = vec3(1,0,0); -#endif spec.g *= roughnessFactor; spec.b *= metallicFactor; vec3 emissive = emissiveColor; -#ifdef HAS_EMISSIVE_MAP - emissive *= texture2D(emissiveMap, vary_texcoord0.xy).rgb; -#endif - -#if DEBUG_PBR_LIGHT_TYPE - col.rgb = vec3(0.75); - emissive = vec3(0); - spec.rgb = vec3(0); -#endif -#if DEBUG_BASIC - col.rgb = vec3( 1, 0, 1 ); -#endif -#if DEBUG_VERTEX - col.rgb = vertex_color.rgb; -#endif -#if DEBUG_NORMAL_MAP - col.rgb = texture2D(bumpMap, vary_texcoord1.xy).rgb; -#endif -#if DEBUG_NORMAL_OUT - col.rgb = vary_normal; -#endif -#if DEBUG_ORM - col.rgb = linear_to_srgb(spec); -#endif -#if DEBUG_POSITION - col.rgb = vary_position.xyz; -#endif + emissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb); tnorm *= gl_FrontFacing ? 1.0 : -1.0; + //spec.rgb = vec3(1,1,0); //col = vec3(0,0,0); //emissive = vary_tangent.xyz*0.5+0.5; - //emissive = vec3(vary_sign*0.5+0.5); + //emissive = vec3(sign*0.5+0.5); + //emissive = vNt * 0.5 + 0.5; + //emissive = tnorm*0.5+0.5; // See: C++: addDeferredAttachments(), GLSL: softenLightF - frag_data[0] = vec4(col, 0.0); // Diffuse - frag_data[1] = vec4(emissive, vertex_color.a); // PBR sRGB Emissive + frag_data[0] = vec4(linear_to_srgb(col), 0.0); // Diffuse + frag_data[1] = vec4(linear_to_srgb(emissive), vertex_color.a); // PBR sRGB Emissive frag_data[2] = vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR); // normal, environment intensity, flags frag_data[3] = vec4(spec.rgb,0); // PBR linear packed Occlusion, Roughness, Metal. } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index e17d91af38..5573c02a60 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -37,41 +37,24 @@ uniform mat3 normal_matrix; uniform mat4 modelview_projection_matrix; #endif -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - -#if !defined(HAS_SKIN) -uniform mat4 modelview_matrix; -#endif - -VARYING vec3 vary_position; - -#endif - uniform mat4 texture_matrix0; ATTRIBUTE vec3 position; ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec3 normal; -ATTRIBUTE vec2 texcoord0; - - -#ifdef HAS_NORMAL_MAP ATTRIBUTE vec4 tangent; +ATTRIBUTE vec2 texcoord0; ATTRIBUTE vec2 texcoord1; +ATTRIBUTE vec2 texcoord2; +VARYING vec2 vary_texcoord0; VARYING vec2 vary_texcoord1; -#endif - -#ifdef HAS_SPECULAR_MAP -ATTRIBUTE vec2 texcoord2; VARYING vec2 vary_texcoord2; -#endif VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; + VARYING vec3 vary_tangent; flat out float vary_sign; - VARYING vec3 vary_normal; void main() @@ -83,64 +66,27 @@ void main() vec3 pos = (mat*vec4(position.xyz,1.0)).xyz; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) - vary_position = pos; -#endif - gl_Position = projection_matrix*vec4(pos,1.0); #else //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - #endif vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - -#ifdef HAS_NORMAL_MAP vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; -#endif - -#ifdef HAS_SPECULAR_MAP vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; -#endif - #ifdef HAS_SKIN - vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz); -#ifdef HAS_NORMAL_MAP - vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz); - vec3 b = cross(n, t)*tangent.w; - - //vary_mat0 = vec3(t.x, b.x, n.x); - //vary_mat1 = vec3(t.y, b.y, n.y); - //vary_mat2 = vec3(t.z, b.z, n.z); -#else //HAS_NORMAL_MAP -vary_normal = n; -#endif //HAS_NORMAL_MAP + vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; + vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz; #else //HAS_SKIN - vec3 n = normalize(normal_matrix * normal); -#ifdef HAS_NORMAL_MAP - vec3 t = normalize(normal_matrix * tangent.xyz); - vary_tangent = t; - vary_sign = tangent.w; - vary_normal = n; + vec3 n = normal_matrix * normal; + vec3 t = normal_matrix * tangent.xyz; +#endif - //vec3 b = cross(n,t)*tangent.w; - //vec3 t = cross(b,n) * binormal.w; - - //vary_mat0 = vec3(t.x, b.x, n.x); - //vary_mat1 = vec3(t.y, b.y, n.y); - //vary_mat2 = vec3(t.z, b.z, n.z); -#else //HAS_NORMAL_MAP - vary_normal = n; -#endif //HAS_NORMAL_MAP -#endif //HAS_SKIN + vary_tangent = normalize(t); + vary_sign = tangent.w; + vary_normal = normalize(n); vertex_color = diffuse_color; - -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND) -#if !defined(HAS_SKIN) - vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz; -#endif -#endif } diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl index 4681fa1abd..63e2fce40f 100644 --- a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl @@ -38,63 +38,190 @@ uniform int sourceIdx; VARYING vec3 vary_dir; -// ============================================================================================================= -// Parts of this file are (c) 2018 Sascha Willems -// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/irradiancecube.frag -/* -MIT License -Copyright (c) 2018 Sascha Willems +// Code below is derived from the Khronos GLTF Sample viewer: +// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/shaders/ibl_filtering.frag -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. +#define MATH_PI 3.1415926535897932384626433832795 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -// ============================================================================================================= +float u_roughness = 1.0; +int u_sampleCount = 16; +float u_lodBias = 2.0; +int u_width = 64; +// Hammersley Points on the Hemisphere +// CC BY 3.0 (Holger Dammertz) +// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html +// with adapted interface +float radicalInverse_VdC(uint bits) +{ + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return float(bits) * 2.3283064365386963e-10; // / 0x100000000 +} + +// hammersley2d describes a sequence of points in the 2d unit square [0,1)^2 +// that can be used for quasi Monte Carlo integration +vec2 hammersley2d(int i, int N) { + return vec2(float(i)/float(N), radicalInverse_VdC(uint(i))); +} + +// Hemisphere Sample + +// TBN generates a tangent bitangent normal coordinate frame from the normal +// (the normal must be normalized) +mat3 generateTBN(vec3 normal) +{ + vec3 bitangent = vec3(0.0, 1.0, 0.0); + + float NdotUp = dot(normal, vec3(0.0, 1.0, 0.0)); + float epsilon = 0.0000001; + /*if (1.0 - abs(NdotUp) <= epsilon) + { + // Sampling +Y or -Y, so we need a more robust bitangent. + if (NdotUp > 0.0) + { + bitangent = vec3(0.0, 0.0, 1.0); + } + else + { + bitangent = vec3(0.0, 0.0, -1.0); + } + }*/ + + vec3 tangent = normalize(cross(bitangent, normal)); + bitangent = cross(normal, tangent); + + return mat3(tangent, bitangent, normal); +} + +struct MicrofacetDistributionSample +{ + float pdf; + float cosTheta; + float sinTheta; + float phi; +}; + +MicrofacetDistributionSample Lambertian(vec2 xi, float roughness) +{ + MicrofacetDistributionSample lambertian; + + // Cosine weighted hemisphere sampling + // http://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/2D_Sampling_with_Multidimensional_Transformations.html#Cosine-WeightedHemisphereSampling + lambertian.cosTheta = sqrt(1.0 - xi.y); + lambertian.sinTheta = sqrt(xi.y); // equivalent to `sqrt(1.0 - cosTheta*cosTheta)`; + lambertian.phi = 2.0 * MATH_PI * xi.x; + + lambertian.pdf = lambertian.cosTheta / MATH_PI; // evaluation for solid angle, therefore drop the sinTheta + + return lambertian; +} + + +// getImportanceSample returns an importance sample direction with pdf in the .w component +vec4 getImportanceSample(int sampleIndex, vec3 N, float roughness) +{ + // generate a quasi monte carlo point in the unit square [0.1)^2 + vec2 xi = hammersley2d(sampleIndex, u_sampleCount); + + MicrofacetDistributionSample importanceSample; + + // generate the points on the hemisphere with a fitting mapping for + // the distribution (e.g. lambertian uses a cosine importance) + importanceSample = Lambertian(xi, roughness); + + // transform the hemisphere sample to the normal coordinate frame + // i.e. rotate the hemisphere to the normal direction + vec3 localSpaceDirection = normalize(vec3( + importanceSample.sinTheta * cos(importanceSample.phi), + importanceSample.sinTheta * sin(importanceSample.phi), + importanceSample.cosTheta + )); + mat3 TBN = generateTBN(N); + vec3 direction = TBN * localSpaceDirection; + + return vec4(direction, importanceSample.pdf); +} + +// Mipmap Filtered Samples (GPU Gems 3, 20.4) +// https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling +// https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf +float computeLod(float pdf) +{ + // // Solid angle of current sample -- bigger for less likely samples + // float omegaS = 1.0 / (float(u_sampleCount) * pdf); + // // Solid angle of texel + // // note: the factor of 4.0 * MATH_PI + // float omegaP = 4.0 * MATH_PI / (6.0 * float(u_width) * float(u_width)); + // // Mip level is determined by the ratio of our sample's solid angle to a texel's solid angle + // // note that 0.5 * log2 is equivalent to log4 + // float lod = 0.5 * log2(omegaS / omegaP); + + // babylon introduces a factor of K (=4) to the solid angle ratio + // this helps to avoid undersampling the environment map + // this does not appear in the original formulation by Jaroslav Krivanek and Mark Colbert + // log4(4) == 1 + // lod += 1.0; + + // We achieved good results by using the original formulation from Krivanek & Colbert adapted to cubemaps + // https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf + float lod = 0.5 * log2( 6.0 * float(u_width) * float(u_width) / (float(u_sampleCount) * pdf)); + + + return lod; +} + +vec3 filterColor(vec3 N) +{ + //return textureLod(uCubeMap, N, 3.0).rgb; + vec3 color = vec3(0.f); + float weight = 0.0f; -#define PI 3.1415926535897932384626433832795 + for(int i = 0; i < u_sampleCount; ++i) + { + vec4 importanceSample = getImportanceSample(i, N, 1.0); + vec3 H = vec3(importanceSample.xyz); + float pdf = importanceSample.w; + + // mipmap filtered samples (GPU Gems 3, 20.4) + float lod = computeLod(pdf); + + // apply the bias to the lod + lod += u_lodBias; + + lod = clamp(lod, 0, 7); + // sample lambertian at a lower resolution to avoid fireflies + vec3 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod).rgb; + + color += lambertian; + } + + if(weight != 0.0f) + { + color /= weight; + } + else + { + color /= float(u_sampleCount); + } + + return color.rgb ; +} + +// entry point void main() { - float deltaPhi = (2.0 * PI) / 11.25; - float deltaTheta = (0.5 * PI) / 4.0; - float mipLevel = 2; - - vec3 N = normalize(vary_dir); - vec3 up = vec3(0.0, 1.0, 0.0); - vec3 right = normalize(cross(up, N)); - up = normalize(cross(N, right)); - - const float TWO_PI = PI * 2.0; - const float HALF_PI = PI * 0.5; - - vec3 color = vec3(0.0); - uint sampleCount = 0u; - for (float phi = 0.0; phi < TWO_PI; phi += deltaPhi) { - for (float theta = 0.0; theta < HALF_PI; theta += deltaTheta) { - vec3 tempVec = cos(phi) * right + sin(phi) * up; - vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec; - color += textureLod(reflectionProbes, vec4(sampleVector, sourceIdx), mipLevel).rgb * cos(theta) * sin(theta); - sampleCount++; - } - } - frag_color = vec4(PI * color / float(sampleCount), 1.0); + vec3 color = vec3(0); + + color = filterColor(vary_dir); + + frag_color = vec4(color,1.0); } -// ============================================================================================================= diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index 94fedce243..7c175eab5f 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -66,7 +66,7 @@ SOFTWARE. // ============================================================================================================= -uniform float roughness; +//uniform float roughness; uniform float mipLevel; @@ -123,14 +123,18 @@ float D_GGX(float dotNH, float roughness) return (alpha2)/(PI * denom*denom); } -vec3 prefilterEnvMap(vec3 R, float roughness) +vec3 prefilterEnvMap(vec3 R) { vec3 N = R; vec3 V = R; vec3 color = vec3(0.0); float totalWeight = 0.0; float envMapDim = 256.0; - int numSamples = 32/max(int(mipLevel), 1); + int numSamples = 8; + + float numMips = 7.0; + + float roughness = (mipLevel+1)/numMips; for(uint i = 0u; i < numSamples; i++) { vec2 Xi = hammersley2d(i, numSamples); @@ -150,8 +154,9 @@ vec3 prefilterEnvMap(vec3 R, float roughness) // Solid angle of 1 pixel across all cube faces float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); // Biased (+1.0) mip level for better result - //float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); - color += textureLod(reflectionProbes, vec4(L,sourceIdx), mipLevel).rgb * dotNL; + //float mip = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f); + float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f); + color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip).rgb * dotNL; totalWeight += dotNL; } @@ -162,7 +167,7 @@ vec3 prefilterEnvMap(vec3 R, float roughness) void main() { vec3 N = normalize(vary_dir); - frag_color = vec4(prefilterEnvMap(N, roughness), 1.0); + frag_color = vec4(prefilterEnvMap(N), 1.0); } // ============================================================================================================= diff --git a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl index ea687aab4f..e8452a9c14 100644 --- a/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl @@ -39,6 +39,7 @@ VARYING vec2 vary_texcoord0; void main() { +#if 0 float w[9]; float c = 1.0/16.0; //corner weight @@ -72,4 +73,7 @@ void main() //color /= wsum; frag_color = vec4(color, 1.0); +#else + frag_color = vec4(texture2DRect(screenMap, vary_texcoord0.xy).rgb, 1.0); +#endif } diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl index c7c241b76e..2ee439f61a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl @@ -27,11 +27,6 @@ /*[EXTRA_CODE_HERE]*/ -#define DEBUG_ANY_LIGHT_TYPE 0 // Output red light cone -#define DEBUG_PBR_LIGHT_TYPE 0 // Output PBR objects in red -#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in red -#define DEBUG_POINT_ZERO 0 // Output zero for point lights - #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else @@ -57,20 +52,24 @@ uniform mat4 inv_proj; VARYING vec4 vary_fragcoord; -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); float calcLegacyDistanceAttenuation(float distance, float falloff); -vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance); vec4 getPosition(vec2 pos_screen); vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity); vec2 getScreenXY(vec4 clip); -void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); vec3 srgb_to_linear(vec3 c); // Util vec3 hue_to_rgb(float hue); +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 v, // surface point to camera + vec3 l); //surface point to light + + void main() { #if defined(LOCAL_LIGHT_KILL) @@ -92,41 +91,43 @@ void main() vec3 diffuse = texture2DRect(diffuseRect, tc).rgb; vec3 h, l, v = -normalize(pos); - float nh, nl, nv, vh, lightDist; + float nh, nv, vh, lightDist; if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) { - vec3 colorDiffuse = vec3(0); - vec3 colorSpec = vec3(0); vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl - vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl + vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space + float perceptualRoughness = orm.g; + float metallic = orm.b; + vec3 f0 = vec3(0.04); + vec3 baseColor = diffuse.rgb; + + vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0); + diffuseColor *= 1.0 - metallic; - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); + vec3 specularColor = mix(f0, baseColor.rgb, metallic); for (int light_idx = 0; light_idx < LIGHT_COUNT; ++light_idx) { vec3 lightColor = light_col[ light_idx ].rgb; // Already in linear, see pipeline.cpp: volume->getLightLinearColor(); float falloff = light_col[ light_idx ].a; - float lightSize = light [ light_idx ].w; - vec3 lv =(light [ light_idx ].xyz - pos); - calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist); + float lightSize = light[ light_idx ].w; + vec3 lv = light[ light_idx ].xyz - pos; + + lightDist = length(lv); float dist = lightDist / lightSize; - if (dist <= 1.0 && nl > 0.0) + if (dist <= 1.0) { + lv /= lightDist; + float dist_atten = calcLegacyDistanceAttenuation(dist, falloff); - vec3 intensity = dist_atten * nl * lightColor; - colorDiffuse += intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); + + vec3 intensity = dist_atten * lightColor * 3.0; + + final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv); } } - - #if DEBUG_PBR_LIGHT_TYPE - colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0); - #endif - final_color = colorDiffuse + colorSpec; } else { @@ -174,18 +175,8 @@ void main() } } } - #if DEBUG_LEG_LIGHT_TYPE - final_color.rgb = vec3(0.5,0,0.0); - #endif } -#if DEBUG_POINT_ZERO - final_color = vec3(0); -#endif -#if DEBUG_ANY_LIGHT_TYPE - final_color = vec3(0.3333,0,0); -#endif - frag_color.rgb = final_color; frag_color.a = 0.0; #endif // LOCAL_LIGHT_KILL diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl index bc4b4eb7e1..6424e18079 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl @@ -28,40 +28,6 @@ /*[EXTRA_CODE_HERE]*/ -#define DEBUG_ANY_LIGHT_TYPE 0 // Output blue light cone -#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in blue -#define DEBUG_PBR_LIGHT_TYPE 0 // Ouput gray if PBR multiSpot lights object -#define DEBUG_PBR_SPOT 0 -#define DEBUG_PBR_SPOT_DIFFUSE 0 // PBR diffuse lit -#define DEBUG_PBR_SPOT_SPECULAR 0 // PBR spec lit - -#define DEBUG_LIGHT_FRUSTUM 0 // If projected light effects a surface -#define DEBUG_AMBIANCE_COLOR 0 // calculated ambiance color -#define DEBUG_AMBIANCE_AOE 0 // area of effect using inverse ambiance color -#define DEBUG_AMBIANCE_FINAL 0 // light color * ambiance color -#define DEBUG_NOISE 0 // monochrome noise -#define DEBUG_SHADOW 0 // Show inverted shadow -#define DEBUG_SPOT_DIFFUSE 0 // dot(n,l) * dist_atten -#define DEBUG_SPOT_NL 0 // monochome area effected by light -#define DEBUG_SPOT_SPEC_POS 0 -#define DEBUG_SPOT_REFLECTION 0 // color: pos reflected along n -#define DEBUG_SPOT_ZERO 0 // Output zero for spotlight - -#define DEBUG_PBR_LIGHT_H 0 // Half vector -#define DEBUG_PBR_LIHGT_L 0 // Light vector -#define DEBUG_PBR_LIGHT_NH 0 // colorized dot(n,h) -#define DEBUG_PBR_LIGHT_NL 0 // colorized dot(n,l) -#define DEBUG_PBR_LIGHT_NV 0 // colorized dot(n,v) -#define DEBUG_PBR_LIGHT_VH 0 // colorized dot(v,h) -#define DEBUG_PBR_LIGHT_DIFFUSE_COLOR 0 // non PBR spotlight -#define DEBUG_PBR_LIGHT_SPECULAR_COLOR 0 // non PBR spotlight -#define DEBUG_PBR_LIGHT_INTENSITY 0 // Light intensity -#define DEBUG_PBR_LIGHT_INTENSITY_NL 0 // Light intensity * dot(n,l) -#define DEBUG_PBR_LIGHT_BRDF_DIFFUSE 0 // like "fullbright" if no "nl" factor -#define DEBUG_PBR_LIGHT_BRDF_SPECULAR 0 -#define DEBUG_PBR_LIGHT_BRDF_FINAL 0 // BRDF Diffuse + BRDF Specular - - #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else @@ -107,19 +73,15 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); float calcLegacyDistanceAttenuation(float distance, float falloff); vec3 colorized_dot(float x); bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc ); -vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v); vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity); vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv); vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv ); vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n); vec2 getScreenXY(vec4 clip); -void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); vec3 srgb_to_linear(vec3 cs); vec4 texture2DLodSpecular(vec2 tc, float lod); @@ -127,6 +89,13 @@ vec4 getPosition(vec2 pos_screen); const float M_PI = 3.14159265; +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 v, // surface point to camera + vec3 l); //surface point to light + void main() { #if defined(LOCAL_LIGHT_KILL) @@ -178,11 +147,17 @@ void main() if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) { - vec3 colorDiffuse = vec3(0); - vec3 colorSpec = vec3(0); vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl - vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl - float metal = packedORM.b; + vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space + float perceptualRoughness = orm.g; + float metallic = orm.b; + vec3 f0 = vec3(0.04); + vec3 baseColor = diffuse.rgb; + + vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0); + diffuseColor *= 1.0 - metallic; + + vec3 specularColor = mix(f0, baseColor.rgb, metallic); // We need this additional test inside a light's frustum since a spotlight's ambiance can be applied if (proj_tc.x > 0.0 && proj_tc.x < 1.0 @@ -194,111 +169,16 @@ void main() if (nl > 0.0) { amb_da += (nl*0.5 + 0.5) * proj_ambiance; - lit = nl * dist_atten; - - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - + dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy ); - slit = getProjectedLightSpecularColor( pos, n ); - - float exposure = M_PI; - dlit *= exposure; - slit *= exposure; - - colorDiffuse = shadow * lit * dlit * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh ); - colorSpec = shadow * lit * slit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh ); - colorSpec += shadow * lit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh ); - - #if DEBUG_PBR_SPOT_DIFFUSE - colorDiffuse = dlit.rgb; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SPOT_SPECULAR - colorDiffuse = vec3(0); colorSpec = slit.rgb; - #endif - #if DEBUG_PBR_SPOT - colorDiffuse = dlit; colorSpec = vec3(0); - colorDiffuse *= nl; - colorDiffuse *= shadow; - #endif + + vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation + final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv)); } amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy ); - colorDiffuse += diffuse.rgb * amb_rgb; - - #if DEBUG_AMBIANCE_FINAL - colorDiffuse = diffuse.rgb * amb_rgb; colorSpec = vec3(0); - #endif - #if DEBUG_LIGHT_FRUSTUM - colorDiffuse = vec3(0,1,0); colorSpec = vec3(0); - #endif - #if DEBUG_NOISE - float noise = texture2D(noiseMap, tc/128.0).b; - colorDiffuse = vec3(noise); colorSpec = vec3(0); - #endif + final_color += diffuse.rgb * amb_rgb; } - - #if DEBUG_PBR_LIGHT_TYPE - colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0); - #endif - - #if DEBUG_PBR_LIGHT_H - colorDiffuse = h*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_LIHGT_L - colorDiffuse = l*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_LIGHT_NH - colorDiffuse = colorized_dot(nh); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_LIGHT_NL - colorDiffuse = colorized_dot(nl); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_LIGHT_NV - colorDiffuse = colorized_dot(nv); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_LIGHT_VH - colorDiffuse = colorized_dot(vh); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_LIGHT_DIFFUSE_COLOR - colorDiffuse = dlit; - #endif - #if DEBUG_PBR_LIGHT_SPECULAR_COLOR - colorDiffuse = slit; - #endif - #if DEBUG_PBR_LIGHT_INTENSITY - colorDiffuse = getLightIntensitySpot( color, size, lightDist, v ); colorSpec = vec3(0); -// colorDiffuse = nl * dist_atten; - #endif - #if DEBUG_PBR_LIGHT_INTENSITY_NL - colorDiffuse = getLightIntensitySpot( color, size, lightDist, v ) * nl; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_LIGHT_BRDF_DIFFUSE - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - - colorDiffuse = BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh ); - colorSpec = vec3(0); - #endif - #if DEBUG_PBR_LIGHT_BRDF_SPECULAR - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - - colorDiffuse = vec3(0); - colorSpec = BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh ); - #endif - #if DEBUG_PBR_LIGHT_BRDF_FINAL - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - colorDiffuse = nl * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh ); - colorSpec = nl * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh ); - #endif - - final_color = colorDiffuse + colorSpec; } else { @@ -326,9 +206,6 @@ void main() amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, noise, proj_tc.xy ); final_color += diffuse.rgb * amb_rgb; -#if DEBUG_LEG_LIGHT_TYPE - final_color = vec3(0,0,0.5); -#endif } if (spec.a > 0.0) @@ -376,58 +253,8 @@ void main() } } } - #if DEBUG_SPOT_REFLECTION - final_color = ref; - #endif - } - -#if DEBUG_LIGHT_FRUSTUM - if (proj_tc.x > 0.0 && proj_tc.x < 1.0 - && proj_tc.y > 0.0 && proj_tc.y < 1.0) - { - final_color = vec3(0,0,1); } -#endif - } - -#if DEBUG_AMBIANCE_AOE - if (proj_tc.x > 0.0 && proj_tc.x < 1.0 - && proj_tc.y > 0.0 && proj_tc.y < 1.0) - { - final_color = 1.0 - amb_rgb; } -#endif -#if DEBUG_AMBIANCE_COLOR - if (proj_tc.x > 0.0 && proj_tc.x < 1.0 - && proj_tc.y > 0.0 && proj_tc.y < 1.0) - { - final_color = amb_rgb; - } -#endif -#if DEBUG_SHADOW - final_color = 1.0 - vec3(shadow); -#endif -#if DEBUG_SPOT_DIFFUSE - final_color = vec3(nl * dist_atten); -#endif -#if DEBUG_SPOT_NL - final_color =vec3(nl); -#endif -#if DEBUG_SPOT_SPEC_POS - vec3 ref = reflect(normalize(pos), n); - vec3 pdelta = proj_p-pos; - float ds = dot(ref, proj_n); - final_color = pos + ref * dot(pdelta, proj_n)/ds; -#endif -#if DEBUG_SPOT_REFLECTION - final_color = reflect(normalize(pos), n); -#endif -#if DEBUG_SPOT_ZERO - final_color = vec3(0,0,0); -#endif -#if DEBUG_ANY_LIGHT_TYPE - final_color = vec3(0,0,0.3333); -#endif //not sure why, but this line prevents MATBUG-194 final_color = max(final_color, vec3(0.0)); diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl index 6f39b0173b..27fca64ab3 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl @@ -27,11 +27,6 @@ /*[EXTRA_CODE_HERE]*/ -#define DEBUG_ANY_LIGHT_TYPE 0 // Output magenta light cone -#define DEBUG_LEG_LIGHT_TYPE 0 // Show Legacy objects in green -#define DEBUG_PBR_LIGHT_TYPE 0 // Show PBR objects in blue -#define DEBUG_POINT_ZERO 0 // Output zero for point light - #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_color; #else @@ -62,17 +57,20 @@ uniform vec2 screen_res; uniform mat4 inv_proj; uniform vec4 viewport; -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); float calcLegacyDistanceAttenuation(float distance, float falloff); -vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance); vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity); vec4 getPosition(vec2 pos_screen); vec2 getScreenXY(vec4 clip); -void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); vec3 srgb_to_linear(vec3 c); +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 v, // surface point to camera + vec3 l); //surface point to light + void main() { vec3 final_color = vec3(0); @@ -101,28 +99,20 @@ void main() if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) { - vec3 colorDiffuse = vec3(0); - vec3 colorSpec = vec3(0); vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl - vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl - float lightSize = size; - vec3 lightColor = color; // Already in linear, see pipeline.cpp: volume->getLightLinearColor(); - - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - - if (nl > 0.0) - { - vec3 intensity = dist_atten * nl * lightColor; // Legacy attenuation - colorDiffuse += intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec += intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); - } - -#if DEBUG_PBR_LIGHT_TYPE - colorDiffuse = vec3(0,0,0.5); colorSpec = vec3(0); -#endif - final_color = colorDiffuse + colorSpec; + vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space + float perceptualRoughness = orm.g; + float metallic = orm.b; + vec3 f0 = vec3(0.04); + vec3 baseColor = diffuse.rgb; + + vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0); + diffuseColor *= 1.0 - metallic; + + vec3 specularColor = mix(f0, baseColor.rgb, metallic); + + vec3 intensity = dist_atten * color * 3.0; // Legacy attenuation + final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv)); } else { @@ -156,19 +146,8 @@ void main() { discard; } - -#if DEBUG_LEG_LIGHT_TYPE - final_color.rgb = vec3(0,0.25,0); -#endif } -#if DEBUG_POINT_ZERO - final_color = vec3(0); -#endif -#if DEBUG_ANY_LIGHT_TYPE - final_color = vec3(0.25,0,0.25); -#endif - frag_color.rgb = final_color; frag_color.a = 0.0; } diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 3ff039261b..463709de9e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -364,7 +364,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, vec3 c, float r2, int i) v -= c; v = env_mat * v; { - return textureLod(irradianceProbes, vec4(v.xyz, refIndex[i].x), 0).rgb * refParams[i].x; + return texture(irradianceProbes, vec4(v.xyz, refIndex[i].x)).rgb * refParams[i].x; } } @@ -524,14 +524,14 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l vec3 pos, vec3 norm, float glossiness, float envIntensity) { // TODO - don't hard code lods - float reflection_lods = 8; + float reflection_lods = 7; preProbeSample(pos); vec3 refnormpersp = reflect(pos.xyz, norm.xyz); ambenv = sampleProbeAmbient(pos, norm); - if (glossiness > 0.0) + //if (glossiness > 0.0) { float lod = (1.0-glossiness)*reflection_lods; glossenv = sampleProbes(pos, normalize(refnormpersp), lod, 1.f); diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index d78c47a36a..a8a3b5d33f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -23,106 +23,6 @@ * $/LicenseInfo$ */ -#define PBR_USE_ATMOS 1 -#define PBR_USE_IBL 1 -#define PBR_USE_SUN 1 - -#define PBR_USE_LINEAR_ALBEDO 1 -#define PBR_USE_DEFAULT_IRRADIANCE 0 // PBR: irradiance, skins/default/textures/default_irradiance.png -#define PBR_USE_IRRADIANCE_HACK 1 - -#define DEBUG_PBR_LIGHT_TYPE 0 // Output no global light to make it easier to see pointLight and spotLight -#define DEBUG_PBR_PACK_ORM0 0 // Rough=0, Metal=0 -#define DEBUG_PBR_PACK_ORM1 0 // Rough=1, Metal=1 -#define DEBUG_PBR_TANGENT1 1 // Tangent = 1,0,0 -#define DEBUG_PBR_VERT2CAM1 0 // vertex2camera = 0,0,1 -#define DEBUG_PBR_SPECLIGHT051 0 // Force specLigh to be 0,0.5,1 - -// Pass input through "as is" -#define DEBUG_PBR_DIFFUSE_MAP 0 // Output: use diffuse in G-Buffer -#define DEBUG_PBR_EMISSIVE 0 // Output: Emissive -#define DEBUG_PBR_METAL 0 // Output: grayscale Metal map -#define DEBUG_PBR_NORMAL_MAP 0 // Output: Normal -- also need to set DEBUG_NORMAL_MAP in pbropaqueF -#define DEBUG_PBR_OCCLUSION 0 // Output: grayscale Occlusion map -#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal -#define DEBUG_PBR_ROUGH_PERCEPTUAL 0 // Output: grayscale Perceptual Roughness map -#define DEBUG_PBR_ROUGH_ALPHA 0 // Output: grayscale Alpha Roughness - -#define DEBUG_PBR_TANGENT 0 // Output: Tangent -#define DEBUG_PBR_BITANGENT 0 // Output: Bitangent -#define DEBUG_PBR_DOT_BV 0 // Output: graysacle dot(Bitangent,Vertex2Camera) -#define DEBUG_PBR_DOT_TV 0 // Output: grayscale dot(Tangent ,Vertex2Camera) - -// IBL Spec -#define DEBUG_PBR_NORMAL 0 // Output: passed in normal -#define DEBUG_PBR_V2C_RAW 0 // Output: vertex2camera -#define DEBUG_PBR_DOT_NV 0 // Output: grayscale dot(Normal ,Vertex2Camera) -#define DEBUG_PBR_BRDF_UV 0 // Output: red green BRDF UV (GGX input) -#define DEBUG_PBR_BRDF_SCALE_BIAS 0 // Output: red green BRDF Scale Bias (GGX output) -#define DEBUG_PBR_BRDF_SCALE_ONLY 0 // Output: grayscale BRDF Scale -#define DEBUG_PBR_BRDF_BIAS_ONLY 0 // Output: grayscale BRDER Bias -#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel -#define DEBUG_PBR_KSPEC 0 // Output: K spec -#define DEBUG_PBR_REFLECTION_DIR 0 // Output: reflection dir -#define DEBUG_PBR_SPEC_IBL 0 // Output: IBL specularity -#define DEBUG_PBR_SPEC_LEGACY 0 // Output: legacyenv -#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: environment reflection -#define DEBUG_PBR_FSS_ESS_GGX 0 // Output: FssEssGGX -#define DEBUG_PBR_SPEC 0 // Output: Final spec - -// IBL Diffuse -#define DEBUG_PBR_DIFFUSE_C 0 // Output: diffuse non metal mix -#define DEBUG_PBR_IRRADIANCE_RAW 0 // Output: Diffuse Irradiance pre-mix -#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance, NOTE: SSAO is factored in -#define DEBUG_PBR_FSS_ESS_LAMBERT 0 // Output: FssEssLambert -#define DEBUG_PBR_EMS 0 // Output: Ems = (1 - BRDF Scale + BRDF Bias) -#define DEBUG_PBR_EMS_AVG 0 // Output: Avg Ems -#define DEBUG_PBR_AVG 0 // Output: Avg -#define DEBUG_PBR_FMS_EMS 0 // Output: FmsEms -#define DEBUG_PBR_DIFFUSE_K 0 // Output: diffuse FssEssLambert + FmsEms -#define DEBUG_PBR_DIFFUSE_PRE_AO 0 // Output: diffuse pre AO -#define DEBUG_PBR_DIFFUSE 0 // Output: diffuse post AO - -// Atmospheric Lighting -#define DEBUG_PBR_AMBENV 0 // Output: ambient environment -#define DEBUG_PBR_AMBOCC 0 // Output: ambient occlusion -#define DEBUG_PBR_DA_RAW 0 // Output: da pre pow() -#define DEBUG_PBR_DA_POW 0 // Output: da post pow() -#define DEBUG_PBR_SUN_LIT 0 // Ouput: sunlit -#define DEBUG_PBR_SUN_CONTRIB 0 // Output: sun_contrib -#define DEBUG_PBR_SKY_ADDITIVE 0 // Output: additive -#define DEBUG_PBR_SKY_ATTEN 0 // Output: greyscale atten.r - -// Sun -#define DEBUG_PBR_SUN_FULL_BRIGHT 0 // Sunlit color = <1,1,1> -#define DEBUG_PBR_SUN_OUT_DIFFUSE 0 // Final sun diffuse : intensity * nl * diffuse -#define DEBUG_PBR_SUN_OUT_SPECULAR 0 // Final sun specular: intensity * nl * specular -#define DEBUG_PBR_SUN_LAMBERT 0 // BRDF Diffuse: Lambertian Diffuse color -#define DEBUG_PBR_SUN_LAMBERT_NL 0 // BRDF Diffuse: nl * Lambertian Diffuse color -#define DEBUG_PBR_SUN_H 0 // Half Vector -#define DEBUG_PBR_SUN_L 0 // Light Vector -#define DEBUG_PBR_SUN_V 0 // Surface to Light Vector -#define DEBUG_PBR_SUN_NH 0 // dot(n,h) -#define DEBUG_PBR_SUN_NL 0 // dot(n,l) -#define DEBUG_PBR_SUN_NV 0 // dot(n,v) -#define DEBUG_PBR_SUN_VH 0 // dot(v,h) -#define DEBUG_PBR_SUN_REFLECT0 0 // reflect0 only -#define DEBUG_PBR_SUN_SPEC_FRESNEL 0 // Fresnel -#define DEBUG_PBR_SUN_SPEC_D 0 // D(h) -#define DEBUG_PBR_SUN_SPEC_V 0 // V(l,v,h) -#define DEBUG_PBR_SUN_SPEC_DF 0 // D() * F() -#define DEBUG_PBR_SUN_SPEC_DV 0 // D() * V() -#define DEBUG_PBR_SUN_SPEC_FV 0 // F() * V() -#define DEBUG_PBR_SUN_SPEC_DFV 0 // D() * F() * V() -#define DEBUG_PBR_SUN_SPEC_NL_DFV 0 // nl * D() * F() * V() -#define DEBUG_PBR_SUN_FINAL 0 // LAMBERT_NL + BRDF() - -#define DEBUG_PBR_IOR 0 // Output: grayscale IOR -#define DEBUG_PBR_REFLECT0_BASE 0 // Output: black reflect0 default from ior -#define DEBUG_PBR_REFLECT0_MIX 0 // Output: diffuse reflect0 calculated from ior -#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance -- NOT USED -#define DEBUG_PBR_SPEC_WEIGHT 0 // Output: specWeight -#define DEBUG_PBR_V2C_REMAP 0 // Output: vertex2camera (remap [-1,1] -> [0,1]) #extension GL_ARB_texture_rectangle : enable #extension GL_ARB_shader_texture_lod : enable @@ -169,16 +69,7 @@ uniform vec2 screen_res; vec3 getNorm(vec2 pos_screen); vec4 getPositionWithDepth(vec2 pos_screen, float depth); -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); -float calcF0(float ior); -void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); - -float getAmbientClamp(); -vec2 getGGX( vec2 brdfPoint ); -void initMaterial( vec3 diffuse, vec3 packedORM, - out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten); vec3 scaleSoftClipFrag(vec3 l); vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); @@ -193,18 +84,26 @@ void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); -// Debug Utils -vec3 BRDFDiffuse(vec3 color); -vec3 colorize_dot(float x); -vec3 fresnelSchlick( vec3 reflect0, vec3 reflect90, float vh); -float D_GGX( float nh, float alphaRough ); -float V_GGX( float nl, float nv, float alphaRough ); - #ifdef WATER_FOG vec4 applyWaterFogView(vec3 pos, vec4 color); #endif -uniform vec3 view_dir; // PBR +// PBR interface +vec3 pbrIbl(vec3 diffuseColor, + vec3 specularColor, + vec3 radiance, // radiance map sample + vec3 irradiance, // irradiance map sample + float ao, // ambient occlusion factor + float nv, // normal dot view vector + float perceptualRoughness); + +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 v, // surface point to camera + vec3 l); //surface point to light + void main() { @@ -212,14 +111,11 @@ void main() float depth = texture2DRect(depthMap, tc.xy).r; vec4 pos = getPositionWithDepth(tc, depth); vec4 norm = texture2DRect(normalMap, tc); - float envIntensity = norm.z; - norm.xyz = getNorm(tc); - vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir; float light_gamma = 1.0 / 1.3; vec4 diffuse = texture2DRect(diffuseRect, tc); - vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); // NOTE: PBR sRGB Emissive + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive #if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO) vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; @@ -241,8 +137,6 @@ void main() calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true); - //vec3 amb_vec = env_mat * norm.xyz; - vec3 ambenv; vec3 glossenv; vec3 legacyenv; @@ -250,492 +144,116 @@ void main() bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR); if (hasPBR) { - // 5.22.2. material.pbrMetallicRoughness.baseColorTexture - // The first three components (RGB) MUST be encoded with the sRGB transfer function. - // - // 5.19.7. material.emissiveTexture - // This texture contains RGB components encoded with the sRGB transfer function. - // - // 5.22.5. material.pbrMetallicRoughness.metallicRoughnessTexture - // These values MUST be encoded with a linear transfer function. - - vec3 colorDiffuse = vec3(0); - vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl - vec3 colorSpec = vec3(0); -// vec3 colorClearCoat = vec3(0); -// vec3 colorSheen = vec3(0); -// vec3 colorTransmission = vec3(0); - - vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl -#if DEBUG_PBR_PACK_ORM0 - packedORM = vec3(0,0,0); -#endif -#if DEBUG_PBR_PACK_ORM1 - packedORM = vec3(1,1,1); -#endif - float IOR = 1.5; // default Index Of Refraction 1.5 (dielectrics) -#if DEBUG_PBR_REFLECT0_BASE - vec3 debug_reflect0 = vec3(calcF0(IOR)); -#endif - float ao = packedORM.r; - float metal = packedORM.b; - vec3 v = -normalize(pos.xyz); -#if DEBUG_PBR_VERT2CAM1 - v = vec3(0,0,1); -#endif - vec3 n = norm.xyz; -// vec3 t = texture2DRect(tangentMap, tc).rgb; -#if DEBUG_PBR_TANGENT1 - vec3 t = vec3(1,0,0); -#endif - vec3 b = cross( n,t); - vec3 reflectVN = normalize(reflect(-v,n)); - - vec3 h, l; - float nh, nl, nv, vh, lightDist; - calcHalfVectors(light_dir, n, v, h, l, nh, nl, nv, vh, lightDist); - - float tv = clamp(dot(t,v),0,1); - float bv = clamp(dot(b,v),0,1); - - // Reference: getMetallicRoughnessInfo -#if PBR_USE_LINEAR_ALBEDO - vec3 base = diffuse.rgb; -#else - vec3 base = linear_to_srgb(diffuse.rgb); -#endif - float perceptualRough = packedORM.g; // NOTE: do NOT clamp here to be consistent with Blender, Blender is wrong and Substance is right - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( base, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); -#if DEBUG_PBR_REFLECTANCE - float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b ); -#endif + norm.xyz = getNorm(tc); + vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space + float perceptualRoughness = orm.g; + float metallic = orm.b; + float ao = orm.r * ambocc; - // Common to RadianceGGX and RadianceLambertian - vec2 brdfPoint = clamp(vec2(nv, perceptualRough), vec2(0,0), vec2(1,1)); - vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0 - vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel - vec3 kSpec = reflect0 + fresnelR*pow(1.0 - nv, 5.0); + vec3 colorEmissive = texture2DRect(specularRect, tc).rgb; //specularRect is sRGB sampler, result is in linear space - // Reference: getIBLRadianceGGX - // https://forum.substance3d.com/index.php?topic=3243.0 - // Glossiness - // This map is the inverse of the roughness map. + // PBR IBL + float gloss = 1.0 - perceptualRoughness; vec3 irradiance = vec3(0); - vec3 specLight = vec3(0); - float gloss = 1.0 - perceptualRough; - sampleReflectionProbes(irradiance, specLight, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); -#if DEBUG_PBR_IRRADIANCE_RAW - vec3 debug_irradiance = irradiance; -#endif + vec3 radiance = vec3(0); + sampleReflectionProbes(irradiance, radiance, legacyenv, pos.xyz, norm.xyz, gloss, 0.0); + irradiance = max(srgb_to_linear(amblit),irradiance) * ambocc*4.0; -#if PBR_USE_DEFAULT_IRRADIANCE - vec2 iruv = vec2(0.5f + 0.5f * atan(reflectVN.z, reflectVN.x) / M_PI, 1.f - acos(reflectVN.y) / M_PI); - irradiance = texture2D(altDiffuseMap, iruv).rgb * ambocc; -#endif -#if PBR_USE_IRRADIANCE_HACK - irradiance = max(amblit,irradiance) * ambocc; -#endif -#if DEBUG_PBR_SPECLIGHT051 - specLight = vec3(0,0.5,1.0); - irradiance = specLight; -#endif - vec3 FssEssGGX = kSpec*vScaleBias.x + vScaleBias.y; -#if DEBUG_PBR_SPEC_IBL - vec3 debug_color_spec = specWeight * specLight * FssEssGGX; -#endif -#if PBR_USE_IBL - colorSpec += specWeight * specLight * FssEssGGX; -#endif + vec3 f0 = vec3(0.04); + vec3 baseColor = diffuse.rgb; + + //baseColor.rgb = vec3(0,0,0); + //colorEmissive = srgb_to_linear(norm.xyz*0.5+0.5); - // Reference: getIBLRadianceLambertian - vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term - float Ems = 1.0 - (vScaleBias.x + vScaleBias.y); - vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0); - vec3 AvgEms = avg * Ems; - vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms); - vec3 kDiffuse = c_diff * (1.0 - FssEssLambert + FmsEms); -#if PBR_USE_IBL - colorDiffuse += (FmsEms + kDiffuse) * irradiance; -#endif - #if DEBUG_PBR_DIFFUSE_PRE_AO - vec3 debug_diffuse = colorDiffuse; - #endif - colorDiffuse *= ao; // Occlusion -- NOTE: pbropaque will need occlusion_strength pre-multiplied into spec.r - colorSpec *= ao; + vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0); + diffuseColor *= 1.0 - metallic; - // Add in sun/moon reflection - if (nl > 0.0 || nv > 0.0) - { - float scale = 4.9; - vec3 sunColor = srgb_to_linear(sunlit * scale); // NOTE: Midday should have strong sunlight -#if DEBUG_PBR_SUN_FULL_BRIGHT - sunColor = vec3(1); -#endif - // scol = sun shadow - vec3 intensity = ambocc * sunColor * nl * scol; -#if PBR_USE_LINEAR_ALBEDO - vec3 sunDiffuse = intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#else - vec3 sunDiffuse = base * intensity * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - vec3 sunSpec = intensity * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); -#endif - // Disabling PBR bloom due to two reasons: - // 1. The glTF 2.0 Specification does not specify bloom, - // 2. As the camera moves there are lots of bloom shimmering. - //bloom = dot(sunSpec, sunSpec) / (scale * scale * scale); - - #if DEBUG_PBR_SUN_SPEC_FRESNEL - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_D - colorDiffuse = vec3(0); - colorSpec = vec3(D_GGX( nh, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_V - colorDiffuse = vec3(0); - colorSpec = vec3(V_GGX( nl, nv, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DF - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= D_GGX( nh, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DV - colorDiffuse = vec3(0); - colorSpec = vec3(D_GGX( nh, alphaRough )); - colorSpec *= vec3(V_GGX( nl, nv, alphaRough )); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_FV - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= V_GGX( nl, nv, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_DFV - colorDiffuse = vec3(0); - colorSpec = fresnelSchlick( reflect0, reflect90, vh ); - colorSpec *= D_GGX( nh, alphaRough ); - colorSpec *= V_GGX( nl, nv, alphaRough ); - bloom = 0; - #endif - #if DEBUG_PBR_SUN_SPEC_NL_DFV - colorDiffuse = vec3(0); - colorSpec = nl * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); - #endif - #if DEBUG_PBR_SUN_FINAL - colorDiffuse = nl * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = nl * BRDFSpecularGGX(reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh); - #endif - - #if DEBUG_PBR_SUN_OUT_DIFFUSE - colorDiffuse = linear_to_srgb(sunDiffuse); - colorSpec = vec3(0); - bloom = 0.0; - #endif - #if DEBUG_PBR_SUN_OUT_SPECULAR - colorDiffuse = linear_to_srgb(sunSpec); - colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_REFLECT0 - colorDiffuse = reflect0; - colorSpec = vec3(0); - #endif - -#if PBR_USE_SUN - colorDiffuse += sunDiffuse; - colorSpec += sunSpec; -#endif - } + vec3 specularColor = mix(f0, baseColor.rgb, metallic); -#if DEBUG_PBR_SUN_LAMBERT - colorDiffuse = BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = vec3(0); - bloom = 0; -#endif -#if DEBUG_PBR_SUN_LAMBERT_NL - colorDiffuse = nl * BRDFLambertian (reflect0, reflect90, c_diff , specWeight, vh); - colorSpec = vec3(0); - bloom = 0; -#endif + vec3 v = -normalize(pos.xyz); + float NdotV = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0); + + color.rgb += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness); + color.rgb += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, v, normalize(light_dir)) * sunlit*8.0 * scol; + color.rgb += colorEmissive; - #if DEBUG_PBR_SUN_H - colorDiffuse = h*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_L - colorDiffuse = l*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_V - colorDiffuse = v*0.5 + 0.5; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NH - colorDiffuse = colorize_dot(nh); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NL - colorDiffuse = colorize_dot(nl); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_NV - colorDiffuse = colorize_dot(nv); colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SUN_VH - colorDiffuse = colorize_dot(vh); colorSpec = vec3(0); - #endif - - color.rgb = colorDiffuse + colorEmissive + colorSpec; - -#if PBR_USE_ATMOS color = linear_to_srgb(color); color *= atten.r; color += 2.0*additive; color = scaleSoftClipFrag(color); color = srgb_to_linear(color); -#endif // PBR_USE_ATMOS - #if DEBUG_PBR_DIFFUSE - color.rgb = colorDiffuse; - #endif - #if DEBUG_PBR_EMISSIVE - color.rgb = colorEmissive; - #endif - #if DEBUG_PBR_METAL - color.rgb = vec3(metal); - #endif - #if DEBUG_PBR_NORMAL_MAP - color.rgb = diffuse.rgb; - #endif - #if DEBUG_PBR_OCCLUSION - color.rgb = vec3(ao); - #endif - #if DEBUG_PBR_ORM - color.rgb = packedORM; - #endif - #if DEBUG_PBR_ROUGH_PERCEPTUAL - color.rgb = vec3(perceptualRough); - #endif - #if DEBUG_PBR_ROUGH_ALPHA - color.rgb = vec3(alphaRough); - #endif - #if DEBUG_PBR_NORMAL - color.rgb = norm.xyz*0.5 + vec3(0.5); - color.rgb = srgb_to_linear(color.rgb); - #endif - #if DEBUG_PBR_TANGENT - color.rgb = t; - #endif - #if DEBUG_PBR_BITANGENT - color.rgb = b; - #endif - #if DEBUG_PBR_DOT_NV - color.rgb = vec3(nv); - #endif - #if DEBUG_PBR_DOT_TV - color.rgb = vec3(tv); - #endif - #if DEBUG_PBR_DOT_BV - color.rgb = vec3(bv); - #endif + frag_color.rgb = color.rgb; //output linear since local lights will be added to this shader's results + } + else + { + float envIntensity = norm.z; + norm.xyz = getNorm(tc); - #if DEBUG_PBR_AVG - color.rgb = avg; - #endif - #if DEBUG_PBR_BRDF_UV - color.rgb = vec3(brdfPoint,0.0); - color.rgb = linear_to_srgb(color.rgb); - #endif - #if DEBUG_PBR_BRDF_SCALE_BIAS - color.rgb = vec3(vScaleBias,0.0); - #endif - #if DEBUG_PBR_DIFFUSE_C - color.rgb = c_diff; - #endif - #if DEBUG_PBR_BRDF_SCALE_ONLY - color.rgb = vec3(vScaleBias.x); - #endif - #if DEBUG_PBR_BRDF_BIAS_ONLY - color.rgb = vec3(vScaleBias.y); - #endif - #if DEBUG_PBR_DIFFUSE_K - color.rgb = kDiffuse; - #endif - #if DEBUG_PBR_DIFFUSE_MAP - color.rgb = diffuse.rgb; - #endif - #if DEBUG_PBR_DIFFUSE_PRE_AO - color.rgb = debug_diffuse; - #endif - #if DEBUG_PBR_EMS - color.rgb = vec3(Ems); - #endif - #if DEBUG_PBR_EMS_AVG - color.rgb = AvgEms; - #endif - #if DEBUG_PBR_FMS_EMS - color.rgb = FmsEms; - #endif - #if DEBUG_PBR_FSS_ESS_GGX - color.rgb = FssEssGGX; // spec - #endif - #if DEBUG_PBR_FSS_ESS_LAMBERT - color.rgb = FssEssLambert; // diffuse - #endif - #if DEBUG_PBR_FRESNEL - color.rgb = fresnelR; - #endif - #if DEBUG_PBR_IOR - color.rgb = vec3(IOR); - #endif - #if DEBUG_PBR_IRRADIANCE_RAW - color.rgb = debug_irradiance; - bloom = 0; - #endif - #if DEBUG_PBR_IRRADIANCE - color.rgb = irradiance; - bloom = 0; - #endif - #if DEBUG_PBR_KSPEC - color.rgb = kSpec; - #endif - #if DEBUG_PBR_REFLECT0_BASE - color.rgb = vec3(debug_reflect0); - #endif - #if DEBUG_PBR_REFLECT0_MIX - color.rgb = vec3(reflect0); - #endif - #if DEBUG_PBR_REFLECTANCE - color.rgb = vec3(reflectance); - #endif - #if DEBUG_PBR_REFLECTION_DIR - color.rgb = reflect(-v, n); // NOTE: equivalent to normalize(reflect(pos.xyz, norm.xyz)); - #endif - #if DEBUG_PBR_SPEC - color.rgb = colorSpec; - #endif - #if DEBUG_PBR_SPEC_REFLECTION - color.rgb = specLight; - #endif - #if DEBUG_PBR_SPEC_WEIGHT - color.rgb = vec3(specWeight); - #endif - #if DEBUG_PBR_V2C_RAW - color.rgb = v; - #endif - #if DEBUG_PBR_V2C_REMAP - color.rgb = v*0.5 + vec3(0.5); - #endif + float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); + da = pow(da, light_gamma); - #if DEBUG_PBR_DA_RAW - color.rgb = vec3(debug_da); - #endif - #if DEBUG_PBR_DA_POW - color.rgb = vec3(da); - #endif - #if DEBUG_PBR_SKY_ADDITIVE - color.rgb = additive; - #endif - #if DEBUG_PBR_SKY_ATTEN - color.rgb = vec3(atten.r); - #endif - #if DEBUG_PBR_SUN_LIT - color.rgb = sunlit; - #endif - #if DEBUG_PBR_SUN_CONTRIB - color.rgb = sun_contrib; - #endif - #if DEBUG_PBR_LIGHT_TYPE - color.rgb = vec3(0); - #endif + diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035 - frag_color.rgb = color.rgb; // PBR is done in linear - } -else -{ - float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); -#if DEBUG_PBR_DA_RAW - float debug_da = da; -#endif - da = pow(da, light_gamma); + sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); + ambenv.rgb = linear_to_srgb(ambenv.rgb); + glossenv.rgb = linear_to_srgb(glossenv.rgb); + legacyenv.rgb = linear_to_srgb(legacyenv.rgb); - diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035 + amblit = max(ambenv, amblit); + color.rgb = amblit*ambocc; - sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); - ambenv.rgb = linear_to_srgb(ambenv.rgb); - glossenv.rgb = linear_to_srgb(glossenv.rgb); - legacyenv.rgb = linear_to_srgb(legacyenv.rgb); + vec3 sun_contrib = min(da, scol) * sunlit; + color.rgb += sun_contrib; + color.rgb = min(color.rgb, vec3(1,1,1)); + color.rgb *= diffuse.rgb; - amblit = max(ambenv, amblit); - color.rgb = amblit*ambocc; + vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - //float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0); - //ambient *= 0.5; - //ambient *= ambient; - //ambient = (1.0 - ambient); - //color.rgb *= ambient; + if (spec.a > 0.0) // specular reflection + { + float sa = dot(normalize(refnormpersp), light_dir.xyz); + vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r); - vec3 sun_contrib = min(da, scol) * sunlit; - color.rgb += sun_contrib; - color.rgb = min(color.rgb, vec3(1,1,1)); - color.rgb *= diffuse.rgb; + // add the two types of shiny together + vec3 spec_contrib = dumbshiny * spec.rgb; + bloom = dot(spec_contrib, spec_contrib) / 6; + color.rgb += spec_contrib; - vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + // add reflection map - EXPERIMENTAL WORK IN PROGRESS + applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); + } - if (spec.a > 0.0) // specular reflection - { - float sa = dot(normalize(refnormpersp), light_dir.xyz); - vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r); + color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); - // add the two types of shiny together - vec3 spec_contrib = dumbshiny * spec.rgb; - bloom = dot(spec_contrib, spec_contrib) / 6; - color.rgb += spec_contrib; + if (envIntensity > 0.0) + { // add environmentmap + //fudge darker + legacyenv *= 0.5*diffuse.a+0.5; + applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); + } - // add reflection map - EXPERIMENTAL WORK IN PROGRESS - applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz); - } + if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) + { + color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a); + color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a); + } - color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a); + #ifdef WATER_FOG + vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom)); + color = fogged.rgb; + bloom = fogged.a; + #endif - if (envIntensity > 0.0) - { // add environmentmap - //fudge darker - legacyenv *= 0.5*diffuse.a+0.5; - applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); + // convert to linear as fullscreen lights need to sum in linear colorspace + // and will be gamma (re)corrected downstream... + //color = ambenv; + //color.b = diffuse.a; + frag_color.rgb = srgb_to_linear(color.rgb); } - if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) - { - color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a); - color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a); - } -#ifdef WATER_FOG - vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom)); - color = fogged.rgb; - bloom = fogged.a; -#endif - #if DEBUG_PBR_LIGHT_TYPE - color.rgb = vec3(0); - #endif - // convert to linear as fullscreen lights need to sum in linear colorspace - // and will be gamma (re)corrected downstream... - //color = ambenv; - //color.b = diffuse.a; - frag_color.rgb = srgb_to_linear(color.rgb); -} -#if DEBUG_PBR_AMBOCC - frag_color.rgb = vec3(ambocc); -#endif -#if DEBUG_PBR_AMBENV - frag_color.rgb = ambenv; -#endif frag_color.a = bloom; } diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl index f23e9db040..c8d45eb429 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl @@ -82,18 +82,14 @@ uniform vec2 screen_res; uniform mat4 inv_proj; -vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh ); -vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh ); void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); float calcLegacyDistanceAttenuation(float distance, float falloff); bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc ); -vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v); vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity); vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv); vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv ); vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n); vec2 getScreenXY(vec4 clip_point); -void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight ); vec3 srgb_to_linear(vec3 c); vec4 texture2DLodSpecular(vec2 tc, float lod); @@ -101,6 +97,13 @@ vec4 getPosition(vec2 pos_screen); const float M_PI = 3.14159265; +vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, + float perceptualRoughness, + float metallic, + vec3 n, // normal + vec3 v, // surface point to camera + vec3 l); //surface point to light + void main() { #if defined(LOCAL_LIGHT_KILL) @@ -148,13 +151,20 @@ void main() vec3 dlit = vec3(0, 0, 0); vec3 slit = vec3(0, 0, 0); + vec3 amb_rgb = vec3(0); if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) { - vec3 colorDiffuse = vec3(0); - vec3 colorSpec = vec3(0); vec3 colorEmissive = spec.rgb; // PBR sRGB Emissive. See: pbropaqueF.glsl - vec3 packedORM = texture2DRect(emissiveRect, tc).rgb; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl - float metal = packedORM.b; + vec3 orm = texture2DRect(emissiveRect, tc).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space + float perceptualRoughness = orm.g; + float metallic = orm.b; + vec3 f0 = vec3(0.04); + vec3 baseColor = diffuse.rgb; + + vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0); + diffuseColor *= 1.0 - metallic; + + vec3 specularColor = mix(f0, baseColor.rgb, metallic); // We need this additional test inside a light's frustum since a spotlight's ambiance can be applied if (proj_tc.x > 0.0 && proj_tc.x < 1.0 @@ -166,46 +176,16 @@ void main() if (nl > 0.0) { amb_da += (nl*0.5 + 0.5) * proj_ambiance; - lit = nl * dist_atten; - - vec3 c_diff, reflect0, reflect90; - float alphaRough, specWeight; - initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight ); - + dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy ); - slit = getProjectedLightSpecularColor( pos, n ); - float exposure = M_PI; - dlit *= exposure; - slit *= exposure; - - colorDiffuse = shadow * lit * dlit * BRDFLambertian ( reflect0, reflect90, c_diff , specWeight, vh ); - colorSpec = shadow * lit * slit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh ); - colorSpec += shadow * lit * BRDFSpecularGGX( reflect0, reflect90, alphaRough, specWeight, vh, nl, nv, nh ); - - #if DEBUG_PBR_SPOT_DIFFUSE - colorDiffuse = dlit.rgb; colorSpec = vec3(0); - #endif - #if DEBUG_PBR_SPOT_SPECULAR - colorDiffuse = vec3(0); colorSpec = slit.rgb; - #endif - #if DEBUG_PBR_SPOT - colorDiffuse = dlit; colorSpec = vec3(0); - colorDiffuse *= nl; - colorDiffuse *= shadow; - #endif + vec3 intensity = dist_atten * dlit * 3.0 * shadow; // Legacy attenuation + final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv)); } - vec3 amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy ); - colorDiffuse += diffuse.rgb * amb_rgb; - + amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy ); + final_color += diffuse.rgb * amb_rgb; } - - #if DEBUG_PBR_LIGHT_TYPE - colorDiffuse = vec3(0.5,0,0); colorSpec = vec3(0.0); - #endif - - final_color = colorDiffuse + colorSpec; } else { diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 6b4ab1be17..cfee0ba529 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 36 +version 37 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -287,14 +287,10 @@ list Intel RenderAnisotropic 1 0 RenderFSAASamples 1 0 RenderGLMultiThreaded 1 0 -RenderGLContextCoreProfile 1 0 +RenderGLContextCoreProfile 1 0 -// AMD cards generally perform better when not using VBOs for streaming data -// AMD cards also prefer an OpenGL Compatibility Profile Context // HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 16 list AMD -RenderUseStreamVBO 1 0 -RenderGLContextCoreProfile 1 0 RenderReflectionProbeCount 1 16 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 311b669d7f..c224fd2a6c 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 39 +version 40 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -70,7 +70,7 @@ RenderShadowDetail 1 2 RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 -RenderGLContextCoreProfile 1 0 +RenderGLContextCoreProfile 1 1 RenderGLMultiThreaded 1 0 // diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7f6f6e5997..999f4a9f20 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -716,6 +716,9 @@ void LLAgent::moveYaw(F32 mag, bool reset_view) U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG; if ((getControlFlags() & mask) == mask) { + // Rotation into both directions should cancel out + // But keep sending controls to simulator, + // it's needed for script based controls gAgentCamera.setYawKey(0); } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d5aa980d7e..e874cf02cb 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -531,7 +531,7 @@ static void settings_to_globals() LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); - LLRender::sGLCoreProfile = TRUE; // Now required, ignoring gSavedSettings.getBOOL("RenderGLContextCoreProfile"); + LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile"); LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); @@ -1449,6 +1449,8 @@ bool LLAppViewer::doFrame() LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" ) // give listeners a chance to run llcoro::suspend(); + // if one of our coroutines threw an uncaught exception, rethrow it now + LLCoros::instance().rethrow(); } if (!LLApp::isExiting()) @@ -3275,9 +3277,18 @@ LLSD LLAppViewer::getViewerInfo() const info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : "Undefined"; if(LLVoiceClient::getInstance()->voiceEnabled()) { - LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); + LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); + const std::string build_version = version.mBuildVersion; std::ostringstream version_string; - version_string << version.serverType << " " << version.serverVersion << std::endl; + if (std::equal(build_version.begin(), build_version.begin() + version.serverVersion.size(), + version.serverVersion.begin())) + { // Normal case: Show type and build version. + version_string << version.serverType << " " << build_version << std::endl; + } + else + { // Mismatch: Show both versions. + version_string << version.serverVersion << "/" << build_version << std::endl; + } info["VOICE_VERSION"] = version_string.str(); } else @@ -4241,6 +4252,15 @@ U32 LLAppViewer::getTextureCacheVersion() } //static +U32 LLAppViewer::getDiskCacheVersion() +{ + // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes. + const U32 DISK_CACHE_VERSION = 1; + + return DISK_CACHE_VERSION ; +} + +//static U32 LLAppViewer::getObjectCacheVersion() { // Viewer object cache version, change if object update @@ -4269,12 +4289,16 @@ bool LLAppViewer::initCache() const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); bool texture_cache_mismatch = false; + bool remove_vfs_files = false; if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion()) { texture_cache_mismatch = true; if(!read_only) { gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion()); + + //texture cache version was bumped up in Simple Cache Viewer, and at this point old vfs files are not needed + remove_vfs_files = true; } } @@ -4320,7 +4344,19 @@ bool LLAppViewer::initCache() if (!read_only) { - if (mPurgeCache) + if (gSavedSettings.getS32("DiskCacheVersion") != LLAppViewer::getDiskCacheVersion()) + { + LLDiskCache::getInstance()->clearCache(); + remove_vfs_files = true; + gSavedSettings.setS32("DiskCacheVersion", LLAppViewer::getDiskCacheVersion()); + } + + if (remove_vfs_files) + { + LLDiskCache::getInstance()->removeOldVFSFiles(); + } + + if (mPurgeCache) { LLSplashScreen::update(LLTrans::getString("StartupClearingCache")); purgeCache(); @@ -5398,7 +5434,7 @@ void LLAppViewer::disconnectViewer() gFloaterView->restoreAll(); } - if (LLSelectMgr::getInstance()) + if (LLSelectMgr::instanceExists()) { LLSelectMgr::getInstance()->deselectAll(); } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 7ab21f35cd..f28a90c703 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -130,6 +130,7 @@ public: static U32 getTextureCacheVersion() ; static U32 getObjectCacheVersion() ; + static U32 getDiskCacheVersion() ; const std::string& getSerialNumber() { return mSerialNumber; } @@ -153,16 +154,16 @@ public: void removeMarkerFiles(); void removeDumpDir(); - // LLAppViewer testing helpers. - // *NOTE: These will potentially crash the viewer. Only for debugging. - virtual void forceErrorLLError(); - virtual void forceErrorBreakpoint(); - virtual void forceErrorBadMemoryAccess(); - virtual void forceErrorInfiniteLoop(); - virtual void forceErrorSoftwareException(); - virtual void forceErrorDriverCrash(); - virtual void forceErrorCoroutineCrash(); - virtual void forceErrorThreadCrash(); + // LLAppViewer testing helpers. + // *NOTE: These will potentially crash the viewer. Only for debugging. + virtual void forceErrorLLError(); + virtual void forceErrorBreakpoint(); + virtual void forceErrorBadMemoryAccess(); + virtual void forceErrorInfiniteLoop(); + virtual void forceErrorSoftwareException(); + virtual void forceErrorDriverCrash(); + virtual void forceErrorCoroutineCrash(); + virtual void forceErrorThreadCrash(); // The list is found in app_settings/settings_files.xml // but since they are used explicitly in code, diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index b0715a3afd..c0990d9d11 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -241,21 +241,6 @@ void LLAvatarList::setDirty(bool val /*= true*/, bool force_refresh /*= false*/) } } -void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name) -{ - LL_DEBUGS("Avaline") << "Adding avaline item into the list: " << item_name << "|" << item_id << ", session: " << session_id << LL_ENDL; - LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false); - item->setAvatarId(item_id, session_id, true, false); - item->setName(item_name); - item->showLastInteractionTime(mShowLastInteractionTime); - item->showSpeakingIndicator(mShowSpeakingIndicator); - item->setOnline(false); - - addItem(item, item_id); - mIDs.push_back(item_id); - sort(); -} - ////////////////////////////////////////////////////////////////////////// // PROTECTED SECTION ////////////////////////////////////////////////////////////////////////// @@ -296,18 +281,10 @@ void LLAvatarList::refresh() { // *NOTE: If you change the UI to show a different string, // be sure to change the filter code below. - if (LLRecentPeople::instance().isAvalineCaller(buddy_id)) - { - const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id); - addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString()); - } - else - { - std::string display_name = getAvatarName(av_name); - addNewItem(buddy_id, - display_name.empty() ? waiting_str : display_name, - LLAvatarTracker::instance().isBuddyOnline(buddy_id)); - } + std::string display_name = getAvatarName(av_name); + addNewItem(buddy_id, + display_name.empty() ? waiting_str : display_name, + LLAvatarTracker::instance().isBuddyOnline(buddy_id)); modified = true; nadded++; @@ -463,7 +440,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask); - if ( mContextMenu && !isAvalineItemSelected()) + if ( mContextMenu) { uuid_vec_t selected_uuids; getSelectedUUIDs(selected_uuids); @@ -523,21 +500,6 @@ BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask) return handled; } -bool LLAvatarList::isAvalineItemSelected() -{ - std::vector<LLPanel*> selected_items; - getSelectedItems(selected_items); - std::vector<LLPanel*>::iterator it = selected_items.begin(); - - for(; it != selected_items.end(); ++it) - { - if (dynamic_cast<LLAvalineListItem*>(*it)) - return true; - } - - return false; -} - void LLAvatarList::setVisible(BOOL visible) { if ( visible == FALSE && mContextMenu ) @@ -626,63 +588,3 @@ bool LLAvatarItemAgentOnTopComparator::doCompare(const LLAvatarListItem* avatar_ } return LLAvatarItemNameComparator::doCompare(avatar_item1,avatar_item2); } - -/************************************************************************/ -/* class LLAvalineListItem */ -/************************************************************************/ -LLAvalineListItem::LLAvalineListItem(bool hide_number/* = true*/) : LLAvatarListItem(false) -, mIsHideNumber(hide_number) -{ - // should not use buildPanel from the base class to ensure LLAvalineListItem::postBuild is called. - buildFromFile( "panel_avatar_list_item.xml"); -} - -BOOL LLAvalineListItem::postBuild() -{ - BOOL rv = LLAvatarListItem::postBuild(); - - if (rv) - { - setOnline(true); - showLastInteractionTime(false); - setShowProfileBtn(false); - setShowInfoBtn(false); - mAvatarIcon->setValue("Avaline_Icon"); - mAvatarIcon->setToolTip(std::string("")); - } - return rv; -} - -// to work correctly this method should be called AFTER setAvatarId for avaline callers with hidden phone number -void LLAvalineListItem::setName(const std::string& name) -{ - if (mIsHideNumber) - { - static U32 order = 0; - typedef std::map<LLUUID, U32> avaline_callers_nums_t; - static avaline_callers_nums_t mAvalineCallersNums; - - llassert(getAvatarId() != LLUUID::null); - - const LLUUID &uuid = getAvatarId(); - - if (mAvalineCallersNums.find(uuid) == mAvalineCallersNums.end()) - { - mAvalineCallersNums[uuid] = ++order; - LL_DEBUGS("Avaline") << "Set name for new avaline caller: " << uuid << ", order: " << order << LL_ENDL; - } - LLStringUtil::format_map_t args; - args["[ORDER]"] = llformat("%u", mAvalineCallersNums[uuid]); - std::string hidden_name = LLTrans::getString("AvalineCaller", args); - - LL_DEBUGS("Avaline") << "Avaline caller: " << uuid << ", name: " << hidden_name << LL_ENDL; - LLAvatarListItem::setAvatarName(hidden_name); - LLAvatarListItem::setAvatarToolTip(hidden_name); - } - else - { - const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name); - LLAvatarListItem::setAvatarName(formatted_phone); - LLAvatarListItem::setAvatarToolTip(formatted_phone); - } -} diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 1a672c279b..48b0e70454 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -98,7 +98,6 @@ public: virtual S32 notifyParent(const LLSD& info); - void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name); void handleDisplayNamesOptionChanged(); void setShowCompleteName(bool show) { mShowCompleteName = show;}; @@ -118,8 +117,6 @@ protected: private: - bool isAvalineItemSelected(); - bool mIgnoreOnlineStatus; bool mShowLastInteractionTime; bool mDirty; @@ -189,27 +186,4 @@ protected: virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const; }; -/** - * Represents Avaline caller in Avatar list in Voice Control Panel and group chats. - */ -class LLAvalineListItem : public LLAvatarListItem -{ -public: - - /** - * Constructor - * - * @param hide_number - flag indicating if number should be hidden. - * In this case It will be shown as "Avaline Caller 1", "Avaline Caller 1", etc. - */ - LLAvalineListItem(bool hide_number = true); - - /*virtual*/ BOOL postBuild(); - - /*virtual*/ void setName(const std::string& name); - -private: - bool mIsHideNumber; -}; - #endif // LL_LLAVATARLIST_H diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index fe94cd27b6..275f17b02a 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -320,9 +320,16 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio // make sure we won't re-report, coro will update timer with correct time later regionp->getRenderInfoReportTimer().resetWithExpiry(SECS_BETWEEN_REGION_REPORTS); - std::string coroname = - LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro", - boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle())); + try + { + std::string coroname = + LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro", + boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoReportCoro, url, regionp->getHandle())); + } + catch (std::bad_alloc&) + { + LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL; + } } } @@ -343,10 +350,17 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi // make sure we won't re-request, coro will update timer with correct time later regionp->getRenderInfoRequestTimer().resetWithExpiry(SECS_BETWEEN_REGION_REQUEST); - // First send a request to get the latest data - std::string coroname = - LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro", - boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle())); + try + { + // First send a request to get the latest data + std::string coroname = + LLCoros::instance().launch("LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro", + boost::bind(&LLAvatarRenderInfoAccountant::avatarRenderInfoGetCoro, url, regionp->getHandle())); + } + catch (std::bad_alloc&) + { + LL_ERRS() << "LLCoros::launch() allocation failure" << LL_ENDL; + } } } diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index bdd516e1de..7ff24f64ac 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -48,6 +48,7 @@ #include "llspeakers.h" //for LLIMSpeakerMgr #include "lltrans.h" #include "llfloaterreg.h" +#include "llfloaterreporter.h" #include "llfloatersidepanelcontainer.h" #include "llmutelist.h" #include "llstylemap.h" @@ -118,6 +119,7 @@ public: mSourceType(CHAT_SOURCE_UNKNOWN), mFrom(), mSessionID(), + mCreationTime(time_corrected()), mMinUserNameWidth(0), mUserNameFont(NULL), mUserNameTextBox(NULL), @@ -403,6 +405,48 @@ public: { LLAvatarActions::pay(getAvatarId()); } + else if (level == "report_abuse") + { + std::string time_string; + if (mTime > 0) // have frame time + { + time_t current_time = time_corrected(); + time_t message_time = current_time - LLFrameTimer::getElapsedSeconds() + mTime; + + time_string = "[" + LLTrans::getString("TimeMonth") + "]/[" + + LLTrans::getString("TimeDay") + "]/[" + + LLTrans::getString("TimeYear") + "] [" + + LLTrans::getString("TimeHour") + "]:[" + + LLTrans::getString("TimeMin") + "]"; + + LLSD substitution; + + substitution["datetime"] = (S32)message_time; + LLStringUtil::format(time_string, substitution); + } + else + { + // From history. This might be empty or not full. + // See LLChatLogParser::parse + time_string = getChild<LLTextBox>("time_box")->getValue().asString(); + + // Just add current date if not full. + // Should be fine since both times are supposed to be stl + if (!time_string.empty() && time_string.size() < 7) + { + time_string = "[" + LLTrans::getString("TimeMonth") + "]/[" + + LLTrans::getString("TimeDay") + "]/[" + + LLTrans::getString("TimeYear") + "] " + time_string; + + LLSD substitution; + // To avoid adding today's date to yesterday's timestamp, + // use creation time instead of current time + substitution["datetime"] = (S32)mCreationTime; + LLStringUtil::format(time_string, substitution); + } + } + LLFloaterReporter::showFromChat(mAvatarID, mFrom, time_string, mText); + } else if(level == "block_unblock") { LLAvatarActions::toggleMute(getAvatarId(), LLMute::flagVoiceChat); @@ -477,6 +521,10 @@ public: { return canModerate(userdata); } + else if (level == "report_abuse") + { + return gAgentID != mAvatarID; + } else if (level == "can_ban_member") { return canBanGroupMember(getAvatarId()); @@ -634,6 +682,12 @@ public: mSessionID = chat.mSessionID; mSourceType = chat.mSourceType; + // To be able to report a message, we need a copy of it's text + // and it's easier to store text directly than trying to get + // it from a lltextsegment or chat's mEditor + mText = chat.mText; + mTime = chat.mTime; + //*TODO overly defensive thing, source type should be maintained out there if((chat.mFromID.isNull() && chat.mFromName.empty()) || (chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull())) { @@ -983,6 +1037,9 @@ protected: EChatSourceType mSourceType; std::string mFrom; LLUUID mSessionID; + std::string mText; + F64 mTime; // IM's frame time + time_t mCreationTime; // Views's time S32 mMinUserNameWidth; const LLFontGL* mUserNameFont; diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp index 86e23e7c83..97b16a5e93 100644 --- a/indra/newview/llconversationloglist.cpp +++ b/indra/newview/llconversationloglist.cpp @@ -391,7 +391,8 @@ bool LLConversationLogList::isActionEnabled(const LLSD& userdata) "can_invite_to_group" == command_name || "can_share" == command_name || "can_block" == command_name || - "can_pay" == command_name) + "can_pay" == command_name || + "report_abuse" == command_name) { return is_p2p; } diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index a685639427..9ec4fb085b 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -182,6 +182,7 @@ void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32 items.push_back(std::string("map")); items.push_back(std::string("share")); items.push_back(std::string("pay")); + items.push_back(std::string("report_abuse")); items.push_back(std::string("block_unblock")); items.push_back(std::string("MuteText")); diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp index 7d4961c598..4d9ef99319 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.cpp +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -80,9 +80,14 @@ LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage() { } +void LLDoNotDisturbNotificationStorage::reset() +{ + setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml")); +} + void LLDoNotDisturbNotificationStorage::initialize() { - setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml")); + reset(); getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1)); } diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h index c6f0bf1ab5..237d58b4de 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.h +++ b/indra/newview/lldonotdisturbnotificationstorage.h @@ -61,6 +61,7 @@ public: void loadNotifications(); void updateNotifications(); void removeNotification(const char * name, const LLUUID& id); + void reset(); protected: diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 1e548141c8..7c4c2e4b7e 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -577,6 +577,8 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba params.mGroup->rebuildMesh(); } + LLGLDisable cull(params.mGLTFMaterial && params.mGLTFMaterial->mDoubleSided ? GL_CULL_FACE : 0); + LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test); params.mVertexBuffer->setBufferFast(mask); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index ee085a65c2..b4807e8d35 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -405,62 +405,76 @@ bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material) { bool tex_setup = false; - if (deferred_render && use_material && current_shader) + if (draw->mGLTFMaterial) { - if (draw->mNormalMap) - { - draw->mNormalMap->addTextureStats(draw->mVSize); - current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap); - } - - if (draw->mSpecularMap) - { - draw->mSpecularMap->addTextureStats(draw->mVSize); - current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap); - } + if (draw->mTextureMatrix) + { + tex_setup = true; + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } } - else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant) + else { - current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); - current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - if (draw->mTextureList.size() > 1) - { - for (U32 i = 0; i < draw->mTextureList.size(); ++i) - { - if (draw->mTextureList[i].notNull()) - { - gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]); - } - } - } - else - { //not batching textures or batch has only 1 texture -- might need a texture matrix - if (draw->mTexture.notNull()) - { - if (use_material) - { - current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture); - } - else - { - gGL.getTexUnit(0)->bindFast(draw->mTexture); - } + if (deferred_render && use_material && current_shader) + { + if (draw->mNormalMap) + { + draw->mNormalMap->addTextureStats(draw->mVSize); + current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap); + } - if (draw->mTextureMatrix) - { - tex_setup = true; - gGL.getTexUnit(0)->activate(); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadMatrix((GLfloat*) draw->mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - } - } - else - { - gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE); - } - } + if (draw->mSpecularMap) + { + draw->mSpecularMap->addTextureStats(draw->mVSize); + current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap); + } + } + else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant) + { + current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); + current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + if (draw->mTextureList.size() > 1) + { + for (U32 i = 0; i < draw->mTextureList.size(); ++i) + { + if (draw->mTextureList[i].notNull()) + { + gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]); + } + } + } + else + { //not batching textures or batch has only 1 texture -- might need a texture matrix + if (draw->mTexture.notNull()) + { + if (use_material) + { + current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture); + } + else + { + gGL.getTexUnit(0)->bindFast(draw->mTexture); + } + + if (draw->mTextureMatrix) + { + tex_setup = true; + gGL.getTexUnit(0)->activate(); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + } + else + { + gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE); + } + } + } return tex_setup; } @@ -615,9 +629,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) LLGLTFMaterial *gltf_mat = params.mGLTFMaterial; // Also see: LLPipeline::getPoolTypeFromTE() bool is_pbr = LLPipeline::sRenderPBR && gltf_mat; + LLGLDisable cull_face(is_pbr && gltf_mat->mDoubleSided ? GL_CULL_FACE : 0); + if (is_pbr && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND) { - target_shader = &gDeferredPBRAlphaProgram[rigged]; + target_shader = &gDeferredPBRAlphaProgram; + if (params.mAvatar != nullptr) + { + target_shader = target_shader->mRiggedVariant; + } + if (current_shader != target_shader) { gPipeline.bindDeferredShader(*target_shader); @@ -662,9 +683,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) target_shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, params.mGLTFMaterial->mRoughnessFactor); target_shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, params.mGLTFMaterial->mMetallicFactor); target_shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, params.mGLTFMaterial->mEmissiveColor.mV); - - target_shader->mLightHash = 0; - gGL.syncLightState(); // Set light uniforms } else { @@ -723,36 +741,37 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) { target_shader = fullbright_shader; } - } - - if (params.mAvatar != nullptr) - { - target_shader = target_shader->mRiggedVariant; - } - if (current_shader != target_shader) - {// If we need shaders, and we're not ALREADY using the proper shader, then bind it - // (this way we won't rebind shaders unnecessarily). - target_shader->bind(); - } - LLVector4 spec_color(1, 1, 1, 1); - F32 env_intensity = 0.0f; - F32 brightness = 1.0f; + if (params.mAvatar != nullptr) + { + target_shader = target_shader->mRiggedVariant; + } - // We have a material. Supply the appropriate data here. - if (mat && deferred_render) - { - spec_color = params.mSpecColor; - env_intensity = params.mEnvIntensity; - brightness = params.mFullbright ? 1.f : 0.f; - } + if (current_shader != target_shader) + {// If we need shaders, and we're not ALREADY using the proper shader, then bind it + // (this way we won't rebind shaders unnecessarily). + target_shader->bind(); + } - if (current_shader) - { - current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]); - current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity); - current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness); + LLVector4 spec_color(1, 1, 1, 1); + F32 env_intensity = 0.0f; + F32 brightness = 1.0f; + + // We have a material. Supply the appropriate data here. + if (mat && deferred_render) + { + spec_color = params.mSpecColor; + env_intensity = params.mEnvIntensity; + brightness = params.mFullbright ? 1.f : 0.f; + } + + if (current_shader) + { + current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]); + current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity); + current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness); + } } if (params.mGroup) diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index be33e1b30a..55c8d84838 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -165,19 +165,6 @@ void LLDrawPoolTerrain::render(S32 pass) LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f); - if (!gGLManager.mHasMultitexture) - { - // No multitexture, render simple land. - renderSimple(); // Render without multitexture - return; - } - // Render simplified land if video card can't do sufficient multitexturing - if (!gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2)) - { - renderSimple(); // Render without multitexture - return; - } - LLGLSPipeline gls; if (mShaderLevel > 1 && sShader->mShaderLevel > 0) @@ -194,10 +181,6 @@ void LLDrawPoolTerrain::render(S32 pass) { renderSimple(); } - else if (gGLManager.mNumTextureUnits < 4) - { - renderFull2TU(); - } else { renderFull4TU(); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index a84f62036e..576024ead3 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -104,7 +104,7 @@ void LLDrawPoolWater::restoreGL() void LLDrawPoolWater::prerender() { - mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; + mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; } S32 LLDrawPoolWater::getNumPasses() @@ -188,12 +188,6 @@ void LLDrawPoolWater::render(S32 pass) stop_glerror(); - if (!gGLManager.mHasMultitexture) - { - // Ack! No multitexture! Bail! - return; - } - LLFace* refl_face = voskyp->getReflFace(); gPipeline.disableLights(); diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 63e7887d81..361a7666fa 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -125,7 +125,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight())); } - if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD) + if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -212,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; + bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; if (use_fbo) { diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 33d6a205e7..5562f1d057 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1211,55 +1211,6 @@ bool LLFace::canRenderAsMask() return false; } - -//static -void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL; - - if (vf.mWeights) - { - mask |= LLVertexBuffer::MAP_WEIGHT4; - } - - LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW); - vf.mVertexBuffer = buff; - - buff->allocateBuffer(vf.mNumVertices, 0, true); - - LLStrider<LLVector4a> f_vert; - LLStrider<LLVector4a> f_tangent; - LLStrider<LLVector3> f_norm; - LLStrider<LLVector2> f_tc; - - buff->getTangentStrider(f_tangent); - buff->getVertexStrider(f_vert); - buff->getNormalStrider(f_norm); - buff->getTexCoord0Strider(f_tc); - - for (U32 i = 0; i < vf.mNumVertices; ++i) - { - *f_vert++ = vf.mPositions[i]; - *f_tangent++ = vf.mTangents[i]; - *f_tc++ = vf.mTexCoords[i]; - (*f_norm++).set(vf.mNormals[i].getF32ptr()); - } - - if (vf.mWeights) - { - LLStrider<LLVector4> f_wght; - buff->getWeight4Strider(f_wght); - for (U32 i = 0; i < vf.mNumVertices; ++i) - { - (*f_wght++).set(vf.mWeights[i].getF32ptr()); - } - } - - buff->flush(); -} - //helper function for pushing primitives for transform shaders and cleaning up //uninitialized data on the tail, plus tracking number of expected primitives void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count) @@ -1304,7 +1255,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, //don't use map range (generates many redundant unmap calls) - bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; + bool map_range = false; if (mVertexBuffer.notNull()) { @@ -1535,155 +1486,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - -#ifdef GL_TRANSFORM_FEEDBACK_BUFFER - if (use_transform_feedback && - mVertexBuffer->getUsage() == GL_DYNAMIC_COPY && - gTransformPositionProgram.mProgramObject && //transform shaders are loaded - mVertexBuffer->useVBOs() && //target buffer is in VRAM - !rebuild_weights && //TODO: add support for weights - !volume.isUnique()) //source volume is NOT flexi - { //use transform feedback to pack vertex buffer - - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - transform feedback"); - LLGLEnable discard(GL_RASTERIZER_DISCARD); - LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); - - if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) - { - mVObjp->getVolume()->genTangents(f); - LLFace::cacheFaceInVRAM(vf); - buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); - } - - LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr; - - gGL.pushMatrix(); - gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix); - - if (rebuild_pos) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf position"); - gTransformPositionProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount); - - U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0; - - S32 val = 0; - U8* vp = (U8*) &val; - vp[0] = index; - vp[1] = 0; - vp[2] = 0; - vp[3] = 0; - - gTransformPositionProgram.uniform1i(sTextureIndexIn, val); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - - push_for_transform(buff, vf.mNumVertices, mGeomCount); - - glEndTransformFeedback(); - } - - if (rebuild_color) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf color"); - gTransformColorProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount); - - S32 val = *((S32*) color.mV); - - gTransformColorProgram.uniform1i(sColorIn, val); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_emissive) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf emissive"); - gTransformColorProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount); - - U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); - - S32 glow32 = glow | - (glow << 8) | - (glow << 16) | - (glow << 24); - - gTransformColorProgram.uniform1i(sColorIn, glow32); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_normal) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf normal"); - gTransformNormalProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_NORMAL); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_tangent) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tangent"); - gTransformTangentProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TANGENT); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_tcoord) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tcoord"); - gTransformTexCoordProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - - bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); - - if (do_bump) - { - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - } - - glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); - gGL.popMatrix(); - - if (cur_shader) - { - cur_shader->bind(); - } - } - else -#endif { //if it's not fullbright and has no normals, bake sunlight based on face normal //bool bake_sunlight = !getTextureEntry()->getFullbright() && @@ -2177,6 +1979,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mask.setElement<3>(); LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents; + if (tbuff == nullptr) + { // non-mesh prims will not have mikktspace tangents + tbuff = vf.mTangents; + } + LLVector4a* src = tbuff; LLVector4a* end = tbuff+num_vertices; @@ -2184,7 +1991,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLVector4a tangent_out; mat_normal.rotate(*src, tangent_out); - tangent_out.normalize3fast(); tangent_out.setSelectWithMask(mask, *src, tangent_out); tangent_out.store4a(tangents); diff --git a/indra/newview/llface.h b/indra/newview/llface.h index aa00c9d052..4778a8110b 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -81,8 +81,6 @@ public: PARTICLE = 0x0080, }; - static void cacheFaceInVRAM(const LLVolumeFace& vf); - public: LLFace(LLDrawable* drawablep, LLViewerObject* objp) { diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 826d4892ef..2c770f6ab8 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -431,41 +431,9 @@ bool LLFeatureManager::loadGPUClass() LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL; mGPUClass = GPU_CLASS_3; #else - if (gGLManager.mGLVersion <= 2.f) - { - mGPUClass = GPU_CLASS_0; - } - else if (gGLManager.mGLVersion <= 3.f) - { - mGPUClass = GPU_CLASS_1; - } - else if (gGLManager.mGLVersion < 3.3f) - { - mGPUClass = GPU_CLASS_2; - } - else if (gGLManager.mGLVersion < 4.f) - { - mGPUClass = GPU_CLASS_3; - } - else - { - mGPUClass = GPU_CLASS_4; - } - if (gGLManager.mIsIntel && mGPUClass > GPU_CLASS_1) - { - // Intels are generally weaker then other GPUs despite having advanced features - mGPUClass = (EGPUClass)(mGPUClass - 1); - } + mGPUClass = GPU_CLASS_2; #endif } - else if (gGLManager.mGLVersion <= 2.f) - { - mGPUClass = GPU_CLASS_0; - } - else if (gGLManager.mGLVersion <= 3.f) - { - mGPUClass = GPU_CLASS_1; - } else if (gbps <= 5.f) { mGPUClass = GPU_CLASS_0; @@ -679,10 +647,6 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("TexUnit8orLess"); } - if (gGLManager.mHasMapBufferRange) - { - maskFeatures("MapBufferRange"); - } if (gGLManager.mVRAM > 512) { maskFeatures("VRAMGT512"); diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index ffbb0bbee9..c075f7e8bd 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -114,6 +114,11 @@ BOOL LLFloater360Capture::postBuild() // by default each time vs restoring the last value mQualityRadioGroup->setSelectedIndex(0); + return true; +} + +void LLFloater360Capture::onOpen(const LLSD& key) +{ // Construct a URL pointing to the first page to load. Although // we do not use this page for anything (after some significant // design changes), we retain the code to load the start page @@ -154,8 +159,6 @@ BOOL LLFloater360Capture::postBuild() // We do an initial capture when the floater is opened, albeit at a 'preview' // quality level (really low resolution, but really fast) onCapture360ImagesBtn(); - - return true; } // called when the user choose a quality level using diff --git a/indra/newview/llfloater360capture.h b/indra/newview/llfloater360capture.h index 6da7ee074a..8f765c0b1b 100644 --- a/indra/newview/llfloater360capture.h +++ b/indra/newview/llfloater360capture.h @@ -47,6 +47,7 @@ class LLFloater360Capture: ~LLFloater360Capture(); BOOL postBuild() override; + void onOpen(const LLSD& key) override; void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; void changeInterestListMode(bool send_everything); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index ab95bc06b8..0186c4aebe 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -105,6 +105,7 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key) mNumResultsReturned(0), mNearMeListComplete(FALSE), mCloseOnSelect(FALSE), + mExcludeAgentFromSearchResults(FALSE), mContextConeOpacity (0.f), mContextConeInAlpha(0.f), mContextConeOutAlpha(0.f), @@ -295,7 +296,7 @@ void LLFloaterAvatarPicker::populateNearMe() for(U32 i=0; i<avatar_ids.size(); i++) { LLUUID& av = avatar_ids[i]; - if(av == gAgent.getID()) continue; + if(mExcludeAgentFromSearchResults && (av == gAgent.getID())) continue; LLSD element; element["id"] = av; // value LLAvatarName av_name; diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index a3037ed651..392633bd7d 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -1047,7 +1047,12 @@ LLPreviewAnimation::LLPreviewAnimation(S32 width, S32 height) : LLViewerDynamicT mDummyAvatar = (LLVOAvatar*)gObjectList.createObjectViewer(LL_PCODE_LEGACY_AVATAR, gAgent.getRegion(), LLViewerObject::CO_FLAG_UI_AVATAR); mDummyAvatar->mSpecialRenderMode = 1; mDummyAvatar->startMotion(ANIM_AGENT_STAND, BASE_ANIM_TIME_OFFSET); - mDummyAvatar->hideSkirt(); + + // on idle overall apperance update will set skirt to visible, so either + // call early or account for mSpecialRenderMode in updateMeshVisibility + mDummyAvatar->updateOverallAppearance(); + mDummyAvatar->hideHair(); + mDummyAvatar->hideSkirt(); // stop extraneous animations mDummyAvatar->stopMotion( ANIM_AGENT_HEAD_ROT, TRUE ); @@ -1135,6 +1140,7 @@ BOOL LLPreviewAnimation::render() { LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)face->getPool(); avatarp->dirtyMesh(); + gPipeline.enableLightsPreview(); avatarPoolp->renderAvatars(avatarp); // renders only one avatar } } diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 1525bb9952..703b5d0011 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -45,6 +45,7 @@ #include "llflashtimer.h" #include "llfloateravatarpicker.h" #include "llfloaterpreference.h" +#include "llfloaterreporter.h" #include "llimview.h" #include "llnotificationsutil.h" #include "lltoolbarview.h" @@ -1242,6 +1243,18 @@ void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec { LLAvatarActions::pay(userID); } + else if ("report_abuse" == command) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(userID, &av_name)) + { + LLFloaterReporter::showFromAvatar(userID, av_name.getCompleteName()); + } + else + { + LLFloaterReporter::showFromAvatar(userID, "not avaliable"); + } + } else if ("block_unblock" == command) { LLAvatarActions::toggleMute(userID, LLMute::flagVoiceChat); @@ -1507,7 +1520,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v } // Handle all other options - if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item)) + if (("can_invite" == item) + || ("can_chat_history" == item) + || ("can_share" == item) + || ("can_pay" == item) + || ("report_abuse" == item)) { // Those menu items are enable only if a single avatar is selected return is_single_select; diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp index 524162ba51..e755e9924c 100644 --- a/indra/newview/llfloatermarketplacelistings.cpp +++ b/indra/newview/llfloatermarketplacelistings.cpp @@ -579,7 +579,25 @@ void LLFloaterMarketplaceListings::updateView() // Update the top message or flip to the tabs and folders view // *TODO : check those messages and create better appropriate ones in strings.xml - if (mRootFolderId.notNull()) + if (mkt_status == MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE) + { + std::string reason = LLMarketplaceData::instance().getSLMConnectionfailureReason(); + if (reason.empty()) + { + text = LLTrans::getString("InventoryMarketplaceConnectionError"); + } + else + { + LLSD args; + args["[REASON]"] = reason; + text = LLTrans::getString("InventoryMarketplaceConnectionErrorReason", args); + } + + title = LLTrans::getString("InventoryOutboxErrorTitle"); + tooltip = LLTrans::getString("InventoryOutboxErrorTooltip"); + LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL; + } + else if (mRootFolderId.notNull()) { // "Marketplace listings is empty!" message strings text = LLTrans::getString("InventoryMarketplaceListingsNoItems", subs); diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index 2afd889609..b34961e8a2 100644 --- a/indra/newview/llfloatermediasettings.cpp +++ b/indra/newview/llfloatermediasettings.cpp @@ -157,6 +157,18 @@ void LLFloaterMediaSettings::apply() } //////////////////////////////////////////////////////////////////////////////// +void LLFloaterMediaSettings::onOpen(const LLSD& key) +{ + if (mPanelMediaSettingsGeneral) + { + // media is expensive, so only load it when nessesary. + // If we need to preload it, set volume to 0 and any pause + // if applicable, then unpause here + mPanelMediaSettingsGeneral->updateMediaPreview(); + } +} + +//////////////////////////////////////////////////////////////////////////////// void LLFloaterMediaSettings::onClose(bool app_quitting) { if(mPanelMediaSettingsGeneral) diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h index f93512eb3a..151e43e6b9 100644 --- a/indra/newview/llfloatermediasettings.h +++ b/indra/newview/llfloatermediasettings.h @@ -42,6 +42,7 @@ public: ~LLFloaterMediaSettings(); /*virtual*/ BOOL postBuild(); + /*virtual*/ void onOpen(const LLSD& key); /*virtual*/ void onClose(bool app_quitting); static LLFloaterMediaSettings* getInstance(); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index b7c98c915c..7c3f3da4cf 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -507,6 +507,15 @@ void LLFloaterModelPreview::onClickCalculateBtn() toggleCalculateButton(false); mUploadBtn->setEnabled(false); + + //disable "simplification" UI + LLPanel* simplification_panel = getChild<LLPanel>("physics simplification"); + LLView* child = simplification_panel->getFirstChild(); + while (child) + { + child->setEnabled(false); + child = simplification_panel->findNextSibling(child); + } } // Modified cell_params, make sure to clear values if you have to reuse cell_params outside of this function diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp index 87973c2286..94261b2e4e 100644 --- a/indra/newview/llfloaterpay.cpp +++ b/indra/newview/llfloaterpay.cpp @@ -72,7 +72,7 @@ struct LLGiveMoneyInfo mFloater(floater), mAmount(amount){} }; -typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr; +typedef std::shared_ptr<LLGiveMoneyInfo> give_money_ptr; ///---------------------------------------------------------------------------- /// Class LLFloaterPay diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index dd9a212c1c..01ebdf6830 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -399,6 +399,7 @@ BOOL LLFloaterPreference::postBuild() gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this)); gSavedPerAccountSettings.getControl("ModelUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeModelFolder, this)); + gSavedPerAccountSettings.getControl("PBRUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangePBRFolder, this)); gSavedPerAccountSettings.getControl("TextureUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeTextureFolder, this)); gSavedPerAccountSettings.getControl("SoundUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeSoundFolder, this)); gSavedPerAccountSettings.getControl("AnimationUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeAnimationFolder, this)); @@ -688,6 +689,7 @@ void LLFloaterPreference::onOpen(const LLSD& key) onChangeMaturity(); onChangeModelFolder(); + onChangePBRFolder(); onChangeTextureFolder(); onChangeSoundFolder(); onChangeAnimationFolder(); @@ -1196,7 +1198,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText"); // Reflections - BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps; + BOOL reflections = LLCubeMap::sUseCubeMaps; ctrl_reflections->setEnabled(reflections); reflections_text->setEnabled(reflections); @@ -1225,14 +1227,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() // Hardware settings - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || - !gGLManager.mHasVertexBufferObject) - { - getChildView("vbo")->setEnabled(FALSE); - } - - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") || - !gGLManager.mHasVertexBufferObject) + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures")) { getChildView("texture compression")->setEnabled(FALSE); } @@ -1773,6 +1768,14 @@ void LLFloaterPreference::onChangeModelFolder() } } +void LLFloaterPreference::onChangePBRFolder() +{ + if (gInventory.isInventoryUsable()) + { + getChild<LLTextBox>("upload_pbr")->setText(get_category_path(LLFolderType::FT_MATERIAL)); + } +} + void LLFloaterPreference::onChangeTextureFolder() { if (gInventory.isInventoryUsable()) @@ -2837,10 +2840,15 @@ void LLPanelPreferenceControls::cancel() if (mConflictHandler[i].hasUnsavedChanges()) { mConflictHandler[i].clear(); + if (mEditingMode == i) + { + // cancel() can be called either when preferences floater closes + // or when child floater closes (like advanced graphical settings) + // in which case we need to clear and repopulate table + regenerateControls(); + } } } - pControlsTable->clearRows(); - pControlsTable->clearColumns(); } void LLPanelPreferenceControls::saveSettings() diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 542df18ddb..af17c46be0 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -173,6 +173,7 @@ public: void applyResolution(); void onChangeMaturity(); void onChangeModelFolder(); + void onChangePBRFolder(); void onChangeTextureFolder(); void onChangeSoundFolder(); void onChangeAnimationFolder(); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 296e155d28..293ccc344c 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1322,6 +1322,7 @@ void LLPanelRegionDebugInfo::onClickDebugConsole(void* data) BOOL LLPanelRegionTerrainInfo::validateTextureSizes() { + static const S32 MAX_TERRAIN_TEXTURE_SIZE = 1024; for(S32 i = 0; i < TERRAIN_TEXTURE_COUNT; ++i) { std::string buffer; @@ -1343,17 +1344,19 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes() LLSD args; args["TEXTURE_NUM"] = i+1; args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); + args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE; LLNotificationsUtil::add("InvalidTerrainBitDepth", args); return FALSE; } - if (width > 512 || height > 512) + if (width > MAX_TERRAIN_TEXTURE_SIZE || height > MAX_TERRAIN_TEXTURE_SIZE) { LLSD args; args["TEXTURE_NUM"] = i+1; args["TEXTURE_SIZE_X"] = width; args["TEXTURE_SIZE_Y"] = height; + args["MAX_SIZE"] = MAX_TERRAIN_TEXTURE_SIZE; LLNotificationsUtil::add("InvalidTerrainSize", args); return FALSE; @@ -3683,7 +3686,7 @@ void LLPanelEstateAccess::searchAgent(LLNameListCtrl* listCtrl, const std::strin if (!search_string.empty()) { listCtrl->setSearchColumn(0); // name column - listCtrl->selectItemByPrefix(search_string, FALSE); + listCtrl->searchItems(search_string, false, true); } else { diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index b73755cf4e..2df4ca973d 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -54,6 +54,7 @@ #include "llbutton.h" #include "llfloaterreg.h" #include "lltexturectrl.h" +#include "lltexteditor.h" #include "llscrolllistctrl.h" #include "lldispatcher.h" #include "llviewerobject.h" @@ -250,9 +251,6 @@ LLFloaterReporter::~LLFloaterReporter() mPosition.setVec(0.0f, 0.0f, 0.0f); - std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() ); - mMCDList.clear(); - delete mResourceDatap; } @@ -661,6 +659,23 @@ void LLFloaterReporter::showFromAvatar(const LLUUID& avatar_id, const std::strin show(avatar_id, avatar_name); } +// static +void LLFloaterReporter::showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description) +{ + show(avatar_id, avatar_name); + + LLStringUtil::format_map_t args; + args["[MSG_TIME]"] = time; + args["[MSG_DESCRIPTION]"] = description; + + LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); + if (self) + { + std::string description = self->getString("chat_report_format", args); + self->getChild<LLUICtrl>("details_edit")->setValue(description); + } +} + void LLFloaterReporter::setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id) { getChild<LLUICtrl>("object_name")->setValue(object_name); @@ -1028,37 +1043,3 @@ void LLFloaterReporter::onClose(bool app_quitting) mSnapshotTimer.stop(); gSavedPerAccountSettings.setBOOL("PreviousScreenshotForReport", app_quitting); } - - -// void LLFloaterReporter::setDescription(const std::string& description, LLMeanCollisionData *mcd) -// { -// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); -// if (self) -// { -// self->getChild<LLUICtrl>("details_edit")->setValue(description); - -// for_each(self->mMCDList.begin(), self->mMCDList.end(), DeletePointer()); -// self->mMCDList.clear(); -// if (mcd) -// { -// self->mMCDList.push_back(new LLMeanCollisionData(mcd)); -// } -// } -// } - -// void LLFloaterReporter::addDescription(const std::string& description, LLMeanCollisionData *mcd) -// { -// LLFloaterReporter *self = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter"); -// if (self) -// { -// LLTextEditor* text = self->getChild<LLTextEditor>("details_edit"); -// if (text) -// { -// text->insertText(description); -// } -// if (mcd) -// { -// self->mMCDList.push_back(new LLMeanCollisionData(mcd)); -// } -// } -// } diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index c678df7155..b6c70e866d 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -93,6 +93,7 @@ public: static void showFromObject(const LLUUID& object_id, const LLUUID& experience_id = LLUUID::null); static void showFromAvatar(const LLUUID& avatar_id, const std::string avatar_name); + static void showFromChat(const LLUUID& avatar_id, const std::string& avatar_name, const std::string& time, const std::string& description); static void showFromExperience(const LLUUID& experience_id); static void onClickSend (void *userdata); @@ -101,8 +102,6 @@ public: void onClickSelectAbuser (); static void closePickTool (void *userdata); static void uploadDoneCallback(const LLUUID &uuid, void* user_data, S32 result, LLExtStat ext_status); - static void addDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); - static void setDescription(const std::string& description, LLMeanCollisionData *mcd = NULL); void setPickedObjectProperties(const std::string& object_name, const std::string& owner_name, const LLUUID owner_id); @@ -114,10 +113,8 @@ private: static void show(const LLUUID& object_id, const std::string& avatar_name = LLStringUtil::null, const LLUUID& experience_id = LLUUID::null); void takeScreenshot(bool use_prev_screenshot = false); - void sendReportViaCaps(std::string url); void uploadImage(); bool validateReport(); - void setReporterID(); LLSD gatherReport(); void sendReportViaLegacy(const LLSD & report); void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report); @@ -144,7 +141,6 @@ private: BOOL mPicking; LLVector3 mPosition; BOOL mCopyrightWarningSeen; - std::list<LLMeanCollisionData*> mMCDList; std::string mDefaultSummary; LLResourceData* mResourceDatap; boost::signals2::connection mAvatarNameCacheConnection; diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index 2e1fbb09e0..bb3ed77772 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -57,10 +57,10 @@ public: const size_t parts = tokens.size(); // get the (optional) category for the search - std::string category; + std::string collection; if (parts > 0) { - category = tokens[0].asString(); + collection = tokens[0].asString(); } // get the (optional) search string @@ -72,7 +72,7 @@ public: // create the LLSD arguments for the search floater LLFloaterSearch::Params p; - p.search.category = category; + p.search.collection = collection; p.search.query = LLURI::unescape(search_text); // open the search floater and perform the requested search @@ -83,8 +83,9 @@ public: LLSearchHandler gSearchHandler; LLFloaterSearch::SearchQuery::SearchQuery() -: category("category", ""), - query("query") +: category("category", ""), + collection("collection", ""), + query("query") {} LLFloaterSearch::LLFloaterSearch(const Params& key) : @@ -93,16 +94,16 @@ LLFloaterSearch::LLFloaterSearch(const Params& key) : { // declare a map that transforms a category name into // the URL suffix that is used to search that category - mCategoryPaths = LLSD::emptyMap(); - mCategoryPaths["all"] = "search"; - mCategoryPaths["people"] = "search/people"; - mCategoryPaths["places"] = "search/places"; - mCategoryPaths["events"] = "search/events"; - mCategoryPaths["groups"] = "search/groups"; - mCategoryPaths["wiki"] = "search/wiki"; - mCategoryPaths["land"] = "land"; - mCategoryPaths["destinations"] = "destinations"; - mCategoryPaths["classifieds"] = "classifieds"; + + mSearchType.insert("standard"); + mSearchType.insert("land"); + mSearchType.insert("classified"); + + mCollectionType.insert("events"); + mCollectionType.insert("destinations"); + mCollectionType.insert("places"); + mCollectionType.insert("groups"); + mCollectionType.insert("people"); } BOOL LLFloaterSearch::postBuild() @@ -157,31 +158,49 @@ void LLFloaterSearch::search(const SearchQuery &p) // work out the subdir to use based on the requested category LLSD subs; - if (mCategoryPaths.has(p.category)) + if (mSearchType.find(p.category) != mSearchType.end()) { - subs["CATEGORY"] = mCategoryPaths[p.category].asString(); + subs["TYPE"] = p.category; } else { - subs["CATEGORY"] = mCategoryPaths["all"].asString(); + subs["TYPE"] = "standard"; } // add the search query string subs["QUERY"] = LLURI::escape(p.query); + subs["COLLECTION"] = ""; + if (subs["TYPE"] == "standard") + { + if (mCollectionType.find(p.collection) != mCollectionType.end()) + { + subs["COLLECTION"] = "&collection_chosen=" + std::string(p.collection); + } + else + { + std::string collection_args(""); + for (std::set<std::string>::iterator it = mCollectionType.begin(); it != mCollectionType.end(); ++it) + { + collection_args += "&collection_chosen=" + std::string(*it); + } + subs["COLLECTION"] = collection_args; + } + } + // add the user's preferred maturity (can be changed via prefs) std::string maturity; if (gAgent.prefersAdult()) { - maturity = "42"; // PG,Mature,Adult + maturity = "gma"; // PG,Mature,Adult } else if (gAgent.prefersMature()) { - maturity = "21"; // PG,Mature + maturity = "gm"; // PG,Mature } else { - maturity = "13"; // PG + maturity = "g"; // PG } subs["MATURITY"] = maturity; diff --git a/indra/newview/llfloatersearch.h b/indra/newview/llfloatersearch.h index 35b268e1b2..cc77ce696f 100644 --- a/indra/newview/llfloatersearch.h +++ b/indra/newview/llfloatersearch.h @@ -49,6 +49,7 @@ public: struct SearchQuery : public LLInitParam::Block<SearchQuery> { Optional<std::string> category; + Optional<std::string> collection; Optional<std::string> query; SearchQuery(); @@ -84,7 +85,8 @@ public: private: /*virtual*/ BOOL postBuild(); - LLSD mCategoryPaths; + std::set<std::string> mSearchType; + std::set<std::string> mCollectionType; U8 mSearchGodLevel; }; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 77a04bc5d7..b6acba6558 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -46,7 +46,6 @@ #include "llfloaterreg.h" #include "llfocusmgr.h" #include "llmediaentry.h" -#include "llmediactrl.h" #include "llmenugl.h" #include "llnotificationsutil.h" #include "llpanelcontents.h" @@ -240,7 +239,6 @@ BOOL LLFloaterTools::postBuild() mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group"); mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group"); mBtnGridOptions = getChild<LLButton>("Options..."); - mTitleMedia = getChild<LLMediaCtrl>("title_media"); mBtnLink = getChild<LLButton>("link_btn"); mBtnUnlink = getChild<LLButton>("unlink_btn"); @@ -329,7 +327,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mCheckSnapToGrid(NULL), mBtnGridOptions(NULL), - mTitleMedia(NULL), mComboGridMode(NULL), mCheckStretchUniform(NULL), mCheckStretchTexture(NULL), @@ -369,8 +366,7 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mLandImpactsObserver(NULL), mDirty(TRUE), - mHasSelection(TRUE), - mNeedMediaTitle(TRUE) + mHasSelection(TRUE) { gFloaterTools = this; @@ -394,9 +390,6 @@ LLFloaterTools::LLFloaterTools(const LLSD& key) mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this)); mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1)); mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1)); - mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this)); - mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this)); - mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this)); mCommitCallbackRegistrar.add("BuildTool.LinkObjects", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance())); mCommitCallbackRegistrar.add("BuildTool.UnlinkObjects", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance())); @@ -553,7 +546,7 @@ void LLFloaterTools::refresh() mPanelObject->refresh(); mPanelVolume->refresh(); mPanelFace->refresh(); - refreshMedia(); + mPanelFace->refreshMedia(); mPanelContents->refresh(); mPanelLandInfo->refresh(); @@ -580,9 +573,6 @@ void LLFloaterTools::draw() mDirty = FALSE; } - // grab media name/title and update the UI widget - updateMediaTitle(); - // mCheckSelectIndividual->set(gSavedSettings.getBOOL("EditLinkedParts")); LLFloater::draw(); } @@ -906,8 +896,7 @@ void LLFloaterTools::onClose(bool app_quitting) LLViewerJoystick::getInstance()->moveAvatar(false); // destroy media source used to grab media title - if( mTitleMedia ) - mTitleMedia->unloadMediaSource(); + mPanelFace->unloadMedia(); // Different from handle_reset_view in that it doesn't actually // move the camera if EditCameraMovement is not set. @@ -1160,51 +1149,6 @@ void LLFloaterTools::onFocusReceived() LLFloater::onFocusReceived(); } -// Media stuff -void LLFloaterTools::refreshMedia() -{ - getMediaState(); -} - -bool LLFloaterTools::selectedMediaEditable() -{ - U32 owner_mask_on; - U32 owner_mask_off; - U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER, - &owner_mask_on, &owner_mask_off ); - U32 group_mask_on; - U32 group_mask_off; - U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP, - &group_mask_on, &group_mask_off ); - U32 everyone_mask_on; - U32 everyone_mask_off; - S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE, - &everyone_mask_on, &everyone_mask_off ); - - bool selected_Media_editable = false; - - // if perms we got back are valid - if ( valid_owner_perms && - valid_group_perms && - valid_everyone_perms ) - { - - if ( ( owner_mask_on & PERM_MODIFY ) || - ( group_mask_on & PERM_MODIFY ) || - ( group_mask_on & PERM_MODIFY ) ) - { - selected_Media_editable = true; - } - else - // user is NOT allowed to press the RESET button - { - selected_Media_editable = false; - }; - }; - - return selected_Media_editable; -} - void LLFloaterTools::updateLandImpacts() { LLParcel *parcel = mParcelSelection->getParcel(); @@ -1221,784 +1165,3 @@ void LLFloaterTools::updateLandImpacts() } } -void LLFloaterTools::getMediaState() -{ - LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); - LLViewerObject* first_object = selected_objects->getFirstObject(); - LLTextBox* media_info = getChild<LLTextBox>("media_info"); - - if( !(first_object - && first_object->getPCode() == LL_PCODE_VOLUME - &&first_object->permModify() - )) - { - getChildView("add_media")->setEnabled(FALSE); - media_info->clear(); - clearMediaSettings(); - return; - } - - std::string url = first_object->getRegion()->getCapability("ObjectMedia"); - bool has_media_capability = (!url.empty()); - - if(!has_media_capability) - { - getChildView("add_media")->setEnabled(FALSE); - LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL; - clearMediaSettings(); - return; - } - - BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() - && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) - || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced(); - bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable()); - - // Check modify permissions and whether any selected objects are in - // the process of being fetched. If they are, then we're not editable - if (editable) - { - LLObjectSelection::iterator iter = selected_objects->begin(); - LLObjectSelection::iterator end = selected_objects->end(); - for ( ; iter != end; ++iter) - { - LLSelectNode* node = *iter; - LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject()); - if (NULL != object) - { - if (!object->permModify()) - { - LL_INFOS("LLFloaterToolsMedia") - << "Selection not editable due to lack of modify permissions on object id " - << object->getID() << LL_ENDL; - - editable = false; - break; - } - // XXX DISABLE this for now, because when the fetch finally - // does come in, the state of this floater doesn't properly - // update. Re-selecting fixes the problem, but there is - // contention as to whether this is a sufficient solution. -// if (object->isMediaDataBeingFetched()) -// { -// LL_INFOS("LLFloaterToolsMedia") -// << "Selection not editable due to media data being fetched for object id " -// << object->getID() << LL_ENDL; -// -// editable = false; -// break; -// } - } - } - } - - // Media settings - bool bool_has_media = false; - struct media_functor : public LLSelectedTEGetFunctor<bool> - { - bool get(LLViewerObject* object, S32 face) - { - LLTextureEntry *te = object->getTE(face); - if (te) - { - return te->hasMedia(); - } - return false; - } - } func; - - - // check if all faces have media(or, all dont have media) - LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue( &func, bool_has_media ); - - const LLMediaEntry default_media_data; - - struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry> - { - functor_getter_media_data(const LLMediaEntry& entry): mMediaEntry(entry) {} - - LLMediaEntry get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return *(object->getTE(face)->getMediaData()); - return mMediaEntry; - }; - - const LLMediaEntry& mMediaEntry; - - } func_media_data(default_media_data); - - LLMediaEntry media_data_get; - LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue( &func_media_data, media_data_get )); - - std::string multi_media_info_str = LLTrans::getString("Multiple Media"); - std::string media_title = ""; - // update UI depending on whether "object" (prim or face) has media - // and whether or not you are allowed to edit it. - - getChildView("add_media")->setEnabled(editable); - // IF all the faces have media (or all dont have media) - if ( LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo ) - { - // TODO: get media title and set it. - media_info->clear(); - // if identical is set, all faces are same (whether all empty or has the same media) - if(!(LLFloaterMediaSettings::getInstance()->mMultipleMedia) ) - { - // Media data is valid - if(media_data_get!=default_media_data) - { - // initial media title is the media URL (until we get the name) - media_title = media_data_get.getHomeURL(); - } - // else all faces might be empty. - } - else // there' re Different Medias' been set on on the faces. - { - media_title = multi_media_info_str; - } - - getChildView("delete_media")->setEnabled(bool_has_media && editable ); - // TODO: display a list of all media on the face - use 'identical' flag - } - else // not all face has media but at least one does. - { - // seleted faces have not identical value - LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data ); - - if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) - { - media_title = multi_media_info_str; - } - else - { - // Media data is valid - if(media_data_get!=default_media_data) - { - // initial media title is the media URL (until we get the name) - media_title = media_data_get.getHomeURL(); - } - } - - getChildView("delete_media")->setEnabled(TRUE); - } - - navigateToTitleMedia(media_title); - media_info->setText(media_title); - - // load values for media settings - updateMediaSettings(); - - LLFloaterMediaSettings::initValues(mMediaSettings, editable ); -} - - -////////////////////////////////////////////////////////////////////////////// -// called when a user wants to add media to a prim or prim face -void LLFloaterTools::onClickBtnAddMedia() -{ - // check if multiple faces are selected - if(LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) - { - LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm); - } - else - { - onClickBtnEditMedia(); - } -} - -// static -bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch( option ) - { - case 0: // "Yes" - gFloaterTools->onClickBtnEditMedia(); - break; - case 1: // "No" - default: - break; - } - return false; -} - -////////////////////////////////////////////////////////////////////////////// -// called when a user wants to edit existing media settings on a prim or prim face -// TODO: test if there is media on the item and only allow editing if present -void LLFloaterTools::onClickBtnEditMedia() -{ - refreshMedia(); - LLFloaterReg::showInstance("media_settings"); -} - -////////////////////////////////////////////////////////////////////////////// -// called when a user wants to delete media from a prim or prim face -void LLFloaterTools::onClickBtnDeleteMedia() -{ - LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm); -} - - -// static -bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch( option ) - { - case 0: // "Yes" - LLSelectMgr::getInstance()->selectionSetMedia( 0, LLSD() ); - if(LLFloaterReg::instanceVisible("media_settings")) - { - LLFloaterReg::hideInstance("media_settings"); - } - break; - - case 1: // "No" - default: - break; - } - return false; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterTools::clearMediaSettings() -{ - LLFloaterMediaSettings::clearValues(false); -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterTools::navigateToTitleMedia( const std::string url ) -{ - std::string multi_media_info_str = LLTrans::getString("Multiple Media"); - if (url.empty() || multi_media_info_str == url) - { - // nothing to show - mNeedMediaTitle = false; - } - else if (mTitleMedia) - { - LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); - - if ( media_plugin ) // Shouldn't this be after navigateTo creates plugin? - { - // if it's a movie, we don't want to hear it - media_plugin->setVolume( 0 ); - }; - - // check if url changed or if we need a new media source - if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL) - { - mTitleMedia->navigateTo( url ); - } - - // flag that we need to update the title (even if no request were made) - mNeedMediaTitle = true; - } -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterTools::updateMediaTitle() -{ - // only get the media name if we need it - if ( ! mNeedMediaTitle ) - return; - - // get plugin impl - LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); - if ( media_plugin ) - { - // get the media name (asynchronous - must call repeatedly) - std::string media_title = media_plugin->getMediaName(); - - // only replace the title if what we get contains something - if ( ! media_title.empty() ) - { - // update the UI widget - LLTextBox* media_title_field = getChild<LLTextBox>("media_info"); - if ( media_title_field ) - { - media_title_field->setText( media_title ); - - // stop looking for a title when we get one - // FIXME: check this is the right approach - mNeedMediaTitle = false; - }; - }; - }; -} - -////////////////////////////////////////////////////////////////////////////// -// -void LLFloaterTools::updateMediaSettings() -{ - bool identical( false ); - std::string base_key( "" ); - std::string value_str( "" ); - int value_int = 0; - bool value_bool = false; - LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); - // TODO: (CP) refactor this using something clever or boost or both !! - - const LLMediaEntry default_media_data; - - // controls - U8 value_u8 = default_media_data.getControls(); - struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 > - { - functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {} - - U8 get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getControls(); - return mMediaEntry.getControls(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_controls(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 ); - base_key = std::string( LLMediaEntry::CONTROLS_KEY ); - mMediaSettings[ base_key ] = value_u8; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // First click (formerly left click) - value_bool = default_media_data.getFirstClickInteract(); - struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool > - { - functor_getter_first_click(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getFirstClickInteract(); - return mMediaEntry.getFirstClickInteract(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_first_click(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool ); - base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Home URL - value_str = default_media_data.getHomeURL(); - struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string > - { - functor_getter_home_url(const LLMediaEntry& entry): mMediaEntry(entry) {} - - std::string get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getHomeURL(); - return mMediaEntry.getHomeURL(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_home_url(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_home_url, value_str ); - base_key = std::string( LLMediaEntry::HOME_URL_KEY ); - mMediaSettings[ base_key ] = value_str; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Current URL - value_str = default_media_data.getCurrentURL(); - struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string > - { - functor_getter_current_url(const LLMediaEntry& entry): mMediaEntry(entry) {} - - std::string get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getCurrentURL(); - return mMediaEntry.getCurrentURL(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_current_url(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_current_url, value_str ); - base_key = std::string( LLMediaEntry::CURRENT_URL_KEY ); - mMediaSettings[ base_key ] = value_str; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Auto zoom - value_bool = default_media_data.getAutoZoom(); - struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool > - { - - functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAutoZoom(); - return mMediaEntry.getAutoZoom(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_auto_zoom(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool ); - base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Auto play - //value_bool = default_media_data.getAutoPlay(); - // set default to auto play TRUE -- angela EXT-5172 - value_bool = true; - struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool > - { - functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAutoPlay(); - //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172 - return true; - }; - - const LLMediaEntry &mMediaEntry; - - } func_auto_play(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool ); - base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - - // Auto scale - // set default to auto scale TRUE -- angela EXT-5172 - //value_bool = default_media_data.getAutoScale(); - value_bool = true; - struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool > - { - functor_getter_auto_scale(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAutoScale(); - // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172 - return true; - }; - - const LLMediaEntry &mMediaEntry; - - } func_auto_scale(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool ); - base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Auto loop - value_bool = default_media_data.getAutoLoop(); - struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool > - { - functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAutoLoop(); - return mMediaEntry.getAutoLoop(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_auto_loop(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool ); - base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // width pixels (if not auto scaled) - value_int = default_media_data.getWidthPixels(); - struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int > - { - functor_getter_width_pixels(const LLMediaEntry& entry): mMediaEntry(entry) {} - - int get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getWidthPixels(); - return mMediaEntry.getWidthPixels(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_width_pixels(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int ); - base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY ); - mMediaSettings[ base_key ] = value_int; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // height pixels (if not auto scaled) - value_int = default_media_data.getHeightPixels(); - struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int > - { - functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - int get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getHeightPixels(); - return mMediaEntry.getHeightPixels(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_height_pixels(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int ); - base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY ); - mMediaSettings[ base_key ] = value_int; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Enable Alt image - value_bool = default_media_data.getAltImageEnable(); - struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool > - { - functor_getter_enable_alt_image(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getAltImageEnable(); - return mMediaEntry.getAltImageEnable(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_enable_alt_image(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool ); - base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - owner interact - value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER ); - struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_owner_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER)); - return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_owner_interact(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool ); - base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - owner control - value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER ); - struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER)); - return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_owner_control(default_media_data); - identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool ); - base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - group interact - value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP ); - struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_group_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP)); - return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_group_interact(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool ); - base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - group control - value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP ); - struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_group_control(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP)); - return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_group_control(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool ); - base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - anyone interact - value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE ); - struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_anyone_interact(const LLMediaEntry& entry): mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE)); - return 0 != ( mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_anyone_interact(default_media_data); - identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool ); - base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // Perms - anyone control - value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE ); - struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool > - { - functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE)); - return 0 != ( mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE ); - }; - - const LLMediaEntry &mMediaEntry; - - } func_perms_anyone_control(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool ); - base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // security - whitelist enable - value_bool = default_media_data.getWhiteListEnable(); - struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool > - { - functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {} - - bool get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getWhiteListEnable(); - return mMediaEntry.getWhiteListEnable(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_whitelist_enable(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool ); - base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY ); - mMediaSettings[ base_key ] = value_bool; - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; - - // security - whitelist URLs - std::vector<std::string> value_vector_str = default_media_data.getWhiteList(); - struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> > - { - functor_getter_whitelist_urls(const LLMediaEntry& entry): mMediaEntry(entry) {} - - std::vector<std::string> get( LLViewerObject* object, S32 face ) - { - if ( object ) - if ( object->getTE(face) ) - if ( object->getTE(face)->getMediaData() ) - return object->getTE(face)->getMediaData()->getWhiteList(); - return mMediaEntry.getWhiteList(); - }; - - const LLMediaEntry &mMediaEntry; - - } func_whitelist_urls(default_media_data); - identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str ); - base_key = std::string( LLMediaEntry::WHITELIST_KEY ); - mMediaSettings[ base_key ].clear(); - std::vector< std::string >::iterator iter = value_vector_str.begin(); - while( iter != value_vector_str.end() ) - { - std::string white_list_url = *iter; - mMediaSettings[ base_key ].append( white_list_url ); - ++iter; - }; - - mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical; -} - diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index ffff564ad4..3bb6492a6e 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -44,7 +44,6 @@ class LLRadioGroup; class LLSlider; class LLTabContainer; class LLTextBox; -class LLMediaCtrl; class LLTool; class LLParcelSelection; class LLObjectSelection; @@ -98,11 +97,6 @@ public: static void setEditTool(void* data); void setTool(const LLSD& user_data); void saveLastTool(); - void onClickBtnDeleteMedia(); - void onClickBtnAddMedia(); - void onClickBtnEditMedia(); - void clearMediaSettings(); - bool selectedMediaEditable(); void updateLandImpacts(); static void setGridMode(S32 mode); @@ -111,13 +105,6 @@ public: private: void refresh(); - void refreshMedia(); - void getMediaState(); - void updateMediaSettings(); - void navigateToTitleMedia( const std::string url ); // navigate if changed - void updateMediaTitle(); - static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); - static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); static void setObjectType( LLPCode pcode ); void onClickGridOptions(); @@ -193,19 +180,12 @@ public: LLParcelSelectionHandle mParcelSelection; LLObjectSelectionHandle mObjectSelection; - LLMediaCtrl *mTitleMedia; - bool mNeedMediaTitle; - private: BOOL mDirty; BOOL mHasSelection; std::map<std::string, std::string> mStatusText; - -protected: - LLSD mMediaSettings; - public: static bool sShowObjectCost; static bool sPreviousFocusOnAvatar; diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp index d5c2ad5f81..917d6dfcd0 100644 --- a/indra/newview/llfloaterurlentry.cpp +++ b/indra/newview/llfloaterurlentry.cpp @@ -112,16 +112,6 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_ panel_media->setMediaType(mime_type); panel_media->setMediaURL(mMediaURLEdit->getValue().asString()); } - else - { - LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get()); - if(panel_face) - { - panel_face->setMediaType(mime_type); - panel_face->setMediaURL(mMediaURLEdit->getValue().asString()); - } - - } getChildView("loading_label")->setVisible( false); closeFloater(); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 09235d8fb2..977023cfe4 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -1008,7 +1008,7 @@ void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui) { mTrackedStatus = LLTracker::TRACKING_NOTHING; LLCtrlListInterface *list = mListFriendCombo; - if (list) + if (list && list->getSelectedValue().asString() != "None") { list->selectByValue( "None" ); } diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 0be748ace9..e395da7f1e 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -327,22 +327,63 @@ void LLFriendCardsManager::syncFriendCardsFolders() /************************************************************************/ /* Private Methods */ /************************************************************************/ -const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const +const LLUUID& LLFriendCardsManager::findFirstCallingCardSubfolder(const LLUUID &parent_id) const { - const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); + if (parent_id.isNull()) + { + return LLUUID::null; + } - std::string friendFolderName = get_friend_folder_name(); + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(parent_id, cats, items); - return findChildFolderUUID(callingCardsFolderID, friendFolderName); + if (!cats || !items || cats->size() == 0) + { + // call failed + return LLUUID::null; + } + + if (cats->size() > 1) + { + const LLViewerInventoryCategory* friendFolder = gInventory.getCategory(parent_id); + if (friendFolder) + { + LL_WARNS_ONCE() << friendFolder->getName() << " folder contains more than one folder" << LL_ENDL; + } + } + + for (LLInventoryModel::cat_array_t::const_iterator iter = cats->begin(); + iter != cats->end(); + ++iter) + { + const LLInventoryCategory* category = (*iter); + if (category->getPreferredType() == LLFolderType::FT_CALLINGCARD) + { + return category->getUUID(); + } + } + + return LLUUID::null; } -const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const +// Inventorry -> +// Calling Cards - > +// Friends - > (the only expected folder) +// All (the only expected folder) + +const LLUUID& LLFriendCardsManager::findFriendFolderUUIDImpl() const { - LLUUID friendFolderUUID = findFriendFolderUUIDImpl(); + const LLUUID callingCardsFolderID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); + + return findFirstCallingCardSubfolder(callingCardsFolderID); +} - std::string friendAllSubfolderName = get_friend_all_subfolder_name(); +const LLUUID& LLFriendCardsManager::findFriendAllSubfolderUUIDImpl() const +{ + LLUUID friendFolderUUID = findFriendFolderUUIDImpl(); - return findChildFolderUUID(friendFolderUUID, friendAllSubfolderName); + return findFirstCallingCardSubfolder(friendFolderUUID); } const LLUUID& LLFriendCardsManager::findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h index 2fb912a930..f5679d7d85 100644 --- a/indra/newview/llfriendcard.h +++ b/indra/newview/llfriendcard.h @@ -116,6 +116,7 @@ private: } const LLUUID& findChildFolderUUID(const LLUUID& parentFolderUUID, const std::string& nonLocalizedName) const; + const LLUUID& findFirstCallingCardSubfolder(const LLUUID &parent_id) const; const LLUUID& findFriendFolderUUIDImpl() const; const LLUUID& findFriendAllSubfolderUUIDImpl() const; const LLUUID& findFriendCardInventoryUUIDImpl(const LLUUID& avatarID); diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h index 91ab445273..7c8e8279c2 100644 --- a/indra/newview/llgesturemgr.h +++ b/indra/newview/llgesturemgr.h @@ -185,7 +185,7 @@ private: std::set<LLUUID> mLoadingAssets; // LLEventHost interface - boost::shared_ptr<LLGestureListener> mListener; + std::shared_ptr<LLGestureListener> mListener; }; #endif diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index d75f3eef6f..38ec24cae8 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -987,9 +987,8 @@ private: //----------------------------------------------------------------------------- F32 gpu_benchmark() { - if (!gGLManager.mHasTimerQuery) + if (gGLManager.mGLVersion < 3.3f) { // don't bother benchmarking venerable drivers which don't support accurate timing anyway - // and are likely to be correctly identified by the GPU table already. return -1.f; } @@ -1115,16 +1114,6 @@ F32 gpu_benchmark() // ensure matched pair of bind() and unbind() calls ShaderBinder binder(gBenchmarkProgram); -#ifdef GL_ARB_vertex_array_object - U32 glarray = 0; - - if (LLRender::sGLCoreProfile) - { - glGenVertexArrays(1, &glarray); - glBindVertexArray(glarray); - } -#endif - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); glFinish(); @@ -1157,15 +1146,6 @@ F32 gpu_benchmark() } } -#ifdef GL_ARB_vertex_array_object - if (LLRender::sGLCoreProfile) - { - glBindVertexArray(0); - glDeleteVertexArrays(1, &glarray); - } -#endif - - std::sort(results.begin(), results.end()); F32 gbps = results[results.size()/2]; diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index e7bc2a9268..84a1278767 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -196,7 +196,7 @@ LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL; // static void LLGroupActions::search() { - LLFloaterReg::showInstance("search"); + LLFloaterReg::showInstance("search", LLSD().with("collection", "groups")); } // static diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 7be35ac260..5952edfc44 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -330,7 +330,7 @@ void LLHUDText::updateVisibility() if (!mSourceObject) { - LL_WARNS() << "HUD text: mSourceObject is NULL, mOnHUDAttachment: " << mOnHUDAttachment << LL_ENDL; + // Beacons mVisible = TRUE; if (mOnHUDAttachment) { diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index b7e0a6a794..98c1d65f92 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -532,7 +532,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& mSessionInitialized(false), mCallBackEnabled(true), mTextIMPossible(true), - mOtherParticipantIsAvatar(true), mStartCallOnInitialize(false), mStartedAsIMCall(voice), mIsDNDsend(false), @@ -544,13 +543,6 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& if (IM_NOTHING_SPECIAL == mType || IM_SESSION_P2P_INVITE == mType) { mVoiceChannel = new LLVoiceChannelP2P(session_id, name, other_participant_id); - mOtherParticipantIsAvatar = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionID); - - // check if it was AVALINE call - if (!mOtherParticipantIsAvatar) - { - mSessionType = AVALINE_SESSION; - } } else { @@ -651,9 +643,6 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES switch(mSessionType) { - case AVALINE_SESSION: - // no text notifications - break; case P2P_SESSION: LLAvatarNameCache::get(mOtherParticipantID, &av_name); other_avatar_name = av_name.getUserName(); @@ -913,11 +902,6 @@ bool LLIMModel::LLIMSession::isGroupChat() return IM_SESSION_GROUP_START == mType || (IM_SESSION_INVITE == mType && gAgent.isInGroup(mSessionID, TRUE)); } -bool LLIMModel::LLIMSession::isOtherParticipantAvaline() -{ - return !mOtherParticipantIsAvatar; -} - LLUUID LLIMModel::LLIMSession::generateOutgoingAdHocHash() const { LLUUID hash = LLUUID::null; @@ -1795,7 +1779,6 @@ LLIMMgr::onConfirmForceCloseError( LLCallDialogManager::LLCallDialogManager(): mPreviousSessionlName(""), -mPreviousSessionType(LLIMModel::LLIMSession::P2P_SESSION), mCurrentSessionlName(""), mSession(NULL), mOldState(LLVoiceChannel::STATE_READY) @@ -1826,12 +1809,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id) mCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution return; } - - if (mSession) - { - // store previous session type to process Avaline calls in dialogs - mPreviousSessionType = mSession->mSessionType; - } mSession = session; @@ -1857,7 +1834,6 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id) mCallDialogPayload["session_name"] = mSession->mName; mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID; mCallDialogPayload["old_channel_name"] = mPreviousSessionlName; - mCallDialogPayload["old_session_type"] = mPreviousSessionType; mCallDialogPayload["state"] = LLVoiceChannel::STATE_CALL_STARTED; mCallDialogPayload["disconnected_channel_name"] = mSession->mName; mCallDialogPayload["session_type"] = mSession->mSessionType; @@ -1893,7 +1869,6 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES mCallDialogPayload["session_name"] = mSession->mName; mCallDialogPayload["other_user_id"] = mSession->mOtherParticipantID; mCallDialogPayload["old_channel_name"] = mPreviousSessionlName; - mCallDialogPayload["old_session_type"] = mPreviousSessionType; mCallDialogPayload["state"] = new_state; mCallDialogPayload["disconnected_channel_name"] = mSession->mName; mCallDialogPayload["session_type"] = mSession->mSessionType; @@ -1910,8 +1885,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES break; case LLVoiceChannel::STATE_HUNG_UP: - // this state is coming before session is changed, so, put it into payload map - mCallDialogPayload["old_session_type"] = mSession->mSessionType; + // this state is coming before session is changed break; case LLVoiceChannel::STATE_CONNECTED : @@ -2031,7 +2005,6 @@ void LLCallDialog::onOpen(const LLSD& key) void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id) { - // *NOTE: 12/28/2009: check avaline calls: LLVoiceClient::isParticipantAvatar returns false for them bool participant_is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id); bool is_group = participant_is_avatar && gAgent.isInGroup(session_id, TRUE); @@ -2052,8 +2025,8 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id) } else { - avatar_icon->setValue("Avaline_Icon"); - avatar_icon->setToolTip(std::string("")); + LL_WARNS() << "Participant neither avatar nor group" << LL_ENDL; + group_icon->setValue(session_id); } } @@ -2097,13 +2070,7 @@ void LLOutgoingCallDialog::show(const LLSD& key) // tell the user which voice channel they are leaving if (!mPayload["old_channel_name"].asString().empty()) { - bool was_avaline_call = LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["old_session_type"].asInteger(); - std::string old_caller_name = mPayload["old_channel_name"].asString(); - if (was_avaline_call) - { - old_caller_name = LLTextUtil::formatPhoneNumber(old_caller_name); - } getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", old_caller_name); show_oldchannel = true; @@ -2116,10 +2083,6 @@ void LLOutgoingCallDialog::show(const LLSD& key) if (!mPayload["disconnected_channel_name"].asString().empty()) { std::string channel_name = mPayload["disconnected_channel_name"].asString(); - if (LLIMModel::LLIMSession::AVALINE_SESSION == mPayload["session_type"].asInteger()) - { - channel_name = LLTextUtil::formatPhoneNumber(channel_name); - } getChild<LLUICtrl>("nearby")->setTextArg("[VOICE_CHANNEL_NAME]", channel_name); // skipping "You will now be reconnected to nearby" in notification when call is ended by disabling voice, @@ -2135,16 +2098,11 @@ void LLOutgoingCallDialog::show(const LLSD& key) std::string callee_name = mPayload["session_name"].asString(); LLUUID session_id = mPayload["session_id"].asUUID(); - bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id); - if (callee_name == "anonymous") + if (callee_name == "anonymous") // obsolete? Likely was part of avaline support { callee_name = getString("anonymous"); } - else if (!is_avatar) - { - callee_name = LLTextUtil::formatPhoneNumber(callee_name); - } LLSD callee_id = mPayload["other_user_id"]; // Beautification: Since you know who you called, just show display name @@ -2344,18 +2302,11 @@ BOOL LLIncomingCallDialog::postBuild() call_type = getString(notify_box_type); } - // check to see if this is an Avaline call - bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id); - if (caller_name == "anonymous") + if (caller_name == "anonymous") // obsolete? Likely was part of avaline support { caller_name = getString("anonymous"); setCallerName(caller_name, caller_name, call_type); } - else if (!is_avatar) - { - caller_name = LLTextUtil::formatPhoneNumber(caller_name); - setCallerName(caller_name, caller_name, call_type); - } else { // Get the full name information @@ -2375,7 +2326,7 @@ BOOL LLIncomingCallDialog::postBuild() if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc") { - // starting notification's timer for P2P and AVALINE invitations + // starting notification's timer for P2P invitations mLifetimeTimer.start(); } else @@ -2384,7 +2335,7 @@ BOOL LLIncomingCallDialog::postBuild() } //it's not possible to connect to existing Ad-Hoc/Group chat through incoming ad-hoc call - //and no IM for avaline + bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id); getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup"); setCanDrag(FALSE); diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 79c831ebb6..fdf9806e2e 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -72,7 +72,6 @@ public: P2P_SESSION, GROUP_SESSION, ADHOC_SESSION, - AVALINE_SESSION, NONE_SESSION, } SType; @@ -92,12 +91,10 @@ public: bool isAdHoc(); bool isP2P(); bool isGroupChat(); - bool isOtherParticipantAvaline(); bool isP2PSessionType() const { return mSessionType == P2P_SESSION;} bool isAdHocSessionType() const { return mSessionType == ADHOC_SESSION;} bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;} - bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;} LLUUID generateOutgoingAdHocHash() const; @@ -136,7 +133,6 @@ public: bool mCallBackEnabled; bool mTextIMPossible; - bool mOtherParticipantIsAvatar; bool mStartCallOnInitialize; //if IM session is created for a voice call @@ -516,7 +512,6 @@ private: protected: std::string mPreviousSessionlName; - LLIMModel::LLIMSession::SType mPreviousSessionType; std::string mCurrentSessionlName; LLIMModel::LLIMSession* mSession; LLVoiceChannel::EState mOldState; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7abe48709b..427e959ce1 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1121,7 +1121,10 @@ void LLInvFVBridge::addMarketplaceContextMenuOptions(U32 flags, LLInventoryModel::cat_array_t categories; LLInventoryModel::item_array_t items; gInventory.collectDescendents(local_version_folder_id, categories, items, FALSE); - if (categories.size() >= gSavedSettings.getU32("InventoryOutboxMaxFolderCount")) + LLCachedControl<U32> max_depth(gSavedSettings, "InventoryOutboxMaxFolderDepth", 4); + LLCachedControl<U32> max_count(gSavedSettings, "InventoryOutboxMaxFolderCount", 20); + if (categories.size() >= max_count + || depth > (max_depth + 1)) { disabled_items.push_back(std::string("New Folder")); } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index c101033a5d..63152d167d 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -135,15 +135,7 @@ bool LLCanCache::operator()(LLInventoryCategory* cat, LLInventoryItem* item) ///---------------------------------------------------------------------------- /// Class LLInventoryValidationInfo ///---------------------------------------------------------------------------- -LLInventoryValidationInfo::LLInventoryValidationInfo(): - mFatalErrorCount(0), - mWarningCount(0), - mLoopCount(0), - mOrphanedCount(0), - mInitialized(false), - mFatalNoRootFolder(false), - mFatalNoLibraryRootFolder(false), - mFatalQADebugMode(false) +LLInventoryValidationInfo::LLInventoryValidationInfo() { } @@ -165,7 +157,6 @@ std::ostream& operator<<(std::ostream& os, const LLInventoryValidationInfo& v) void LLInventoryValidationInfo::asLLSD(LLSD& sd) const { sd["fatal_error_count"] = mFatalErrorCount; - sd["warning_count"] = mWarningCount; sd["loop_count"] = mLoopCount; sd["orphaned_count"] = mOrphanedCount; sd["initialized"] = mInitialized; @@ -173,6 +164,20 @@ void LLInventoryValidationInfo::asLLSD(LLSD& sd) const sd["fatal_no_root_folder"] = mFatalNoRootFolder; sd["fatal_no_library_root_folder"] = mFatalNoLibraryRootFolder; sd["fatal_qa_debug_mode"] = mFatalQADebugMode; + + sd["warning_count"] = mWarningCount; + if (mWarningCount>0) + { + sd["warnings"] = LLSD::emptyArray(); + for (auto const& it : mWarnings) + { + S32 val =LLSD::Integer(it.second); + if (val>0) + { + sd["warnings"][it.first] = val; + } + } + } if (mMissingRequiredSystemFolders.size()>0) { sd["missing_system_folders"] = LLSD::emptyArray(); @@ -342,13 +347,13 @@ const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LL return NULL; } -LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const +LLInventoryModel::EAncestorResult LLInventoryModel::getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const { LLInventoryObject *object = getObject(object_id); if (!object) { LL_WARNS(LOG_INV) << "Unable to trace topmost ancestor, initial object " << object_id << " does not exist" << LL_ENDL; - return ANSCESTOR_MISSING; + return ANCESTOR_MISSING; } std::set<LLUUID> object_ids{ object_id }; // loop protection @@ -358,19 +363,19 @@ LLInventoryModel::EAnscestorResult LLInventoryModel::getObjectTopmostAncestor(co if (object_ids.find(parent_id) != object_ids.end()) { LL_WARNS(LOG_INV) << "Detected a loop on an object " << parent_id << " when searching for ancestor of " << object_id << LL_ENDL; - return ANSCESTOR_LOOP; + return ANCESTOR_LOOP; } object_ids.insert(parent_id); LLInventoryObject *parent_object = getObject(parent_id); if (!parent_object) { LL_WARNS(LOG_INV) << "unable to trace topmost ancestor of " << object_id << ", missing item for uuid " << parent_id << LL_ENDL; - return ANSCESTOR_MISSING; + return ANCESTOR_MISSING; } object = parent_object; } result = object->getUUID(); - return ANSCESTOR_OK; + return ANCESTOR_OK; } // Get the object by id. Returns NULL if not found. @@ -539,9 +544,18 @@ void LLInventoryModel::consolidateForType(const LLUUID& main_id, LLFolderType::E LLViewerInventoryCategory* cat = getCategory(*it); changeCategoryParent(cat, main_id, TRUE); } - + // Purge the emptied folder - removeCategory(folder_id); + // Note that this might be a system folder, don't validate removability + LLViewerInventoryCategory* cat = getCategory(folder_id); + if (cat) + { + const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (trash_id.notNull()) + { + changeCategoryParent(cat, trash_id, TRUE); + } + } remove_inventory_category(folder_id, NULL); } } @@ -628,6 +642,11 @@ const LLUUID LLInventoryModel::findUserDefinedCategoryUUIDForType(LLFolderType:: cat_id = LLUUID(gSavedPerAccountSettings.getString("AnimationUploadFolder")); break; } + case LLFolderType::FT_MATERIAL: + { + cat_id = LLUUID(gSavedPerAccountSettings.getString("PBRUploadFolder")); + break; + } default: break; } @@ -3896,9 +3915,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LLPointer<LLInventoryValidationInfo> validation_info = new LLInventoryValidationInfo; S32 fatal_errs = 0; - S32 warnings = 0; - S32 loops = 0; - S32 orphaned = 0; + S32 warning_count= 0; + S32 loop_count = 0; + S32 orphaned_count = 0; if (getRootFolderID().isNull()) { @@ -3919,7 +3938,9 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const // ParentChild should be one larger because of the special entry for null uuid. LL_INFOS("Inventory") << "unexpected sizes: cat map size " << mCategoryMap.size() << " parent/child " << mParentChildCategoryTree.size() << LL_ENDL; - warnings++; + + validation_info->mWarnings["category_map_size"]++; + warning_count++; } S32 cat_lock = 0; S32 item_lock = 0; @@ -3938,32 +3959,35 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (!cat) { LL_WARNS("Inventory") << "null cat" << LL_ENDL; - warnings++; + validation_info->mWarnings["null_cat"]++; + warning_count++; continue; } LLUUID topmost_ancestor_id; // Will leave as null uuid on failure - EAnscestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id); + EAncestorResult res = getObjectTopmostAncestor(cat_id, topmost_ancestor_id); switch (res) { - case ANSCESTOR_MISSING: - orphaned++; + case ANCESTOR_MISSING: + orphaned_count++; break; - case ANSCESTOR_LOOP: - loops++; + case ANCESTOR_LOOP: + loop_count++; break; - case ANSCESTOR_OK: + case ANCESTOR_OK: break; default: LL_WARNS("Inventory") << "Unknown ancestor error for " << cat_id << LL_ENDL; - warnings++; + validation_info->mWarnings["unknown_ancestor_status"]++; + warning_count++; break; } if (cat_id != cat->getUUID()) { LL_WARNS("Inventory") << "cat id/index mismatch " << cat_id << " " << cat->getUUID() << LL_ENDL; - warnings++; + validation_info->mWarnings["cat_id_index_mismatch"]++; + warning_count++; } if (cat->getParentUUID().isNull()) @@ -3973,7 +3997,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const LL_WARNS("Inventory") << "cat " << cat_id << " has no parent, but is not root (" << getRootFolderID() << ") or library root (" << getLibraryRootFolderID() << ")" << LL_ENDL; - warnings++; + validation_info->mWarnings["null_parent"]++; + warning_count++; } } cat_array_t* cats; @@ -3982,7 +4007,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (!cats || !items) { LL_WARNS("Inventory") << "invalid direct descendents for " << cat_id << LL_ENDL; - warnings++; + validation_info->mWarnings["direct_descendents"]++; + warning_count++; continue; } if (cat->getDescendentCount() == LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN) @@ -4000,7 +4026,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const << " cached " << cat->getDescendentCount() << " expected " << cats->size() << "+" << items->size() << "=" << cats->size() +items->size() << LL_ENDL; - warnings++; + validation_info->mWarnings["invalid_descendent_count"]++; + warning_count++; } } if (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN) @@ -4024,7 +4051,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (!item) { LL_WARNS("Inventory") << "null item at index " << i << " for cat " << cat_id << LL_ENDL; - warnings++; + validation_info->mWarnings["null_item_at_index"]++; + warning_count++; continue; } @@ -4035,7 +4063,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const LL_WARNS("Inventory") << "wrong parent for " << item_id << " found " << item->getParentUUID() << " expected " << cat_id << LL_ENDL; - warnings++; + validation_info->mWarnings["wrong_parent_for_item"]++; + warning_count++; } @@ -4045,7 +4074,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "item " << item_id << " found as child of " << cat_id << " but not in top level mItemMap" << LL_ENDL; - warnings++; + validation_info->mWarnings["item_not_in_top_map"]++; + warning_count++; } else { @@ -4059,11 +4089,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const // Topmost ancestor should be root or library. LLUUID topmost_ancestor_id; - EAnscestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); - if (found != ANSCESTOR_OK) + EAncestorResult found = getObjectTopmostAncestor(item_id, topmost_ancestor_id); + if (found != ANCESTOR_OK) { LL_WARNS("Inventory") << "unable to find topmost ancestor for " << item_id << LL_ENDL; - warnings++; + validation_info->mWarnings["topmost_ancestor_not_found"]++; + warning_count++; } else { @@ -4074,7 +4105,8 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const << " got " << topmost_ancestor_id << " expected " << getRootFolderID() << " or " << getLibraryRootFolderID() << LL_ENDL; - warnings++; + validation_info->mWarnings["topmost_ancestor_not_recognized"]++; + warning_count++; } } } @@ -4090,7 +4122,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName() << "] orphaned - no child cat array for alleged parent " << parent_id << LL_ENDL; - orphaned++; + orphaned_count++; } else { @@ -4108,7 +4140,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "cat " << cat_id << " name [" << cat->getName() << "] orphaned - not found in child cat array of alleged parent " << parent_id << LL_ENDL; - orphaned++; + orphaned_count++; } } } @@ -4117,7 +4149,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const LLFolderType::EType folder_type = cat->getPreferredType(); bool cat_is_in_library = false; LLUUID topmost_id; - if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANSCESTOR_OK && topmost_id == getLibraryRootFolderID()) + if (getObjectTopmostAncestor(cat->getUUID(),topmost_id) == ANCESTOR_OK && topmost_id == getLibraryRootFolderID()) { cat_is_in_library = true; } @@ -4150,14 +4182,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (item->getUUID() != item_id) { LL_WARNS("Inventory") << "item_id " << item_id << " does not match " << item->getUUID() << LL_ENDL; - warnings++; + validation_info->mWarnings["item_id_mismatch"]++; + warning_count++; } const LLUUID& parent_id = item->getParentUUID(); if (parent_id.isNull()) { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] has null parent id!" << LL_ENDL; - orphaned++; + orphaned_count++; } else { @@ -4168,7 +4201,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] orphaned - alleged parent has no child items list " << parent_id << LL_ENDL; - orphaned++; + orphaned_count++; } else { @@ -4185,7 +4218,7 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const { LL_WARNS("Inventory") << "item " << item_id << " name [" << item->getName() << "] orphaned - not found as child of alleged parent " << parent_id << LL_ENDL; - orphaned++; + orphaned_count++; } } @@ -4203,18 +4236,18 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const LL_WARNS("Inventory") << "link " << item->getUUID() << " type " << item->getActualType() << " missing backlink info at target_id " << target_id << LL_ENDL; - orphaned++; + orphaned_count++; } // Links should have referents. if (item->getActualType() == LLAssetType::AT_LINK && !target_item) { LL_WARNS("Inventory") << "broken item link " << item->getName() << " id " << item->getUUID() << LL_ENDL; - orphaned++; + orphaned_count++; } else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER && !target_cat) { LL_WARNS("Inventory") << "broken folder link " << item->getName() << " id " << item->getUUID() << LL_ENDL; - orphaned++; + orphaned_count++; } if (target_item && target_item->getIsLinkType()) { @@ -4286,23 +4319,30 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const if (is_automatic) { LL_WARNS("Inventory") << "Fatal inventory corruption: cannot create system folder of type " << ft << LL_ENDL; - fatal_errs++; validation_info->mMissingRequiredSystemFolders.insert(folder_type); + fatal_errs++; } else { // Can create, and will when needed. - warnings++; + // (Not sure this is really a warning, but worth logging) + validation_info->mWarnings["missing_system_folder_can_create"]++; + warning_count++; } } else if (count_under_root > 1) { LL_WARNS("Inventory") << "Fatal inventory corruption: system folder type has excess copies under root, type " << ft << " count " << count_under_root << LL_ENDL; validation_info->mDuplicateRequiredSystemFolders.insert(folder_type); - if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS) + if (!is_automatic + && folder_type != LLFolderType::FT_SETTINGS + // FT_MATERIAL might need to be automatic like the rest of upload folders + && folder_type != LLFolderType::FT_MATERIAL + ) { // It is a fatal problem or can lead to fatal problems for COF, // outfits, trash and other non-automatic folders. + validation_info->mFatalSystemDuplicate++; fatal_errs++; } else @@ -4310,13 +4350,15 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const // For automatic folders it's not a fatal issue and shouldn't // break inventory or other functionality further // Exception: FT_SETTINGS is not automatic, but only deserves a warning. - warnings++; + validation_info->mWarnings["non_fatal_system_duplicate_under_root"]++; + warning_count++; } } if (count_elsewhere > 0) { LL_WARNS("Inventory") << "Found " << count_elsewhere << " extra folders of type " << ft << " outside of root" << LL_ENDL; - warnings++; + validation_info->mWarnings["non_fatal_system_duplicate_elsewhere"]++; + warning_count++; } } } @@ -4338,12 +4380,12 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const // FIXME need to fail login and tell user to retry, contact support if problem persists. bool valid = (fatal_errs == 0); - LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warnings << ", valid: " << valid << LL_ENDL; + LL_INFOS("Inventory") << "Validate done, fatal errors: " << fatal_errs << ", warnings: " << warning_count << ", valid: " << valid << LL_ENDL; validation_info->mFatalErrorCount = fatal_errs; - validation_info->mWarningCount = warnings; - validation_info->mLoopCount = loops; - validation_info->mOrphanedCount = orphaned; + validation_info->mWarningCount = warning_count; + validation_info->mLoopCount = loop_count; + validation_info->mOrphanedCount = orphaned_count; return validation_info; } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index 85343cf95c..cb960d8185 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -65,15 +65,19 @@ public: void toOstream(std::ostream& os) const; void asLLSD(LLSD& sd) const; + bool mInitialized{false}; + S32 mWarningCount{0}; + std::map<std::string,U32> mWarnings; + + S32 mLoopCount{0}; // Presence of folders whose ancestors loop onto themselves + S32 mOrphanedCount{0}; // Missing or orphaned items, links and folders + + S32 mFatalErrorCount{0}; + bool mFatalNoRootFolder{false}; + S32 mFatalSystemDuplicate{0}; + bool mFatalNoLibraryRootFolder{false}; + bool mFatalQADebugMode{false}; - S32 mFatalErrorCount; - S32 mWarningCount; - S32 mLoopCount; // Presence of folders whose ansestors loop onto themselves - S32 mOrphanedCount; // Missing or orphaned items, links and folders - bool mInitialized; - bool mFatalNoRootFolder; - bool mFatalNoLibraryRootFolder; - bool mFatalQADebugMode; std::set<LLFolderType::EType> mMissingRequiredSystemFolders; std::set<LLFolderType::EType> mDuplicateRequiredSystemFolders; }; @@ -286,13 +290,13 @@ public: // Check if one object has a parent chain up to the category specified by UUID. BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const; - enum EAnscestorResult{ - ANSCESTOR_OK = 0, - ANSCESTOR_MISSING = 1, - ANSCESTOR_LOOP = 2, + enum EAncestorResult{ + ANCESTOR_OK = 0, + ANCESTOR_MISSING = 1, + ANCESTOR_LOOP = 2, }; // Follow parent chain to the top. - EAnscestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; + EAncestorResult getObjectTopmostAncestor(const LLUUID& object_id, LLUUID& result) const; //-------------------------------------------------------------------- // Find diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index cd24b3ea43..bc035fc2f6 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -1612,6 +1612,10 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata) { gSavedPerAccountSettings.setString("AnimationUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); } + else if (param == "pbr_material") + { + gSavedPerAccountSettings.setString("PBRUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); + } } void LLInventoryPanel::purgeSelectedItems() @@ -2150,6 +2154,7 @@ namespace LLInitParam declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX); declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT); declare(LLFolderType::lookup(LLFolderType::FT_SETTINGS) , LLFolderType::FT_SETTINGS); + declare(LLFolderType::lookup(LLFolderType::FT_MATERIAL) , LLFolderType::FT_MATERIAL); declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_LISTINGS) , LLFolderType::FT_MARKETPLACE_LISTINGS); declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_STOCK), LLFolderType::FT_MARKETPLACE_STOCK); declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_VERSION), LLFolderType::FT_MARKETPLACE_VERSION); diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 79dbe17982..af2a9f6afd 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -109,6 +109,8 @@ public: LLLineEditor* getTextEntry() const { return mTextEntry; } void handleLoginComplete(); + bool isNavMeshDirty() { return mIsNavMeshDirty; } + private: enum EParcelIcon diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 044c76ce2c..dd4ae4d201 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -758,7 +758,14 @@ void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type& if (mMarketPlaceStatus != MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED) { // If already initialized, just confirm the status so the callback gets called - setSLMStatus(mMarketPlaceStatus); + if (mMarketPlaceFailureReason.empty()) + { + setSLMStatus(mMarketPlaceStatus); + } + else + { + setSLMConnectionFailure(mMarketPlaceFailureReason); + } } else { @@ -799,28 +806,27 @@ void LLMarketplaceData::getMerchantStatusCoro() if (httpCode == HTTP_NOT_FOUND) { log_SLM_infos("Get /merchant", httpCode, std::string("User is not a merchant")); - setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT); + LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MERCHANT); } else if (httpCode == HTTP_SERVICE_UNAVAILABLE) { log_SLM_infos("Get /merchant", httpCode, std::string("Merchant is not migrated")); - setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT); + LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_MIGRATED_MERCHANT); } - else if (httpCode == HTTP_INTERNAL_ERROR) + else { - // 499 includes timeout and ssl error - marketplace is down or having issues, we do not show it in this request according to MAINT-5938 LL_WARNS("SLM") << "SLM Merchant Request failed with status: " << httpCode << ", reason : " << status.toString() << ", code : " << result["error_code"].asString() << ", description : " << result["error_description"].asString() << LL_ENDL; - LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); - } - else - { - std::string err_code = result["error_code"].asString(); - //std::string err_description = result["error_description"].asString(); - log_SLM_warning("Get /merchant", httpCode, status.toString(), err_code, result["error_description"]); - setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE); + std::string reason = status.toString(); + if (reason.empty()) + { + reason = result["error_code"].asString(); + } + // Since user might not even have a marketplace, there is no reason to report the error + // to the user, instead write it down into listings' floater + LLMarketplaceData::instance().setSLMConnectionFailure(reason); } return; } @@ -1298,6 +1304,17 @@ std::string LLMarketplaceData::getSLMConnectURL(const std::string& route) void LLMarketplaceData::setSLMStatus(U32 status) { mMarketPlaceStatus = status; + mMarketPlaceFailureReason.clear(); + if (mStatusUpdatedSignal) + { + (*mStatusUpdatedSignal)(); + } +} + +void LLMarketplaceData::setSLMConnectionFailure(const std::string& reason) +{ + mMarketPlaceStatus = MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE; + mMarketPlaceFailureReason = reason; if (mStatusUpdatedSignal) { (*mStatusUpdatedSignal)(); diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index fee9225f77..088507d850 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -198,7 +198,9 @@ public: typedef boost::signals2::signal<void ()> status_updated_signal_t; void initializeSLM(const status_updated_signal_t::slot_type& cb); U32 getSLMStatus() const { return mMarketPlaceStatus; } + std::string getSLMConnectionfailureReason() { return mMarketPlaceFailureReason; } void setSLMStatus(U32 status); + void setSLMConnectionFailure(const std::string& reason); void getSLMListings(); bool isEmpty() { return (mMarketplaceItems.size() == 0); } void setDataFetchedSignal(const status_updated_signal_t::slot_type& cb); @@ -272,6 +274,7 @@ private: // Handling Marketplace connection and inventory connection U32 mMarketPlaceStatus; + std::string mMarketPlaceFailureReason; status_updated_signal_t* mStatusUpdatedSignal; LLInventoryObserver* mInventoryObserver; bool mDirtyCount; // If true, stock count value need to be updated at the next check diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 6461aa71a6..bdc66a85fc 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -204,14 +204,14 @@ void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id) LLColor4 LLMaterialEditor::getAlbedoColor() { - LLColor4 ret = LLColor4(childGetValue("albedo color")); + LLColor4 ret = linearColor4(LLColor4(childGetValue("albedo color"))); ret.mV[3] = getTransparency(); return ret; } void LLMaterialEditor::setAlbedoColor(const LLColor4& color) { - childSetValue("albedo color", color.getValue()); + childSetValue("albedo color", srgbColor4(color).getValue()); setTransparency(color.mV[3]); } @@ -761,8 +761,8 @@ bool LLMaterialEditor::saveIfNeeded() tid.generate(); // timestamp-based randomization + uniquification LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); std::string res_desc = buildMaterialDescription(); - U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); - LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Uploads"); + LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index 142977e939..d3b981e205 100644 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -154,8 +154,7 @@ void mark_dead_and_remove_if(T &c, const PredicateMatchRequest &matchPred) if (matchPred(*it)) { (*it)->markDead(); - // *TDOO: When C++11 is in change the following line to: it = c.erase(it); - c.erase(it++); + it = c.erase(it); } else { diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 6fa71e130e..5b2326336b 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -383,6 +383,9 @@ U32 LLMeshRepository::sLODPending = 0; U32 LLMeshRepository::sCacheBytesRead = 0; U32 LLMeshRepository::sCacheBytesWritten = 0; +U32 LLMeshRepository::sCacheBytesHeaders = 0; +U32 LLMeshRepository::sCacheBytesSkins = 0; +U32 LLMeshRepository::sCacheBytesDecomps = 0; U32 LLMeshRepository::sCacheReads = 0; U32 LLMeshRepository::sCacheWrites = 0; U32 LLMeshRepository::sMaxLockHoldoffs = 0; @@ -1874,6 +1877,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes LLMutexLock lock(mHeaderMutex); mMeshHeaderSize[mesh_id] = header_size; mMeshHeader[mesh_id] = header; + LLMeshRepository::sCacheBytesHeaders += header_size; } @@ -3013,27 +3017,6 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) return -1; } -void LLMeshRepository::cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header) -{ - mThread->mMeshHeader[data.mUUID] = header; - - // we cache the mesh for default parameters - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - volume_params.setSculptID(data.mUUID, LL_SCULPT_TYPE_MESH); - - for (U32 i = 0; i < 4; i++) - { - if (data.mModel[i].notNull()) - { - LLPointer<LLVolume> volume = new LLVolume(volume_params, LLVolumeLODGroup::getVolumeScaleFromDetail(i)); - volume->copyVolumeFaces(data.mModel[i]); - volume->setMeshAssetLoaded(TRUE); - } - } - -} - // Handle failed or successful requests for mesh assets. // // Support for 200 responses was added for several reasons. One, @@ -3951,6 +3934,8 @@ void LLMeshRepository::notifyLoadedMeshes() void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) { mSkinMap[info.mMeshID] = info; + // Alternative: We can get skin size from header + sCacheBytesSkins += info.sizeBytes(); skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID); if (iter != mLoadingSkins.end()) @@ -3974,10 +3959,14 @@ void LLMeshRepository::notifyDecompositionReceived(LLModel::Decomposition* decom { //just insert decomp into map mDecompositionMap[decomp->mMeshID] = decomp; mLoadingDecompositions.erase(decomp->mMeshID); + sCacheBytesDecomps += decomp->sizeBytes(); } else { //merge decomp with existing entry + sCacheBytesDecomps -= iter->second->sizeBytes(); iter->second->merge(decomp); + sCacheBytesDecomps += iter->second->sizeBytes(); + mLoadingDecompositions.erase(decomp->mMeshID); delete decomp; } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 5459bbb4af..6fe4ea5514 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -552,6 +552,9 @@ public: static U32 sLODProcessing; static U32 sCacheBytesRead; static U32 sCacheBytesWritten; + static U32 sCacheBytesHeaders; + static U32 sCacheBytesSkins; + static U32 sCacheBytesDecomps; static U32 sCacheReads; static U32 sCacheWrites; static U32 sMaxLockHoldoffs; // Maximum sequential locking failures @@ -641,8 +644,6 @@ public: std::queue<LLUUID> mPendingPhysicsShapeRequests; U32 mMeshThreadCount; - - void cacheOutgoingMesh(LLMeshUploadData& data, LLSD& header); LLMeshRepoThread* mThread; std::vector<LLMeshUploadThread*> mUploads; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index c3fbada9db..076ebd80c2 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1308,7 +1308,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // extra space for normals and text coords S32 tc_bytes_size = ((size_vertices * sizeof(LLVector2)) + 0xF) & ~0xF; - LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size); + LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size); LLVector4a* combined_normals = combined_positions + size_vertices; LLVector2* combined_tex_coords = (LLVector2*)(combined_normals + size_vertices); @@ -1428,7 +1428,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // IV. Repack back into individual faces - LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size); + LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size); LLVector4a* buffer_normals = buffer_positions + size_vertices; LLVector2* buffer_tex_coords = (LLVector2*)(buffer_normals + size_vertices); S32 buffer_idx_size = (size_indices * sizeof(U16) + 0xF) & ~0xF; @@ -1549,7 +1549,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { new_face.resizeIndices(buf_indices_copied); new_face.resizeVertices(buf_positions_copied); - + new_face.allocateTangents(buf_positions_copied, true); S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF; LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size); @@ -1833,6 +1833,15 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d LLModel* target_model = mModel[lod][mdl_idx]; + // carry over normalized transform into simplified model + for (int i = 0; i < base->getNumVolumeFaces(); ++i) + { + LLVolumeFace& src = base->getVolumeFace(i); + LLVolumeFace& dst = target_model->getVolumeFace(i); + dst.mNormalizedScale = src.mNormalizedScale; + dst.mNormalizedTranslation = src.mNormalizedTranslation; + } + S32 model_meshopt_mode = meshopt_mode; // Ideally this should run not per model, @@ -2736,7 +2745,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) continue; } - LLModel* base_mdl = *base_iter; base_iter++; S32 num_faces = mdl->getNumVolumeFaces(); @@ -2811,7 +2819,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) //find closest weight to vf.mVertices[i].mPosition LLVector3 pos(vf.mPositions[i].getF32ptr()); - const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); + const LLModel::weight_list& weight_list = mdl->getJointInfluences(pos); llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this LLVector4 w(0, 0, 0, 0); @@ -2938,6 +2946,20 @@ void LLModelPreview::loadedCallback( { pPreview->lookupLODModelFiles(lod); } + + const LLVOAvatar* avatarp = pPreview->getPreviewAvatar(); + if (avatarp) { // set up ground plane for possible rendering + const LLVector3 root_pos = avatarp->mRoot->getPosition(); + const LLVector4a* ext = avatarp->mDrawable->getSpatialExtents(); + const LLVector4a min = ext[0], max = ext[1]; + const F32 center = (max[2] - min[2]) * 0.5f; + const F32 ground = root_pos[2] - center; + auto plane = pPreview->mGroundPlane; + plane[0] = {min[0], min[1], ground}; + plane[1] = {max[0], min[1], ground}; + plane[2] = {max[0], max[1], ground}; + plane[3] = {min[0], max[1], ground}; + } } } @@ -3145,6 +3167,9 @@ BOOL LLModelPreview::render() // (note: all these UI updates need to be somewhere that is not render) fmp->childSetValue("upload_skin", true); mFirstSkinUpdate = false; + upload_skin = true; + skin_weight = true; + mViewOption["show_skin_weight"] = true; } fmp->enableViewOption("show_skin_weight"); @@ -3749,6 +3774,7 @@ BOOL LLModelPreview::render() { getPreviewAvatar()->renderBones(); } + renderGroundPlane(mPelvisZOffset); if (shader) { shader->bind(); @@ -3770,6 +3796,28 @@ BOOL LLModelPreview::render() return TRUE; } +void LLModelPreview::renderGroundPlane(float z_offset) +{ // Not necesarilly general - beware - but it seems to meet the needs of LLModelPreview::render + + gGL.diffuseColor3f( 1.0f, 0.0f, 1.0f ); + + gGL.begin(LLRender::LINES); + gGL.vertex3fv(mGroundPlane[0].mV); + gGL.vertex3fv(mGroundPlane[1].mV); + + gGL.vertex3fv(mGroundPlane[1].mV); + gGL.vertex3fv(mGroundPlane[2].mV); + + gGL.vertex3fv(mGroundPlane[2].mV); + gGL.vertex3fv(mGroundPlane[3].mV); + + gGL.vertex3fv(mGroundPlane[3].mV); + gGL.vertex3fv(mGroundPlane[0].mV); + + gGL.end(); +} + + //----------------------------------------------------------------------------- // refresh() //----------------------------------------------------------------------------- diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 215f44357f..7cb5fd6845 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -224,6 +224,8 @@ private: LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; } // Count amount of original models, excluding sub-models static U32 countRootModels(LLModelLoader::model_list models); + LLVector3 mGroundPlane[4]; + void renderGroundPlane(float z_offset = 0.0f); typedef enum { diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 4a8ef53a8b..bf00d77dea 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -352,7 +352,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags) void LLMuteList::updateAdd(const LLMute& mute) { - // External mutes (e.g. Avaline callers) are local only, don't send them to the server. + // External mutes are local only, don't send them to the server. if (mute.mType == LLMute::EXTERNAL) { return; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 5215126789..8058faa5c7 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -271,6 +271,25 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) return handled; } +// virtual +BOOL LLNameListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y)); + LLFloater* floater = gFloaterView->getParentFloater(this); + if (floater && floater->isFrontmost() && hit_item) + { + if(hit_item->isGroup()) + { + ContextMenuType prev_menu = getContextMenuType(); + setContextMenu(MENU_GROUP); + BOOL handled = LLScrollListCtrl::handleRightMouseDown(x, y, mask); + setContextMenu(prev_menu); + return handled; + } + } + return LLScrollListCtrl::handleRightMouseDown(x, y, mask); +} + // public void LLNameListCtrl::addGroupNameItem(const LLUUID& group_id, EAddPosition pos, BOOL enabled) diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index ef0be135e6..5dd5da5892 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -170,6 +170,7 @@ public: /*virtual*/ void updateColumns(bool force_update); /*virtual*/ void mouseOverHighlightNthItem( S32 index ); + /*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); private: void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false); void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item); diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 19dbbeb60e..2dd7cfab27 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -713,7 +713,7 @@ void LLNavigationBar::resizeLayoutPanel() } void LLNavigationBar::invokeSearch(std::string search_text) { - LLFloaterReg::showInstance("search", LLSD().with("category", "all").with("query", LLSD(search_text))); + LLFloaterReg::showInstance("search", LLSD().with("category", "standard").with("query", LLSD(search_text))); } void LLNavigationBar::clearHistoryCache() @@ -733,3 +733,8 @@ int LLNavigationBar::getDefFavBarHeight() { return mDefaultFpRect.getHeight(); } + +bool LLNavigationBar::isRebakeNavMeshAvailable() +{ + return mCmbLocation->isNavMeshDirty(); +} diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h index 646911a62c..11c671294a 100755 --- a/indra/newview/llnavigationbar.h +++ b/indra/newview/llnavigationbar.h @@ -102,6 +102,8 @@ public: int getDefNavBarHeight(); int getDefFavBarHeight(); + + bool isRebakeNavMeshAvailable(); private: // the distance between navigation panel and favorites panel in pixels diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 9a030f1d7d..ff33efe4aa 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -120,7 +120,7 @@ void LLPanelProfileTab::setApplyProgress(bool started) } } - LLPanel* panel = findChild<LLPanel>("indicator_stack"); + LLView* panel = findChild<LLView>("indicator_stack"); if (panel) { panel->setVisible(started); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 6e897e2c7e..ea10aa75ae 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1308,7 +1308,8 @@ void LLPanelEditWearable::changeCamera(U8 subpart) gMorphView->setCameraOffset( subpart_entry->mCameraOffset ); if (gSavedSettings.getBOOL("AppearanceCameraMovement")) { - gAgentCamera.setFocusOnAvatar(FALSE, FALSE); + // Unlock focus from avatar but don't stop animation to not interrupt ANIM_AGENT_CUSTOMIZE + gAgentCamera.setFocusOnAvatar(FALSE, gAgentCamera.getCameraAnimating()); gMorphView->updateCamera(); } } diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index ac4c76351d..6498215e94 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -49,11 +49,15 @@ #include "llinventoryfunctions.h" #include "llinventorymodel.h" // gInventory #include "llinventorymodelbackgroundfetch.h" +#include "llfloatermediasettings.h" +#include "llfloaterreg.h" #include "lllineeditor.h" #include "llmaterialmgr.h" +#include "llmediactrl.h" #include "llmediaentry.h" #include "llmenubutton.h" #include "llnotificationsutil.h" +#include "llpanelcontents.h" #include "llradiogroup.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -115,10 +119,9 @@ std::string USE_TEXTURE; LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit() { - LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); - LLRender::eTexIndex channel_to_edit = (combobox_matmedia && combobox_matmedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? + LLRender::eTexIndex channel_to_edit = (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? (radio_mat_type ? (LLRender::eTexIndex)radio_mat_type->getSelectedIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP; channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit; @@ -177,6 +180,8 @@ BOOL LLPanelFace::postBuild() childSetCommitCallback("glossiness",&LLPanelFace::onCommitMaterialGloss, this); childSetCommitCallback("environment",&LLPanelFace::onCommitMaterialEnv, this); childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); + childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this); + childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this); childSetAction("button align",&LLPanelFace::onClickAutoFix,this); childSetAction("button align textures", &LLPanelFace::onAlignTexture, this); @@ -321,11 +326,11 @@ BOOL LLPanelFace::postBuild() mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP); } - LLComboBox* combo_mat_media = findChild<LLComboBox>("combobox matmedia"); - if(combo_mat_media) + mComboMatMedia = getChild<LLComboBox>("combobox matmedia"); + if(mComboMatMedia) { - combo_mat_media->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this); - combo_mat_media->selectNthItem(MATMEDIA_MATERIAL); + mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this); + mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); } LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type"); @@ -350,6 +355,9 @@ BOOL LLPanelFace::postBuild() mMenuClipboardColor = getChild<LLMenuButton>("clipboard_color_params_btn"); mMenuClipboardTexture = getChild<LLMenuButton>("clipboard_texture_params_btn"); + + mTitleMedia = getChild<LLMediaCtrl>("title_media"); + mTitleMediaText = getChild<LLTextBox>("media_info"); clearCtrls(); @@ -358,24 +366,31 @@ BOOL LLPanelFace::postBuild() LLPanelFace::LLPanelFace() : LLPanel(), - mIsAlpha(false) + mIsAlpha(false), + mComboMatMedia(NULL), + mTitleMedia(NULL), + mTitleMediaText(NULL), + mNeedMediaTitle(true) { USE_TEXTURE = LLTrans::getString("use_texture"); mCommitCallbackRegistrar.add("PanelFace.menuDoToSelected", boost::bind(&LLPanelFace::menuDoToSelected, this, _2)); mEnableCallbackRegistrar.add("PanelFace.menuEnable", boost::bind(&LLPanelFace::menuEnableItem, this, _2)); } - LLPanelFace::~LLPanelFace() { - // Children all cleaned up by default view destructor. + unloadMedia(); } - void LLPanelFace::draw() { updateCopyTexButton(); + // grab media name/title and update the UI widget + // Todo: move it, it's preferable not to update + // labels inside draw + updateMediaTitle(); + LLPanel::draw(); } @@ -866,14 +881,13 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced(); // only turn on auto-adjust button if there is a media renderer and the media is loaded - getChildView("button align")->setEnabled(editable); + childSetEnabled("button align", editable); - LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); - if (combobox_matmedia->getCurrentIndex() < MATMEDIA_MATERIAL) + if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL) { - combobox_matmedia->selectNthItem(MATMEDIA_MATERIAL); + mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL); } - combobox_matmedia->setEnabled(editable); + mComboMatMedia->setEnabled(editable); LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE) @@ -926,22 +940,22 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) { getChildView("color label")->setEnabled(editable && !has_pbr_material); } - LLColorSwatchCtrl* mColorSwatch = findChild<LLColorSwatchCtrl>("colorswatch"); + LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch"); LLColor4 color = LLColor4::white; bool identical_color = false; - if(mColorSwatch) + if(color_swatch) { LLSelectedTE::getColor(color, identical_color); - LLColor4 prev_color = mColorSwatch->get(); + LLColor4 prev_color = color_swatch->get(); - mColorSwatch->setOriginal(color); - mColorSwatch->set(color, force_set_values || (prev_color != color) || !editable); + color_swatch->setOriginal(color); + color_swatch->set(color, force_set_values || (prev_color != color) || !editable); - mColorSwatch->setValid(editable && !has_pbr_material); - mColorSwatch->setEnabled(editable && !has_pbr_material); - mColorSwatch->setCanApplyImmediately( editable ); + color_swatch->setValid(editable); + color_swatch->setEnabled( editable ); + color_swatch->setCanApplyImmediately( editable ); } // Color transparency @@ -1090,10 +1104,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) texture_ctrl->setTentative(FALSE); texture_ctrl->setEnabled(editable); texture_ctrl->setImageAssetID(id); - getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); - getChildView("label alphamode")->setEnabled(editable && mIsAlpha); - getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); - getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material); + getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material); + getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); + getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); texture_ctrl->setBakeTextureEnabled(TRUE); } @@ -1116,10 +1130,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) texture_ctrl->setTentative(TRUE); texture_ctrl->setEnabled(editable); texture_ctrl->setImageAssetID(id); - getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); - getChildView("label alphamode")->setEnabled(editable && mIsAlpha); - getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); - getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material); + getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material); + getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); + getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material); texture_ctrl->setBakeTextureEnabled(TRUE); } @@ -1208,7 +1222,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s); getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s); - if (combobox_matmedia->getCurrentIndex() == MATMEDIA_PBR) + if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR) { getChildView("TexScaleU")->setEnabled(editable && has_pbr_material); getChildView("shinyScaleU")->setEnabled(editable && has_pbr_material); @@ -1256,7 +1270,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) BOOL norm_scale_tentative = !identical_norm_scale_t; BOOL spec_scale_tentative = !identical_spec_scale_t; - if (combobox_matmedia->getCurrentIndex() == MATMEDIA_PBR) + if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR) { getChildView("TexScaleV")->setEnabled(editable && has_pbr_material); getChildView("shinyScaleV")->setEnabled(editable && has_pbr_material); @@ -1311,7 +1325,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative)); getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative)); - if (combobox_matmedia->getCurrentIndex() == MATMEDIA_PBR) + if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR) { getChildView("TexOffsetU")->setEnabled(editable && has_pbr_material); getChildView("shinyOffsetU")->setEnabled(editable && has_pbr_material); @@ -1350,7 +1364,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative)); getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative)); - if (combobox_matmedia->getCurrentIndex() == MATMEDIA_PBR) + if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR) { getChildView("TexOffsetV")->setEnabled(editable && has_pbr_material); getChildView("shinyOffsetV")->setEnabled(editable && has_pbr_material); @@ -1386,7 +1400,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) F32 norm_rot_deg = norm_rotation * RAD_TO_DEG; F32 spec_rot_deg = spec_rotation * RAD_TO_DEG; - if (combobox_matmedia->getCurrentIndex() == MATMEDIA_PBR) + if (mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR) { getChildView("TexRot")->setEnabled(editable && has_pbr_material); getChildView("shinyRot")->setEnabled(editable && has_pbr_material); @@ -1467,7 +1481,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; bool enabled = editable && (index != 1); bool identical_repeats = true; - S32 material_selection = combobox_matmedia->getCurrentIndex(); + S32 material_selection = mComboMatMedia->getCurrentIndex(); F32 repeats = 1.0f; U32 material_type = MATTYPE_DIFFUSE; @@ -1726,6 +1740,755 @@ void LLPanelFace::refresh() getState(); } +void LLPanelFace::refreshMedia() +{ + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + LLViewerObject* first_object = selected_objects->getFirstObject(); + + if (!(first_object + && first_object->getPCode() == LL_PCODE_VOLUME + && first_object->permModify() + )) + { + getChildView("add_media")->setEnabled(FALSE); + mTitleMediaText->clear(); + clearMediaSettings(); + return; + } + + std::string url = first_object->getRegion()->getCapability("ObjectMedia"); + bool has_media_capability = (!url.empty()); + + if (!has_media_capability) + { + getChildView("add_media")->setEnabled(FALSE); + LL_WARNS("LLFloaterToolsMedia") << "Media not enabled (no capability) in this region!" << LL_ENDL; + clearMediaSettings(); + return; + } + + BOOL is_nonpermanent_enforced = (LLSelectMgr::getInstance()->getSelection()->getFirstRootNode() + && LLSelectMgr::getInstance()->selectGetRootsNonPermanentEnforced()) + || LLSelectMgr::getInstance()->selectGetNonPermanentEnforced(); + bool editable = is_nonpermanent_enforced && (first_object->permModify() || selectedMediaEditable()); + + // Check modify permissions and whether any selected objects are in + // the process of being fetched. If they are, then we're not editable + if (editable) + { + LLObjectSelection::iterator iter = selected_objects->begin(); + LLObjectSelection::iterator end = selected_objects->end(); + for (; iter != end; ++iter) + { + LLSelectNode* node = *iter; + LLVOVolume* object = dynamic_cast<LLVOVolume*>(node->getObject()); + if (NULL != object) + { + if (!object->permModify()) + { + LL_INFOS("LLFloaterToolsMedia") + << "Selection not editable due to lack of modify permissions on object id " + << object->getID() << LL_ENDL; + + editable = false; + break; + } + } + } + } + + // Media settings + bool bool_has_media = false; + struct media_functor : public LLSelectedTEGetFunctor<bool> + { + bool get(LLViewerObject* object, S32 face) + { + LLTextureEntry *te = object->getTE(face); + if (te) + { + return te->hasMedia(); + } + return false; + } + } func; + + + // check if all faces have media(or, all dont have media) + LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media); + + const LLMediaEntry default_media_data; + + struct functor_getter_media_data : public LLSelectedTEGetFunctor< LLMediaEntry> + { + functor_getter_media_data(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + LLMediaEntry get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return *(object->getTE(face)->getMediaData()); + return mMediaEntry; + }; + + const LLMediaEntry& mMediaEntry; + + } func_media_data(default_media_data); + + LLMediaEntry media_data_get; + LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get)); + + std::string multi_media_info_str = LLTrans::getString("Multiple Media"); + std::string media_title = ""; + // update UI depending on whether "object" (prim or face) has media + // and whether or not you are allowed to edit it. + + getChildView("add_media")->setEnabled(editable); + // IF all the faces have media (or all dont have media) + if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo) + { + // TODO: get media title and set it. + mTitleMediaText->clear(); + // if identical is set, all faces are same (whether all empty or has the same media) + if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia)) + { + // Media data is valid + if (media_data_get != default_media_data) + { + // initial media title is the media URL (until we get the name) + media_title = media_data_get.getHomeURL(); + } + // else all faces might be empty. + } + else // there' re Different Medias' been set on on the faces. + { + media_title = multi_media_info_str; + } + + getChildView("delete_media")->setEnabled(bool_has_media && editable); + // TODO: display a list of all media on the face - use 'identical' flag + } + else // not all face has media but at least one does. + { + // seleted faces have not identical value + LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data); + + if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) + { + media_title = multi_media_info_str; + } + else + { + // Media data is valid + if (media_data_get != default_media_data) + { + // initial media title is the media URL (until we get the name) + media_title = media_data_get.getHomeURL(); + } + } + + getChildView("delete_media")->setEnabled(TRUE); + } + + U32 materials_media = mComboMatMedia->getCurrentIndex(); + if (materials_media == MATMEDIA_MEDIA) + { + // currently displaying media info, navigateTo and update title + navigateToTitleMedia(media_title); + } + else + { + // Media can be heavy, don't keep it around + // MAC specific: MAC doesn't support setVolume(0) so if not + // unloaded, it might keep playing audio until user closes editor + unloadMedia(); + mNeedMediaTitle = false; + } + + mTitleMediaText->setText(media_title); + + // load values for media settings + updateMediaSettings(); + + LLFloaterMediaSettings::initValues(mMediaSettings, editable); +} + +void LLPanelFace::unloadMedia() +{ + // destroy media source used to grab media title + if (mTitleMedia) + mTitleMedia->unloadMediaSource(); +} + +////////////////////////////////////////////////////////////////////////////// +// +void LLPanelFace::navigateToTitleMedia( const std::string url ) +{ + std::string multi_media_info_str = LLTrans::getString("Multiple Media"); + if (url.empty() || multi_media_info_str == url) + { + // nothing to show + mNeedMediaTitle = false; + } + else if (mTitleMedia) + { + LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); + // check if url changed or if we need a new media source + if (mTitleMedia->getCurrentNavUrl() != url || media_plugin == NULL) + { + mTitleMedia->navigateTo( url ); + + LLViewerMediaImpl* impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(mTitleMedia->getTextureID()); + if (impl) + { + // if it's a page with a movie, we don't want to hear it + impl->setVolume(0); + }; + } + + // flag that we need to update the title (even if no request were made) + mNeedMediaTitle = true; + } +} + +bool LLPanelFace::selectedMediaEditable() +{ + U32 owner_mask_on; + U32 owner_mask_off; + U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_OWNER, + &owner_mask_on, &owner_mask_off); + U32 group_mask_on; + U32 group_mask_off; + U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_GROUP, + &group_mask_on, &group_mask_off); + U32 everyone_mask_on; + U32 everyone_mask_off; + S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm(PERM_EVERYONE, + &everyone_mask_on, &everyone_mask_off); + + bool selected_Media_editable = false; + + // if perms we got back are valid + if (valid_owner_perms && + valid_group_perms && + valid_everyone_perms) + { + + if ((owner_mask_on & PERM_MODIFY) || + (group_mask_on & PERM_MODIFY) || + (everyone_mask_on & PERM_MODIFY)) + { + selected_Media_editable = true; + } + else + // user is NOT allowed to press the RESET button + { + selected_Media_editable = false; + }; + }; + + return selected_Media_editable; +} + +void LLPanelFace::clearMediaSettings() +{ + LLFloaterMediaSettings::clearValues(false); +} + +void LLPanelFace::updateMediaSettings() +{ + bool identical(false); + std::string base_key(""); + std::string value_str(""); + int value_int = 0; + bool value_bool = false; + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + // TODO: (CP) refactor this using something clever or boost or both !! + + const LLMediaEntry default_media_data; + + // controls + U8 value_u8 = default_media_data.getControls(); + struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 > + { + functor_getter_controls(const LLMediaEntry &entry) : mMediaEntry(entry) {} + + U8 get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getControls(); + return mMediaEntry.getControls(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_controls(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_controls, value_u8); + base_key = std::string(LLMediaEntry::CONTROLS_KEY); + mMediaSettings[base_key] = value_u8; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // First click (formerly left click) + value_bool = default_media_data.getFirstClickInteract(); + struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool > + { + functor_getter_first_click(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getFirstClickInteract(); + return mMediaEntry.getFirstClickInteract(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_first_click(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_first_click, value_bool); + base_key = std::string(LLMediaEntry::FIRST_CLICK_INTERACT_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Home URL + value_str = default_media_data.getHomeURL(); + struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string > + { + functor_getter_home_url(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + std::string get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getHomeURL(); + return mMediaEntry.getHomeURL(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_home_url(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_home_url, value_str); + base_key = std::string(LLMediaEntry::HOME_URL_KEY); + mMediaSettings[base_key] = value_str; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Current URL + value_str = default_media_data.getCurrentURL(); + struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string > + { + functor_getter_current_url(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + std::string get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getCurrentURL(); + return mMediaEntry.getCurrentURL(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_current_url(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_current_url, value_str); + base_key = std::string(LLMediaEntry::CURRENT_URL_KEY); + mMediaSettings[base_key] = value_str; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Auto zoom + value_bool = default_media_data.getAutoZoom(); + struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool > + { + + functor_getter_auto_zoom(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAutoZoom(); + return mMediaEntry.getAutoZoom(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_zoom(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_auto_zoom, value_bool); + base_key = std::string(LLMediaEntry::AUTO_ZOOM_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Auto play + //value_bool = default_media_data.getAutoPlay(); + // set default to auto play TRUE -- angela EXT-5172 + value_bool = true; + struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_play(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAutoPlay(); + //return mMediaEntry.getAutoPlay(); set default to auto play TRUE -- angela EXT-5172 + return true; + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_play(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_auto_play, value_bool); + base_key = std::string(LLMediaEntry::AUTO_PLAY_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + + // Auto scale + // set default to auto scale TRUE -- angela EXT-5172 + //value_bool = default_media_data.getAutoScale(); + value_bool = true; + struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_scale(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAutoScale(); + // return mMediaEntry.getAutoScale(); set default to auto scale TRUE -- angela EXT-5172 + return true; + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_scale(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_auto_scale, value_bool); + base_key = std::string(LLMediaEntry::AUTO_SCALE_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Auto loop + value_bool = default_media_data.getAutoLoop(); + struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool > + { + functor_getter_auto_loop(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAutoLoop(); + return mMediaEntry.getAutoLoop(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_auto_loop(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_auto_loop, value_bool); + base_key = std::string(LLMediaEntry::AUTO_LOOP_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // width pixels (if not auto scaled) + value_int = default_media_data.getWidthPixels(); + struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int > + { + functor_getter_width_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + int get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getWidthPixels(); + return mMediaEntry.getWidthPixels(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_width_pixels(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_width_pixels, value_int); + base_key = std::string(LLMediaEntry::WIDTH_PIXELS_KEY); + mMediaSettings[base_key] = value_int; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // height pixels (if not auto scaled) + value_int = default_media_data.getHeightPixels(); + struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int > + { + functor_getter_height_pixels(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + int get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getHeightPixels(); + return mMediaEntry.getHeightPixels(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_height_pixels(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_height_pixels, value_int); + base_key = std::string(LLMediaEntry::HEIGHT_PIXELS_KEY); + mMediaSettings[base_key] = value_int; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Enable Alt image + value_bool = default_media_data.getAltImageEnable(); + struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool > + { + functor_getter_enable_alt_image(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getAltImageEnable(); + return mMediaEntry.getAltImageEnable(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_enable_alt_image(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_enable_alt_image, value_bool); + base_key = std::string(LLMediaEntry::ALT_IMAGE_ENABLE_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - owner interact + value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER); + struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_owner_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER)); + return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_OWNER); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_owner_interact(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_owner_interact, value_bool); + base_key = std::string(LLPanelContents::PERMS_OWNER_INTERACT_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - owner control + value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER); + struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_owner_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER)); + return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_OWNER); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_owner_control(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_owner_control, value_bool); + base_key = std::string(LLPanelContents::PERMS_OWNER_CONTROL_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - group interact + value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP); + struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_group_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP)); + return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_GROUP); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_group_interact(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_group_interact, value_bool); + base_key = std::string(LLPanelContents::PERMS_GROUP_INTERACT_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - group control + value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP); + struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_group_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP)); + return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_GROUP); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_group_control(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_group_control, value_bool); + base_key = std::string(LLPanelContents::PERMS_GROUP_CONTROL_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - anyone interact + value_bool = 0 != (default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE); + struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_anyone_interact(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE)); + return 0 != (mMediaEntry.getPermsInteract() & LLMediaEntry::PERM_ANYONE); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_anyone_interact(default_media_data); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&func_perms_anyone_interact, value_bool); + base_key = std::string(LLPanelContents::PERMS_ANYONE_INTERACT_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // Perms - anyone control + value_bool = 0 != (default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE); + struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool > + { + functor_getter_perms_anyone_control(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE)); + return 0 != (mMediaEntry.getPermsControl() & LLMediaEntry::PERM_ANYONE); + }; + + const LLMediaEntry &mMediaEntry; + + } func_perms_anyone_control(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_perms_anyone_control, value_bool); + base_key = std::string(LLPanelContents::PERMS_ANYONE_CONTROL_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // security - whitelist enable + value_bool = default_media_data.getWhiteListEnable(); + struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool > + { + functor_getter_whitelist_enable(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + bool get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getWhiteListEnable(); + return mMediaEntry.getWhiteListEnable(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_whitelist_enable(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_whitelist_enable, value_bool); + base_key = std::string(LLMediaEntry::WHITELIST_ENABLE_KEY); + mMediaSettings[base_key] = value_bool; + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; + + // security - whitelist URLs + std::vector<std::string> value_vector_str = default_media_data.getWhiteList(); + struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> > + { + functor_getter_whitelist_urls(const LLMediaEntry& entry) : mMediaEntry(entry) {} + + std::vector<std::string> get(LLViewerObject* object, S32 face) + { + if (object) + if (object->getTE(face)) + if (object->getTE(face)->getMediaData()) + return object->getTE(face)->getMediaData()->getWhiteList(); + return mMediaEntry.getWhiteList(); + }; + + const LLMediaEntry &mMediaEntry; + + } func_whitelist_urls(default_media_data); + identical = selected_objects->getSelectedTEValue(&func_whitelist_urls, value_vector_str); + base_key = std::string(LLMediaEntry::WHITELIST_KEY); + mMediaSettings[base_key].clear(); + std::vector< std::string >::iterator iter = value_vector_str.begin(); + while (iter != value_vector_str.end()) + { + std::string white_list_url = *iter; + mMediaSettings[base_key].append(white_list_url); + ++iter; + }; + + mMediaSettings[base_key + std::string(LLPanelContents::TENTATIVE_SUFFIX)] = !identical; +} + +void LLPanelFace::updateMediaTitle() +{ + // only get the media name if we need it + if (!mNeedMediaTitle) + return; + + // get plugin impl + LLPluginClassMedia* media_plugin = mTitleMedia->getMediaPlugin(); + if (media_plugin && mTitleMedia->getCurrentNavUrl() == media_plugin->getNavigateURI()) + { + // get the media name (asynchronous - must call repeatedly) + std::string media_title = media_plugin->getMediaName(); + + // only replace the title if what we get contains something + if (!media_title.empty()) + { + // update the UI widget + if (mTitleMediaText) + { + mTitleMediaText->setText(media_title); + + // stop looking for a title when we get one + mNeedMediaTitle = false; + }; + }; + }; +} + // // Static functions // @@ -1784,47 +2547,46 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata) self->updateShinyControls(false,true); self->updateBumpyControls(false,true); self->updateUI(); + self->refreshMedia(); } -// static void LLPanelFace::updateVisibility() { - LLComboBox* combo_matmedia = findChild<LLComboBox>("combobox matmedia"); LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type"); LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type"); LLComboBox* combo_shininess = findChild<LLComboBox>("combobox shininess"); LLComboBox* combo_bumpiness = findChild<LLComboBox>("combobox bumpiness"); - if (!radio_mat_type || !radio_pbr_type || !combo_matmedia || !combo_shininess || !combo_bumpiness) + if (!radio_mat_type || !radio_pbr_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness) { LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL; return; } - U32 materials_media = combo_matmedia->getCurrentIndex(); + U32 materials_media = mComboMatMedia->getCurrentIndex(); U32 material_type = radio_mat_type->getSelectedIndex(); U32 pbr_type = radio_pbr_type->getSelectedIndex(); - bool show_media = (materials_media == MATMEDIA_MEDIA) && combo_matmedia->getEnabled(); + bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled(); bool show_material = materials_media == MATMEDIA_MATERIAL; bool show_pbr = materials_media == MATMEDIA_PBR; - bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && combo_matmedia->getEnabled())); - bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && combo_matmedia->getEnabled(); - bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); - bool show_pbr_albedo = show_pbr && (pbr_type == PBRTYPE_ALBEDO) && combo_matmedia->getEnabled(); - bool show_pbr_normal = show_pbr && (pbr_type == PBRTYPE_NORMAL) && combo_matmedia->getEnabled(); - bool show_pbr_metallic = show_pbr && (pbr_type == PBRTYPE_METALLIC) && combo_matmedia->getEnabled(); + bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled())); + bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled(); + bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled(); + bool show_pbr_albedo = show_pbr && (pbr_type == PBRTYPE_ALBEDO) && mComboMatMedia->getEnabled(); + bool show_pbr_normal = show_pbr && (pbr_type == PBRTYPE_NORMAL) && mComboMatMedia->getEnabled(); + bool show_pbr_metallic = show_pbr && (pbr_type == PBRTYPE_METALLIC) && mComboMatMedia->getEnabled(); radio_mat_type->setVisible(show_material); radio_pbr_type->setVisible(show_pbr); // Media controls - getChildView("media_info")->setVisible(show_media); + mTitleMediaText->setVisible(show_media); getChildView("add_media")->setVisible(show_media); getChildView("delete_media")->setVisible(show_media); getChildView("button align")->setVisible(show_media); // Diffuse texture controls getChildView("texture control")->setVisible(show_texture && show_material); - getChildView("label alphamode")->setVisible((show_texture && show_material) || show_pbr); - getChildView("combobox alphamode")->setVisible((show_texture && show_material) || show_pbr); + getChildView("label alphamode")->setVisible(show_texture && show_material); + getChildView("combobox alphamode")->setVisible(show_texture && show_material); getChildView("label maskcutoff")->setVisible(false); getChildView("maskcutoff")->setVisible(false); if ((show_texture && show_material) || show_pbr) @@ -1960,12 +2722,11 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh } - LLComboBox* combo_matmedia = getChild<LLComboBox>("combobox matmedia"); LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); - U32 materials_media = combo_matmedia->getCurrentIndex(); + U32 materials_media = mComboMatMedia->getCurrentIndex(); U32 material_type = radio_mat_type->getSelectedIndex(); bool show_material = (materials_media == MATMEDIA_MATERIAL); - bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && combo_matmedia->getEnabled(); + bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled(); U32 shiny_value = comboShiny->getCurrentIndex(); bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture getChildView("label glossiness")->setVisible(show_shinyctrls); @@ -2039,11 +2800,10 @@ void LLPanelFace::updateAlphaControls() U32 alpha_value = comboAlphaMode->getCurrentIndex(); bool show_alphactrls = (alpha_value == ALPHAMODE_MASK); // Alpha masking - LLComboBox* combobox_matmedia = getChild<LLComboBox>("combobox matmedia"); U32 mat_media = MATMEDIA_MATERIAL; - if (combobox_matmedia) + if (mComboMatMedia) { - mat_media = combobox_matmedia->getCurrentIndex(); + mat_media = mComboMatMedia->getCurrentIndex(); } U32 mat_type = MATTYPE_DIFFUSE; @@ -2260,6 +3020,77 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data) sendBump(nmap_id.isNull() ? 0 : BUMPY_TEXTURE); } +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to edit existing media settings on a prim or prim face +// TODO: test if there is media on the item and only allow editing if present +void LLPanelFace::onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata) +{ + LLPanelFace* self = (LLPanelFace*)userdata; + self->refreshMedia(); + LLFloaterReg::showInstance("media_settings"); +} + +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to delete media from a prim or prim face +void LLPanelFace::onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata) +{ + LLNotificationsUtil::add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm); +} + +////////////////////////////////////////////////////////////////////////////// +// called when a user wants to add media to a prim or prim face +void LLPanelFace::onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata) +{ + // check if multiple faces are selected + if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) + { + LLPanelFace* self = (LLPanelFace*)userdata; + self->refreshMedia(); + LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm); + } + else + { + onClickBtnEditMedia(ctrl, userdata); + } +} + +// static +bool LLPanelFace::deleteMediaConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch (option) + { + case 0: // "Yes" + LLSelectMgr::getInstance()->selectionSetMedia(0, LLSD()); + if (LLFloaterReg::instanceVisible("media_settings")) + { + LLFloaterReg::hideInstance("media_settings"); + } + break; + + case 1: // "No" + default: + break; + } + return false; +} + +// static +bool LLPanelFace::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch (option) + { + case 0: // "Yes" + LLFloaterReg::showInstance("media_settings"); + break; + case 1: // "No" + default: + break; + } + return false; +} + //static void LLPanelFace::syncOffsetX(LLPanelFace* self, F32 offsetU) { @@ -2637,10 +3468,9 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata) LLPanelFace* self = (LLPanelFace*) userdata; LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl"); - LLComboBox* combo_matmedia = self->getChild<LLComboBox>("combobox matmedia"); LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type"); - U32 materials_media = combo_matmedia->getCurrentIndex(); + U32 materials_media = self->mComboMatMedia->getCurrentIndex(); U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : 0; F32 repeats_per_meter = repeats_ctrl->getValue().asReal(); @@ -3576,14 +4406,6 @@ bool LLPanelFace::menuEnableItem(const LLSD& userdata) } -// TODO: I don't know who put these in or what these are for??? -void LLPanelFace::setMediaURL(const std::string& url) -{ -} -void LLPanelFace::setMediaType(const std::string& mime_type) -{ -} - // static void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata) { diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 6746d67ce3..725cfb0f5f 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -47,6 +47,7 @@ class LLUICtrl; class LLViewerObject; class LLFloater; class LLMaterialID; +class LLMediaCtrl; class LLMenuButton; // Represents an edit for use in replicating the op across one or more materials in the selection set. @@ -97,11 +98,11 @@ public: LLPanelFace(); virtual ~LLPanelFace(); - void draw(); - void refresh(); - void setMediaURL(const std::string& url); - void setMediaType(const std::string& mime_type); + void refreshMedia(); + void unloadMedia(); + + /*virtual*/ void draw(); LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material) { @@ -117,6 +118,12 @@ public: LLRender::eTexIndex getTextureChannelToEdit(); protected: + void navigateToTitleMedia(const std::string url); + bool selectedMediaEditable(); + void clearMediaSettings(); + void updateMediaSettings(); + void updateMediaTitle(); + void getState(); void sendTexture(); // applies and sends texture @@ -159,6 +166,9 @@ protected: void onCloseTexturePicker(const LLSD& data); + static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); + static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); + // Make UI reflect state of currently selected material (refresh) // and UI mode (e.g. editing normal map v diffuse map) // @@ -205,6 +215,9 @@ protected: static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata); static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata); static void onCommitPbrType(LLUICtrl* ctrl, void* userdata); + static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata); + static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata); static void onCommitBump( LLUICtrl* ctrl, void* userdata); static void onCommitTexGen( LLUICtrl* ctrl, void* userdata); static void onCommitShiny( LLUICtrl* ctrl, void* userdata); @@ -257,6 +270,10 @@ private: F32 getCurrentShinyOffsetU(); F32 getCurrentShinyOffsetV(); + LLComboBox *mComboMatMedia; + LLMediaCtrl *mTitleMedia; + LLTextBox *mTitleMediaText; + // Update visibility of controls to match current UI mode // (e.g. materials vs media editing) // @@ -264,10 +281,6 @@ private: // void updateVisibility(); - // Make material(s) reflect current state of UI (apply edit) - // - void updateMaterial(); - // Hey look everyone, a type-safe alternative to copy and paste! :) // @@ -446,6 +459,9 @@ private: LLSD mClipboardParams; + LLSD mMediaSettings; + bool mNeedMediaTitle; + public: #if defined(DEF_GET_MAT_STATE) #undef DEF_GET_MAT_STATE diff --git a/indra/newview/llpanellandaudio.cpp b/indra/newview/llpanellandaudio.cpp index e7bdc51b4a..9e3fc54477 100644 --- a/indra/newview/llpanellandaudio.cpp +++ b/indra/newview/llpanellandaudio.cpp @@ -97,6 +97,9 @@ BOOL LLPanelLandAudio::postBuild() mCheckAVSoundGroup = getChild<LLCheckBoxCtrl>("group av sound check"); childSetCommitCallback("group av sound check", onCommitAny, this); + mCheckObscureMOAP = getChild<LLCheckBoxCtrl>("obscure_moap"); + childSetCommitCallback("obscure_moap", onCommitAny, this); + return TRUE; } @@ -157,6 +160,9 @@ void LLPanelLandAudio::refresh() mCheckAVSoundGroup->set(parcel->getAllowGroupAVSounds() || parcel->getAllowAnyAVSounds()); // On if "Everyone" is on mCheckAVSoundGroup->setEnabled(can_change_av_sounds && !parcel->getAllowAnyAVSounds()); // Enabled if "Everyone" is off + + mCheckObscureMOAP->set(parcel->getObscureMOAP()); + mCheckObscureMOAP->setEnabled(can_change_media); } } // static @@ -184,6 +190,8 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata) group_av_sound = self->mCheckAVSoundGroup->get(); } + bool obscure_moap = self->mCheckObscureMOAP->get(); + // Remove leading/trailing whitespace (common when copying/pasting) LLStringUtil::trim(music_url); @@ -194,6 +202,7 @@ void LLPanelLandAudio::onCommitAny(LLUICtrl*, void *userdata) parcel->setMusicURL(music_url); parcel->setAllowAnyAVSounds(any_av_sound); parcel->setAllowGroupAVSounds(group_av_sound); + parcel->setObscureMOAP(obscure_moap); // Send current parcel data upstream to server LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel ); diff --git a/indra/newview/llpanellandaudio.h b/indra/newview/llpanellandaudio.h index 7e4fce80e4..b54fe62179 100644 --- a/indra/newview/llpanellandaudio.h +++ b/indra/newview/llpanellandaudio.h @@ -53,6 +53,7 @@ private: LLLineEditor* mMusicURLEdit; LLCheckBoxCtrl* mCheckAVSoundAny; LLCheckBoxCtrl* mCheckAVSoundGroup; + LLCheckBoxCtrl* mCheckObscureMOAP; LLSafeHandle<LLParcelSelection>& mParcel; }; diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index 9730f0f16d..e1818cc68b 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -98,9 +98,6 @@ BOOL LLPanelMediaSettingsGeneral::postBuild() childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this); childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this); - // interrogates controls and updates widgets as required - updateMediaPreview(); - return true; } @@ -313,9 +310,6 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& _media data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); }; }; - - // interrogates controls and updates widgets as required - self->updateMediaPreview(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 09e568e9ac..f4eaa78f11 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -61,6 +61,7 @@ #include "llcommandhandler.h" #include "llfloaterprofiletexture.h" #include "llfloaterreg.h" +#include "llfloaterreporter.h" #include "llfilepicker.h" #include "llfirstuse.h" #include "llgroupactions.h" @@ -582,6 +583,22 @@ public: } return true; } + + // reportAbuse is here due to convoluted avatar handling + // in LLScrollListCtrl and LLTextBase + if (verb == "reportAbuse" && web == NULL) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(avatar_id, &av_name)) + { + LLFloaterReporter::showFromAvatar(avatar_id, av_name.getCompleteName()); + } + else + { + LLFloaterReporter::showFromAvatar(avatar_id, "not avaliable"); + } + return true; + } return false; } }; @@ -1936,23 +1953,6 @@ void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) } } -void LLPanelProfileSecondLife::onOpenNotes() -{ - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - if (!parent_floater) - { - return; - } - - LLTabContainer* tab_container = parent_floater->findChild<LLTabContainer>("panel_profile_tabs", TRUE); - if (!tab_container) - { - return; - } - - tab_container->selectTabByName(PANEL_NOTES); -} - ////////////////////////////////////////////////////////////////////////// // LLPanelProfileWeb diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index ca6ef3f794..d32bb943bd 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -184,7 +184,6 @@ private: void onShowAgentProfileTexture(); void onShowTexturePicker(); void onCommitProfileImage(const LLUUID& id); - void onOpenNotes(); private: typedef std::map<std::string, LLUUID> group_map_t; diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 5c93271446..b50b652966 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -641,13 +641,6 @@ void LLPanelVolume::refresh() mRootObject = NULL; } - BOOL visible = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; - - getChildView("Light FOV")->setVisible( visible); - getChildView("Light Focus")->setVisible( visible); - getChildView("Light Ambiance")->setVisible( visible); - getChildView("light texture control")->setVisible( visible); - bool enable_mesh = false; LLSD sim_features; diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index 94d20828ec..9b60d1ae2f 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -38,154 +38,11 @@ #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally #endif -// See EXT-4301. -/** - * class LLAvalineUpdater - observe the list of voice participants in session and check - * presence of Avaline Callers among them. - * - * LLAvalineUpdater is a LLVoiceClientParticipantObserver. It provides two kinds of validation: - * - whether Avaline caller presence among participants; - * - whether watched Avaline caller still exists in voice channel. - * Both validations have callbacks which will notify subscriber if any of event occur. - * - * @see findAvalineCaller() - * @see checkIfAvalineCallersExist() - */ -class LLAvalineUpdater : public LLVoiceClientParticipantObserver -{ -public: - typedef boost::function<void(const LLUUID& speaker_id)> process_avaline_callback_t; - - LLAvalineUpdater(process_avaline_callback_t found_cb, process_avaline_callback_t removed_cb) - : mAvalineFoundCallback(found_cb) - , mAvalineRemovedCallback(removed_cb) - { - LLVoiceClient::getInstance()->addObserver(this); - } - ~LLAvalineUpdater() - { - if (LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver(this); - } - } - - /** - * Adds UUID of Avaline caller to watch. - * - * @see checkIfAvalineCallersExist(). - */ - void watchAvalineCaller(const LLUUID& avaline_caller_id) - { - mAvalineCallers.insert(avaline_caller_id); - } - - void onParticipantsChanged() - { - uuid_set_t participant_uuids; - LLVoiceClient::getInstance()->getParticipantList(participant_uuids); - - - // check whether Avaline caller exists among voice participants - // and notify Participant List - findAvalineCaller(participant_uuids); - - // check whether watched Avaline callers still present among voice participant - // and remove if absents. - checkIfAvalineCallersExist(participant_uuids); - } - -private: - typedef std::set<LLUUID> uuid_set_t; - - /** - * Finds Avaline callers among voice participants and calls mAvalineFoundCallback. - * - * When Avatar is in group call with Avaline caller and then ends call Avaline caller stays - * in Group Chat floater (exists in LLSpeakerMgr). If Avatar starts call with that group again - * Avaline caller is added to voice channel AFTER Avatar is connected to group call. - * But Voice Control Panel (VCP) is filled from session LLSpeakerMgr and there is no information - * if a speaker is Avaline caller. - * - * In this case this speaker is created as avatar and will be recreated when it appears in - * Avatar's Voice session. - * - * @see LLParticipantList::onAvalineCallerFound() - */ - void findAvalineCaller(const uuid_set_t& participant_uuids) - { - uuid_set_t::const_iterator it = participant_uuids.begin(), it_end = participant_uuids.end(); - - for(; it != it_end; ++it) - { - const LLUUID& participant_id = *it; - if (!LLVoiceClient::getInstance()->isParticipantAvatar(participant_id)) - { - LL_DEBUGS("Avaline") << "Avaline caller found among voice participants: " << participant_id << LL_ENDL; - - if (mAvalineFoundCallback) - { - mAvalineFoundCallback(participant_id); - } - } - } - } - - /** - * Finds Avaline callers which are not anymore among voice participants and calls mAvalineRemovedCallback. - * - * The problem is when Avaline caller ends a call it is removed from Voice Client session but - * still exists in LLSpeakerMgr. Server does not send such information. - * This method implements a HUCK to notify subscribers that watched Avaline callers by class - * are not anymore in the call. - * - * @see LLParticipantList::onAvalineCallerRemoved() - */ - void checkIfAvalineCallersExist(const uuid_set_t& participant_uuids) - { - uuid_set_t::iterator it = mAvalineCallers.begin(); - uuid_set_t::const_iterator participants_it_end = participant_uuids.end(); - - while (it != mAvalineCallers.end()) - { - const LLUUID participant_id = *it; - LL_DEBUGS("Avaline") << "Check avaline caller: " << participant_id << LL_ENDL; - bool not_found = participant_uuids.find(participant_id) == participants_it_end; - if (not_found) - { - LL_DEBUGS("Avaline") << "Watched Avaline caller is not found among voice participants: " << participant_id << LL_ENDL; - - // notify Participant List - if (mAvalineRemovedCallback) - { - mAvalineRemovedCallback(participant_id); - } - - // remove from the watch list - mAvalineCallers.erase(it++); - } - else - { - ++it; - } - } - } - - process_avaline_callback_t mAvalineFoundCallback; - process_avaline_callback_t mAvalineRemovedCallback; - - uuid_set_t mAvalineCallers; -}; - LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) : LLConversationItemSession(data_source->getSessionID(), root_view_model), mSpeakerMgr(data_source), mValidateSpeakerCallback(NULL) { - - mAvalineUpdater = new LLAvalineUpdater(boost::bind(&LLParticipantList::onAvalineCallerFound, this, _1), - boost::bind(&LLParticipantList::onAvalineCallerRemoved, this, _1)); - mSpeakerAddListener = new SpeakerAddListener(*this); mSpeakerRemoveListener = new SpeakerRemoveListener(*this); mSpeakerClearListener = new SpeakerClearListener(*this); @@ -243,32 +100,6 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewMode LLParticipantList::~LLParticipantList() { - delete mAvalineUpdater; -} - -/* - Seems this method is not necessary after onAvalineCallerRemoved was implemented; - - It does nothing because list item is always created with correct class type for Avaline caller. - For now Avaline Caller is removed from the LLSpeakerMgr List when it is removed from the Voice Client - session. - This happens in two cases: if Avaline Caller ends call itself or if Resident ends group call. - - Probably Avaline caller should be removed from the LLSpeakerMgr list ONLY if it ends call itself. - Asked in EXT-4301. -*/ -void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id) -{ - removeParticipant(participant_id); - // re-add avaline caller with a correct class instance. - addAvatarIDExceptAgent(participant_id); -} - -void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id) -{ - LL_DEBUGS("Avaline") << "Removing avaline caller from the list: " << participant_id << LL_ENDL; - - mSpeakerMgr->removeAvalineSpeaker(participant_id); } void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb) @@ -386,7 +217,6 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id) std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id); // Create a participant view model instance participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel); - mAvalineUpdater->watchAvalineCaller(avatar_id); } // *TODO : Need to update the online/offline status of the participant diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h index 3a3ae76604..14c0a63692 100644 --- a/indra/newview/llparticipantlist.h +++ b/indra/newview/llparticipantlist.h @@ -32,7 +32,6 @@ class LLSpeakerMgr; class LLUICtrl; -class LLAvalineUpdater; class LLParticipantList : public LLConversationItemSession { @@ -133,8 +132,6 @@ protected: }; private: - void onAvalineCallerFound(const LLUUID& participant_id); - void onAvalineCallerRemoved(const LLUUID& participant_id); /** * Adjusts passed participant to work properly. @@ -156,7 +153,6 @@ private: LLPointer<SpeakerMuteListener> mSpeakerMuteListener; validate_speaker_callback_t mValidateSpeakerCallback; - LLAvalineUpdater* mAvalineUpdater; }; #endif // LL_PARTICIPANTLIST_H diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp index 9bc77393dc..9bf771db8a 100644 --- a/indra/newview/llpersistentnotificationstorage.cpp +++ b/indra/newview/llpersistentnotificationstorage.cpp @@ -163,12 +163,16 @@ void LLPersistentNotificationStorage::loadNotifications() LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL; } -void LLPersistentNotificationStorage::initialize() +void LLPersistentNotificationStorage::reset() { - std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml"; - setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name)); - setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")); + std::string file_name = "open_notifications_" + LLGridManager::getInstance()->getGrid() + ".xml"; + setFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, file_name)); + setOldFileName(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml")); +} +void LLPersistentNotificationStorage::initialize() +{ + reset(); LLNotifications::instance().getChannel("Persistent")-> connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1)); } diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h index 1fb4487286..335d85aaf6 100644 --- a/indra/newview/llpersistentnotificationstorage.h +++ b/indra/newview/llpersistentnotificationstorage.h @@ -52,6 +52,7 @@ public: void saveNotifications(); void loadNotifications(); + void reset(); protected: diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 230def5362..3fd4f51559 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -866,7 +866,10 @@ bool LLPreviewNotecard::loadNotecardText(const std::string& filename) buffer[nread] = '\0'; fclose(file); - mEditor->setText(LLStringExplicit(buffer)); + std::string text = std::string(buffer); + LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab()); + + mEditor->setText(text); delete[] buffer; return true; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index e4b4b597ca..5043250e08 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -601,7 +601,10 @@ bool LLScriptEdCore::loadScriptText(const std::string& filename) buffer[nread] = '\0'; fclose(file); - mEditor->setText(LLStringExplicit(buffer)); + std::string text = std::string(buffer); + LLStringUtil::replaceTabsWithSpaces(text, LLTextEditor::spacesPerTab()); + + mEditor->setText(text); delete[] buffer; return true; diff --git a/indra/newview/llrecentpeople.cpp b/indra/newview/llrecentpeople.cpp index 83b0c4f1bf..0faf6bf889 100644 --- a/indra/newview/llrecentpeople.cpp +++ b/indra/newview/llrecentpeople.cpp @@ -42,14 +42,6 @@ bool LLRecentPeople::add(const LLUUID& id, const LLSD& userdata) if (is_not_group_id) { - // For each avaline call the id of caller is different even if - // the phone number is the same. - // To avoid duplication of avaline list items in the recent list - // of panel People, deleting id's with similar phone number. - const LLUUID& caller_id = getIDByPhoneNumber(userdata); - if (caller_id.notNull()) - mPeople.erase(caller_id); - //[] instead of insert to replace existing id->llsd["date"] with new date value mPeople[id] = userdata; mChangedSignal(); @@ -90,35 +82,6 @@ const LLSD& LLRecentPeople::getData(const LLUUID& id) const return no_data; } -bool LLRecentPeople::isAvalineCaller(const LLUUID& id) const -{ - recent_people_t::const_iterator it = mPeople.find(id); - - if (it != mPeople.end()) - { - const LLSD& user = it->second; - return user["avaline_call"].asBoolean(); - } - - return false; -} - -const LLUUID& LLRecentPeople::getIDByPhoneNumber(const LLSD& userdata) -{ - if (!userdata["avaline_call"].asBoolean()) - return LLUUID::null; - - for (recent_people_t::const_iterator it = mPeople.begin(); it != mPeople.end(); ++it) - { - const LLSD& user_info = it->second; - - if (user_info["call_number"].asString() == userdata["call_number"].asString()) - return it->first; - } - - return LLUUID::null; -} - // virtual bool LLRecentPeople::handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) { diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h index 18b669ff4f..1b322f2c0a 100644 --- a/indra/newview/llrecentpeople.h +++ b/indra/newview/llrecentpeople.h @@ -62,9 +62,7 @@ public: * @param id avatar to add. * * @param userdata additional information about last interaction party. - * For example when last interaction party is not an avatar - * but an avaline caller, additional info (such as phone - * number, session id and etc.) should be added. + * For example session id can be added. * * @return false if the avatar is in the list already, true otherwise */ @@ -97,13 +95,6 @@ public: const LLSD& getData(const LLUUID& id) const; /** - * Checks whether specific participant is an avaline caller - * - * @param id identifier of specific participant - */ - bool isAvalineCaller(const LLUUID& id) const; - - /** * Set callback to be called when the list changed. * * Multiple callbacks can be set. @@ -122,8 +113,6 @@ public: private: - const LLUUID& getIDByPhoneNumber(const LLSD& userdata); - typedef std::map<LLUUID, LLSD> recent_people_t; recent_people_t mPeople; signal_t mChangedSignal; diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 2a7ab84501..d9dd1e9381 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -82,6 +82,11 @@ void LLReflectionMap::autoAdjustOrigin() // cast a ray towards 8 corners of bounding box // nudge origin towards center of empty space + if (!node) + { + return; + } + if (node->isLeaf() || node->getChildCount() > 1 || node->getData().size() > 0) { // use center of object bounding box for leaf nodes or nodes with multiple child nodes mOrigin = bounds[0]; diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 97277ee798..9c6d7ea26f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -410,8 +410,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 mips = log2((F32)LL_REFLECTION_PROBE_RESOLUTION) + 0.5f; - //for (int i = 0; i < mMipChain.size(); ++i) - for (int i = 0; i < 1; ++i) + for (int i = 0; i < mMipChain.size(); ++i) { LL_PROFILE_GPU_ZONE("probe mip"); mMipChain[i].bindTarget(); @@ -447,10 +446,14 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) if (mip >= 0) { + LL_PROFILE_GPU_ZONE("probe mip copy"); mTexture->bind(0); //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, targetIdx * 6 + face, 0, 0, res, res); - glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + if (i == 0) + { + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res); + } mTexture->unbind(); } mMipChain[i].flush(); @@ -474,8 +477,12 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) static LLStaticHashedString sMipLevel("mipLevel"); + mMipChain[1].bindTarget(); + U32 res = mMipChain[1].getWidth(); + for (int i = 1; i < mMipChain.size(); ++i) { + LL_PROFILE_GPU_ZONE("probe radiance gen"); for (int cf = 0; cf < 6; ++cf) { // for each cube face LLCoordFrame frame; @@ -485,15 +492,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) frame.getOpenGLRotation(mat); gGL.loadMatrix(mat); - mMipChain[i].bindTarget(); static LLStaticHashedString sRoughness("roughness"); gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1)); gRadianceGenProgram.uniform1f(sMipLevel, llmax((F32)(i - 1), 0.f)); - if (i > 0) - { - gRadianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex); - } + gGL.begin(gGL.QUADS); gGL.vertex3f(-1, -1, -1); gGL.vertex3f(1, -1, -1); @@ -501,12 +504,17 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) gGL.vertex3f(-1, 1, -1); gGL.end(); gGL.flush(); - - S32 res = mMipChain[i].getWidth(); + glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); - mMipChain[i].flush(); + } + + if (i != mMipChain.size() - 1) + { + res /= 2; + glViewport(0, 0, res, res); } } + gRadianceGenProgram.unbind(); //generate irradiance map @@ -514,7 +522,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); - gIrradianceGenProgram.uniform1i(sSourceIdx, probe->mCubeIndex); + gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); int start_mip = 0; // find the mip target to start with based on irradiance map resolution @@ -526,8 +534,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) } } - for (int i = start_mip; i < mMipChain.size(); ++i) + //for (int i = start_mip; i < mMipChain.size(); ++i) { + int i = start_mip; + LL_PROFILE_GPU_ZONE("probe irradiance gen"); + glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight()); for (int cf = 0; cf < 6; ++cf) { // for each cube face LLCoordFrame frame; @@ -537,8 +548,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) frame.getOpenGLRotation(mat); gGL.loadMatrix(mat); - mMipChain[i].bindTarget(); - gGL.begin(gGL.QUADS); gGL.vertex3f(-1, -1, -1); gGL.vertex3f(1, -1, -1); @@ -551,9 +560,11 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mIrradianceMaps->bind(channel); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res); mTexture->bind(channel); - mMipChain[i].flush(); } } + + mMipChain[1].flush(); + gIrradianceGenProgram.unbind(); } } @@ -835,6 +846,6 @@ void LLReflectionMapManager::initReflectionMaps() mTexture->allocate(LL_REFLECTION_PROBE_RESOLUTION, 3, mReflectionProbeCount + 2); mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE); } } diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 6a2f53aa42..49d5aa3e14 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -445,14 +445,14 @@ void LLSceneMonitor::calcDiffAggregate() if(mDiffState == EXECUTE_DIFF) { - glBeginQuery(GL_SAMPLES_PASSED_ARB, mQueryObject); + glBeginQuery(GL_SAMPLES_PASSED, mQueryObject); } gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff); if(mDiffState == EXECUTE_DIFF) { - glEndQuery(GL_SAMPLES_PASSED_ARB); + glEndQuery(GL_SAMPLES_PASSED); mDiffState = WAIT_ON_RESULT; } @@ -483,11 +483,11 @@ void LLSceneMonitor::fetchQueryResult() mDiffState = WAITING_FOR_NEXT_DIFF; GLuint available = 0; - glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available); + glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE, &available); if(available) { GLuint count = 0; - glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_ARB, &count); + glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT, &count); mDiffResult = sqrtf(count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio)); //0.5 -> (front face + back face) diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h index e033cae3ab..31f11eb8ef 100644 --- a/indra/newview/llsearchableui.h +++ b/indra/newview/llsearchableui.h @@ -41,9 +41,9 @@ namespace ll struct PanelData; struct TabContainerData; - typedef boost::shared_ptr< SearchableItem > SearchableItemPtr; - typedef boost::shared_ptr< PanelData > PanelDataPtr; - typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr; + typedef std::shared_ptr< SearchableItem > SearchableItemPtr; + typedef std::shared_ptr< PanelData > PanelDataPtr; + typedef std::shared_ptr< TabContainerData > TabContainerDataPtr; typedef std::vector< TabContainerData > tTabContainerDataList; typedef std::vector< SearchableItemPtr > tSearchableItemList; @@ -55,7 +55,7 @@ namespace ll LLView const *mView; ll::ui::SearchableControl const *mCtrl; - std::vector< boost::shared_ptr< SearchableItem > > mChildren; + std::vector< std::shared_ptr< SearchableItem > > mChildren; virtual ~SearchableItem(); @@ -68,8 +68,8 @@ namespace ll LLPanel const *mPanel; std::string mLabel; - std::vector< boost::shared_ptr< SearchableItem > > mChildren; - std::vector< boost::shared_ptr< PanelData > > mChildPanel; + std::vector< std::shared_ptr< SearchableItem > > mChildren; + std::vector< std::shared_ptr< PanelData > > mChildPanel; virtual ~PanelData(); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 12ba29466d..99835d4e5a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -63,6 +63,7 @@ #include "llfloatertools.h" #include "llframetimer.h" #include "llfocusmgr.h" +#include "llgltfmateriallist.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" #include "llinventorymodel.h" @@ -310,14 +311,29 @@ void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle) { struct f : public LLSelectedNodeFunctor { + f(bool a, LLSelectMgr* p) : mAvatarOverridesPersist(a), mManager(p) {} + bool mAvatarOverridesPersist; + LLSelectMgr* mManager; virtual bool apply(LLSelectNode* node) { + if (mAvatarOverridesPersist) + { + LLViewerObject* object = node->getObject(); + if (object && !object->getParent()) + { + LLVOAvatar* avatar = object->asAvatar(); + if (avatar) + { + mManager->mAvatarOverridesMap.emplace(avatar->getID(), AvatarPositionOverride(node->mLastPositionLocal, node->mLastRotation, object)); + } + } + } node->mLastPositionLocal.setVec(0, 0, 0); node->mLastRotation = LLQuaternion(); node->mLastScale.setVec(0, 0, 0); return true; } - } func; + } func(mAllowSelectAvatar, this); selected_handle->applyToNodes(&func); } @@ -351,6 +367,93 @@ void LLSelectMgr::overrideObjectUpdates() getSelection()->applyToNodes(&func); } +void LLSelectMgr::resetAvatarOverrides() +{ + mAvatarOverridesMap.clear(); +} + +void LLSelectMgr::overrideAvatarUpdates() +{ + if (mAvatarOverridesMap.size() == 0) + { + return; + } + + if (!mAllowSelectAvatar || !gFloaterTools) + { + resetAvatarOverrides(); + return; + } + + if (!gFloaterTools->getVisible() && getSelection()->isEmpty()) + { + // when user switches selection, floater is invisible and selection is empty + LLToolset *toolset = LLToolMgr::getInstance()->getCurrentToolset(); + if (toolset->isShowFloaterTools() + && toolset->isToolSelected(0)) // Pie tool + { + resetAvatarOverrides(); + return; + } + } + + // remove selected avatars from this list, + // but set object overrides to make sure avatar won't snap back + struct f : public LLSelectedNodeFunctor + { + f(LLSelectMgr* p) : mManager(p) {} + LLSelectMgr* mManager; + virtual bool apply(LLSelectNode* selectNode) + { + LLViewerObject* object = selectNode->getObject(); + if (object && !object->getParent()) + { + LLVOAvatar* avatar = object->asAvatar(); + if (avatar) + { + uuid_av_override_map_t::iterator iter = mManager->mAvatarOverridesMap.find(avatar->getID()); + if (iter != mManager->mAvatarOverridesMap.end()) + { + if (selectNode->mLastPositionLocal.isExactlyZero()) + { + selectNode->mLastPositionLocal = iter->second.mLastPositionLocal; + } + if (selectNode->mLastRotation == LLQuaternion()) + { + selectNode->mLastRotation = iter->second.mLastRotation; + } + mManager->mAvatarOverridesMap.erase(iter); + } + } + } + return true; + } + } func(this); + getSelection()->applyToNodes(&func); + + // Override avatar positions + uuid_av_override_map_t::iterator it = mAvatarOverridesMap.begin(); + while (it != mAvatarOverridesMap.end()) + { + if (it->second.mObject->isDead()) + { + it = mAvatarOverridesMap.erase(it); + } + else + { + if (!it->second.mLastPositionLocal.isExactlyZero()) + { + it->second.mObject->setPosition(it->second.mLastPositionLocal); + } + if (it->second.mLastRotation != LLQuaternion()) + { + it->second.mObject->setRotation(it->second.mLastRotation); + } + it++; + } + } +} + //----------------------------------------------------------------------------- // Select just the object, not any other group members. //----------------------------------------------------------------------------- @@ -886,7 +989,7 @@ void LLSelectMgr::addAsFamily(std::vector<LLViewerObject*>& objects, BOOL add_to // Can't select yourself if (objectp->mID == gAgentID - && !LLSelectMgr::getInstance()->mAllowSelectAvatar) + && !mAllowSelectAvatar) { continue; } @@ -1792,16 +1895,56 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) asset_id = mItem->getAssetUUID(); } + if (asset_id.notNull() && !objectp->hasRenderMaterialParams()) + { + // make sure param section exists + objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/); + } + if (te != -1) { - objectp->setRenderMaterialID(te, asset_id); + LLTextureEntry* tep = objectp->getTE(te); + if (asset_id.notNull()) + { + tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + } + else + { + tep->setGLTFMaterial(nullptr); + } + + objectp->faceMappingChanged(); + gPipeline.markTextured(objectp->mDrawable); + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + param_block->setMaterial(te, asset_id); + } } - else + else // Shouldn't happen? { S32 num_faces = objectp->getNumTEs(); for (S32 face = 0; face < num_faces; face++) { - objectp->setRenderMaterialID(face, asset_id); + LLTextureEntry* tep = objectp->getTE(face); + if (asset_id.notNull()) + { + tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + } + else + { + tep->setGLTFMaterial(nullptr); + } + + objectp->faceMappingChanged(); + gPipeline.markTextured(objectp->mDrawable); + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + param_block->setMaterial(face, asset_id); + } } } @@ -1809,26 +1952,43 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) } }; - if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) + // TODO: once PBR starts supporting permissions, implement/figure this out + /*if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) { getSelection()->applyNoCopyTextureToTEs(item); } - else + else*/ { f setfunc(item, mat_id); getSelection()->applyToTEs(&setfunc); } - struct g : public LLSelectedObjectFunctor { LLViewerInventoryItem* mItem; g(LLViewerInventoryItem* item) : mItem(item) {} virtual bool apply(LLViewerObject* object) { + if (object && !object->permModify()) + { + return false; + } + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + if (param_block->isEmpty()) + { + object->setHasRenderMaterialParams(false); + } + else + { + object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); + } + } + if (!mItem) { - object->sendTEUpdate(); // 1 particle effect per object LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); effectp->setSourceObject(gAgentAvatarp); @@ -1836,6 +1996,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) effectp->setDuration(LL_HUD_DUR_SHORT); effectp->setColor(LLColor4U(gAgent.getEffectColor())); } + + object->sendTEUpdate(); return true; } } sendfunc(item); @@ -2025,15 +2187,40 @@ void LLSelectMgr::selectionRevertGLTFMaterials() { LLObjectSelectionHandle mSelectedObjects; f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {} - bool apply(LLViewerObject* object, S32 te) + bool apply(LLViewerObject* objectp, S32 te) { - if (object->permModify()) + if (objectp && !objectp->permModify()) { - LLSelectNode* nodep = mSelectedObjects->findNode(object); - if (nodep && te < (S32)nodep->mSavedGLTFMaterials.size()) + return false; + } + + LLSelectNode* nodep = mSelectedObjects->findNode(objectp); + if (nodep && te < (S32)nodep->mSavedGLTFMaterials.size()) + { + LLUUID asset_id = nodep->mSavedGLTFMaterials[te]; + LLTextureEntry* tep = objectp->getTE(te); + if (asset_id.notNull()) + { + tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); + + if (!objectp->hasRenderMaterialParams()) + { + // make sure param section exists + objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an immediate update*/); + } + } + else + { + tep->setGLTFMaterial(nullptr); + } + + objectp->faceMappingChanged(); + gPipeline.markTextured(objectp->mDrawable); + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) { - LLUUID id = nodep->mSavedGLTFMaterials[te]; - object->setRenderMaterialID(te, id); + param_block->setMaterial(te, asset_id); } } return true; @@ -2041,7 +2228,32 @@ void LLSelectMgr::selectionRevertGLTFMaterials() } setfunc(mSelectedObjects); getSelection()->applyToTEs(&setfunc); - LLSelectMgrSendFunctor sendfunc; + struct g : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + if (object && !object->permModify()) + { + return false; + } + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)object->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + if (param_block->isEmpty()) + { + object->setHasRenderMaterialParams(false); + } + else + { + object->parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); + } + } + + object->sendTEUpdate(); + return true; + } + } sendfunc; getSelection()->applyToObjects(&sendfunc); } @@ -6402,6 +6614,24 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep) LLSelectNode::~LLSelectNode() { + LLSelectMgr *manager = LLSelectMgr::getInstance(); + if (manager->mAllowSelectAvatar + && (!mLastPositionLocal.isExactlyZero() + || mLastRotation != LLQuaternion())) + { + LLViewerObject* object = getObject(); //isDead() check + if (object && !object->getParent()) + { + LLVOAvatar* avatar = object->asAvatar(); + if (avatar) + { + // Avatar was moved and needs to stay that way + manager->mAvatarOverridesMap.emplace(avatar->getID(), LLSelectMgr::AvatarPositionOverride(mLastPositionLocal, mLastRotation, object)); + } + } + } + + delete mPermissions; mPermissions = NULL; } @@ -6923,6 +7153,10 @@ void LLSelectMgr::updateSelectionCenter() const F32 MOVE_SELECTION_THRESHOLD = 1.f; // Movement threshold in meters for updating selection // center (tractor beam) + // override any avatar updates received + // Works only if avatar was repositioned + // and edit floater is visible + overrideAvatarUpdates(); //override any object updates received //for selected objects overrideObjectUpdates(); diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 3b76f87c44..cc6815296e 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -469,6 +469,30 @@ public: void resetObjectOverrides(LLObjectSelectionHandle selected_handle); void overrideObjectUpdates(); + void resetAvatarOverrides(); + void overrideAvatarUpdates(); + + struct AvatarPositionOverride + { + AvatarPositionOverride(); + AvatarPositionOverride(LLVector3 &vec, LLQuaternion &quat, LLViewerObject *obj) : + mLastPositionLocal(vec), + mLastRotation(quat), + mObject(obj) + { + } + LLVector3 mLastPositionLocal; + LLQuaternion mLastRotation; + LLPointer<LLViewerObject> mObject; + }; + + // Avatar overrides should persist even after selection + // was removed as long as edit floater is up + typedef std::map<LLUUID, AvatarPositionOverride> uuid_av_override_map_t; + uuid_av_override_map_t mAvatarOverridesMap; +public: + + // Returns the previous value of mForceSelection BOOL setForceSelection(BOOL force); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index a1c703b02f..634fc39460 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -123,7 +123,7 @@ void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, cons void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback) { - U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner(); + U32 nextOwnerPerm = LLFloaterPerms::getNextOwnerPerms("Settings"); createInventoryItem(settings, nextOwnerPerm, parent_id, settings_name, callback); } diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index abb936c3e5..ea671a130e 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -534,7 +534,7 @@ void LLSpeakerMgr::updateSpeakerList() } else if (mSpeakers.size() == 0) { - // For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list + // For all other session type (ad-hoc, P2P), we use the initial participants targets list for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it) { // Add buddies if they are on line, add any other avatar. diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index d1dbf72fe9..ed795b5155 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -245,14 +245,6 @@ public: bool isSpeakerToBeRemoved(const LLUUID& speaker_id); /** - * Removes avaline speaker. - * - * This is a HACK due to server does not send information that Avaline caller ends call. - * It can be removed when server is updated. See EXT-4301 for details - */ - bool removeAvalineSpeaker(const LLUUID& speaker_id) { return removeSpeaker(speaker_id); } - - /** * Initializes mVoiceModerated depend on LLSpeaker::mModeratorMutedVoice of agent's participant. * * Is used only to implement workaround to initialize mVoiceModerated on first join to group chat. See EXT-6937 diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 142dc4c46e..6aca701fe2 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -255,6 +255,7 @@ static bool mLoginStatePastUI = false; static bool mBenefitsSuccessfullyInit = false; const F32 STATE_AGENT_WAIT_TIMEOUT = 240; //seconds +const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Give region 3 chances std::unique_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState")); std::unique_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener()); @@ -927,6 +928,12 @@ bool idle_startup() LLPersistentNotificationStorage::initParamSingleton(); LLDoNotDisturbNotificationStorage::initParamSingleton(); } + else + { + // reinitialize paths in case user switched grids or accounts + LLPersistentNotificationStorage::getInstance()->reset(); + LLDoNotDisturbNotificationStorage::getInstance()->reset(); + } // Set PerAccountSettingsFile to the default value. std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")); @@ -1388,10 +1395,21 @@ bool idle_startup() { LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED ); } + else if (regionp->capabilitiesError()) + { + // Try to connect despite capabilities' error state + LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); + } else { U32 num_retries = regionp->getNumSeedCapRetries(); - if (num_retries > 0) + if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN) + { + // Region will keep trying to get capabilities, + // but for now continue as if caps were granted + LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); + } + else if (num_retries > 0) { LLStringUtil::format_map_t args; args["[NUMBER]"] = llformat("%d", num_retries + 1); @@ -2385,6 +2403,11 @@ void login_callback(S32 option, void *userdata) void show_release_notes_if_required() { static bool release_notes_shown = false; + // We happen to know that instantiating LLVersionInfo implicitly + // instantiates the LLEventMailDrop named "relnotes", which we (might) use + // below. If viewer release notes stop working, might be because that + // LLEventMailDrop got moved out of LLVersionInfo and hasn't yet been + // instantiated. if (!release_notes_shown && (LLVersionInfo::instance().getChannelAndVersion() != gLastRunVersion) && LLVersionInfo::instance().getViewerMaturity() != LLVersionInfo::TEST_VIEWER // don't show Release Notes for the test builds && gSavedSettings.getBOOL("UpdaterShowReleaseNotes") @@ -2503,8 +2526,6 @@ void use_circuit_callback(void**, S32 result) void register_viewer_callbacks(LLMessageSystem* msg) { msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data ); - msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader ); - msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket ); msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update ); msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update ); msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update ); diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 2dad9cd2dc..f4649a672b 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -416,15 +416,6 @@ BOOL LLFloaterTexturePicker::postBuild() mInventoryPanel = getChild<LLInventoryPanel>("inventory panel"); - // if can select both materials and textures, set textures_material_combo's layout as visible - childSetVisible("combo_layout", mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL); - - mTextureMaterialsCombo = getChild<LLComboBox>("textures_material_combo"); - mTextureMaterialsCombo->setCommitCallback(onSelectTextureMaterials, this); - - // set the combo box to the first entry in the list (currently textures and materials) - mTextureMaterialsCombo->selectByValue(0); - mModeSelector = getChild<LLComboBox>("mode_selection"); mModeSelector->setCommitCallback(onModeSelect, this); mModeSelector->selectByValue(0); @@ -435,7 +426,7 @@ BOOL LLFloaterTexturePicker::postBuild() // selected at startup, we call the same function that is triggered // when a texture/materials/both choice is made and let it take care // of setting the filters - onSelectTextureMaterials(0, this); + refreshInventoryFilter(); mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask); mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2)); @@ -469,21 +460,7 @@ BOOL LLFloaterTexturePicker::postBuild() mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list"); mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this); - mLocalScrollCtrl->clearRows(); - - if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) - { - LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); - LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); - } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) - { - LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); - } - else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) - { - LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); - } + refreshLocalList(); mNoCopyTextureSelected = FALSE; @@ -531,6 +508,8 @@ void LLFloaterTexturePicker::draw() if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) { + // TODO: Fix this! Picker is not warrantied to be connected to a selection + // LLSelectMgr shouldn't be used in texture picker LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); if (obj) { @@ -843,7 +822,6 @@ void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata) self->getChild<LLButton>("Blank")->setVisible(index == 0 ? TRUE : FALSE); self->getChild<LLButton>("None")->setVisible(index == 0 ? TRUE : FALSE); self->getChild<LLButton>("Pipette")->setVisible(index == 0 ? TRUE : FALSE); - self->getChild<LLComboBox>("textures_material_combo")->setVisible(index == 0 ? TRUE : FALSE); self->getChild<LLFilterEditor>("inventory search editor")->setVisible(index == 0 ? TRUE : FALSE); self->getChild<LLInventoryPanel>("inventory panel")->setVisible(index == 0 ? TRUE : FALSE); @@ -963,21 +941,7 @@ void LLFloaterTexturePicker::onBtnRemove(void* userdata) self->getChild<LLButton>("l_rem_btn")->setEnabled(false); self->getChild<LLButton>("l_upl_btn")->setEnabled(false); - self->mLocalScrollCtrl->clearRows(); - - if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) - { - LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); - LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); - } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) - { - LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); - } - else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) - { - LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl); - } + self->refreshLocalList(); } } @@ -1205,36 +1169,46 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) mInventoryPanel->setFilterSubString(search_string); } -void LLFloaterTexturePicker::onSelectTextureMaterials(LLUICtrl* ctrl, void *userdata) +void LLFloaterTexturePicker::refreshLocalList() { - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata; - int index = self->mTextureMaterialsCombo->getValue().asInteger(); - - U32 filter_types = 0x0; + mLocalScrollCtrl->clearRows(); - if (self->mInventoryPickType != LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) { - // mInventoryPickType overrides combo - index = self->mInventoryPickType; + LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); + LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); } + else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) + { + LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); + } + else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) + { + LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); + } +} + +void LLFloaterTexturePicker::refreshInventoryFilter() +{ + U32 filter_types = 0x0; - if (index == LLTextureCtrl::PICK_TEXTURE_MATERIAL) + if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) { filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; filter_types |= 0x1 << LLInventoryType::IT_MATERIAL; } - else if (index == LLTextureCtrl::PICK_TEXTURE) + else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) { filter_types |= 0x1 << LLInventoryType::IT_TEXTURE; filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT; } - else if (index == LLTextureCtrl::PICK_MATERIAL) + else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) { filter_types |= 0x1 << LLInventoryType::IT_MATERIAL; } - self->mInventoryPanel->setFilterTypes(filter_types); + mInventoryPanel->setFilterTypes(filter_types); } void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled) @@ -1267,27 +1241,8 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryType type) { mInventoryPickType = type; - - // if can select both materials and textures, set textures_material_combo's layout as visible - childSetVisible("combo_layout", mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL); - - mLocalScrollCtrl->clearRows(); - if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL) - { - LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); - LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); - } - else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE) - { - LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl); - } - else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL) - { - LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl); - } - - // refresh filters - onSelectTextureMaterials(0, this); + refreshLocalList(); + refreshInventoryFilter(); } void LLFloaterTexturePicker::onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle) @@ -1712,56 +1667,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id) if (op == TEXTURE_SELECT && mOnSelectCallback) { - // determine if the selected item in inventory is a material - // by finding the item in inventory and inspecting its (IT_) type - LLUUID item_id = floaterp->findItemID(floaterp->getAssetID(), FALSE); - LLInventoryItem* item = gInventory.getItem(item_id); - if (item) - { - if (item->getInventoryType() == LLInventoryType::IT_MATERIAL) - { - // ask the selection manager for the list of selected objects - // to which the material will be applied. - LLObjectSelectionHandle selectedObjectsHandle = LLSelectMgr::getInstance()->getSelection(); - if (selectedObjectsHandle.notNull()) - { - LLObjectSelection* selectedObjects = selectedObjectsHandle.get(); - if (!selectedObjects->isEmpty()) - { - // we have a selection - iterate over it - for (LLObjectSelection::valid_iterator obj_iter = selectedObjects->valid_begin(); - obj_iter != selectedObjects->valid_end(); - ++obj_iter) - { - LLSelectNode* object = *obj_iter; - LLViewerObject* viewer_object = object->getObject(); - if (viewer_object) - { - // the asset ID of the material we want to apply - // the the selected objects - LLUUID asset_id = item->getAssetUUID(); - - // iterate over the faces in the object - // TODO: consider the case where user has - // selected only certain faces - S32 num_faces = viewer_object->getNumTEs(); - for (S32 face = 0; face < num_faces; face++) - { - viewer_object->setRenderMaterialID(face, asset_id); - dialog_refresh_all(); - } - viewer_object->sendTEUpdate(); - } - } - } - } - } - } - else - // original behavior for textures, not materials - { - mOnSelectCallback(this, LLSD()); - } + mOnSelectCallback(this, LLSD()); } else if (op == TEXTURE_CANCEL && mOnCancelCallback) { diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 9cb86a2e74..0a5a281e76 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -78,8 +78,6 @@ public: TEXTURE_CANCEL } ETexturePickOp; - // Should match the entries in floater_texture_ctrl.xml - // for the textures_material_combo combo box typedef enum e_pick_inventory_type { PICK_TEXTURE_MATERIAL = 0, @@ -356,8 +354,6 @@ public: static void onBakeTextureSelect(LLUICtrl* ctrl, void *userdata); static void onHideBaseMeshRegionCheck(LLUICtrl* ctrl, void *userdata); - static void onSelectTextureMaterials(LLUICtrl* ctrl, void *userdata); - void setLocalTextureEnabled(BOOL enabled); void setBakeTextureEnabled(BOOL enabled); @@ -366,6 +362,9 @@ public: static void onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle); protected: + void refreshLocalList(); + void refreshInventoryFilter(); + LLPointer<LLViewerTexture> mTexturep; LLView* mOwner; @@ -387,7 +386,6 @@ protected: BOOL mActive; LLFilterEditor* mFilterEdit; - LLComboBox* mTextureMaterialsCombo; LLInventoryPanel* mInventoryPanel; PermissionMask mImmediateFilterPermMask; PermissionMask mDnDFilterPermMask; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index dc10e42446..987918fc1d 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -262,7 +262,6 @@ static const char* e_state_name[] = "LOAD_FROM_TEXTURE_CACHE", "CACHE_POST", "LOAD_FROM_NETWORK", - "LOAD_FROM_SIMULATOR", "WAIT_HTTP_RESOURCE", "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", @@ -428,7 +427,6 @@ public: LOAD_FROM_TEXTURE_CACHE, CACHE_POST, LOAD_FROM_NETWORK, - LOAD_FROM_SIMULATOR, WAIT_HTTP_RESOURCE, // Waiting for HTTP resources WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources SEND_HTTP_REQ, // Commit to sending as HTTP @@ -472,17 +470,11 @@ private: // Locks: Mw void clearPackets(); - // Locks: Mw - void setupPacketData(); // Locks: Mw void removeFromCache(); // Threads: Ttf - // Locks: Mw - bool processSimulatorPackets(); - - // Threads: Ttf bool writeToCacheComplete(); // Threads: Ttf @@ -581,8 +573,7 @@ private: BOOL mHaveAllData; BOOL mInLocalCache; BOOL mInCache; - bool mCanUseHTTP, - mCanUseNET ; //can get from asset server. + bool mCanUseHTTP; S32 mRetryAttempt; S32 mActiveCount; LLCore::HttpStatus mGetStatus; @@ -854,7 +845,6 @@ const char* sStateDescs[] = { "LOAD_FROM_TEXTURE_CACHE", "CACHE_POST", "LOAD_FROM_NETWORK", - "LOAD_FROM_SIMULATOR", "WAIT_HTTP_RESOURCE", "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", @@ -866,7 +856,7 @@ const char* sStateDescs[] = { "DONE" }; -const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR, +const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE }; // static @@ -940,8 +930,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mResourceWaitCount(0U), mFetchRetryPolicy(10.f,3600.f,2.f,10) { - mCanUseNET = mUrl.empty() ; - mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; // LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL; if (!mFetcher->mDebugPause) @@ -1003,39 +991,6 @@ void LLTextureFetchWorker::clearPackets() mFirstPacket = 0; } -// Locks: Mw -void LLTextureFetchWorker::setupPacketData() -{ - S32 data_size = 0; - if (mFormattedImage.notNull()) - { - data_size = mFormattedImage->getDataSize(); - } - if (data_size > 0) - { - // Only used for simulator requests - mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1; - if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size) - { - LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL; - removeFromCache(); - resetFormattedData(); - clearPackets(); - } - else if (mFileSize > 0) - { - mLastPacket = mFirstPacket-1; - mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1; - } - else - { - // This file was cached using HTTP so we have to refetch the first packet - resetFormattedData(); - clearPackets(); - } - } -} - // Locks: Mw (ctor invokes without lock) void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size) { @@ -1127,14 +1082,14 @@ bool LLTextureFetchWorker::doWork(S32 param) if (mImagePriority < F_ALMOST_ZERO) { - if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR) + if (mState == INIT || mState == LOAD_FROM_NETWORK) { LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - priority < 0"); LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL; return true; // abort } } - if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP) + if(mState > CACHE_POST && !mCanUseHTTP) { LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post"); //nowhere to get data, abort. @@ -1357,14 +1312,14 @@ bool LLTextureFetchWorker::doWork(S32 param) else { mCanUseHTTP = false ; - LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL; + LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL; } } else { // This will happen if not logged in or if a region deoes not have HTTP Texture enabled //LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL; - LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL; + LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL; mCanUseHTTP = false; } } @@ -1382,77 +1337,12 @@ bool LLTextureFetchWorker::doWork(S32 param) } // don't return, fall through to next state } - else if (mSentRequest == UNSENT && mCanUseNET) - { - // Add this to the network queue and sit here. - // LLTextureFetch::update() will send off a request which will change our state - mWriteToCacheState = CAN_WRITE ; - mRequestedSize = mDesiredSize; - mRequestedDiscard = mDesiredDiscard; - mSentRequest = QUEUED; - mFetcher->addToNetworkQueue(this); - recordTextureStart(false); - return false; - } else { - // Shouldn't need to do anything here - //llassert(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); return false; } } - if (mState == LOAD_FROM_SIMULATOR) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_SIMULATOR"); - if (mFormattedImage.isNull()) - { - mFormattedImage = new LLImageJ2C; - } - if (processSimulatorPackets()) - { - // Capture some measure of total size for metrics - F64 byte_count = 0; - if (mLastPacket >= mFirstPacket) - { - for (S32 i=mFirstPacket; i<=mLastPacket; i++) - { - llassert_always((i>=0) && (i<mPackets.size())); - if (mPackets[i]) - { - byte_count += mPackets[i]->mSize; - } - } - } - - LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL; - mFetcher->removeFromNetworkQueue(this, false); - if (mFormattedImage.isNull() || !mFormattedImage->getDataSize()) - { - // processSimulatorPackets() failed -// LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL; - LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL; - return true; // failed - } - - if (mLoadedDiscard < 0) - { - LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard - << ", should be >=0" << LL_ENDL; - } - setState(DECODE_IMAGE); - mWriteToCacheState = SHOULD_WRITE; - - recordTextureDone(false, byte_count); - } - else - { - mFetcher->addToNetworkQueue(this); // failsafe - recordTextureStart(false); - } - return false; - } - if (mState == WAIT_HTTP_RESOURCE) { LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE"); @@ -1496,8 +1386,6 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL; return true; // abort } - - mFetcher->removeFromNetworkQueue(this, false); S32 cur_size = 0; if (mFormattedImage.notNull()) @@ -1642,17 +1530,6 @@ bool LLTextureFetchWorker::doWork(S32 param) } return true; } - - // roll back to try UDP - if (mCanUseNET) - { - setState(INIT); - mCanUseHTTP = false; - mUrl.clear(); - releaseHttpSemaphore(); - //return false; - return doWork(param); - } } else if (http_service_unavail == mGetStatus) { @@ -2222,69 +2099,6 @@ void LLTextureFetchWorker::removeFromCache() // Threads: Ttf // Locks: Mw -bool LLTextureFetchWorker::processSimulatorPackets() -{ - if (mFormattedImage.isNull() || mRequestedSize < 0) - { - // not sure how we got here, but not a valid state, abort! - llassert_always(mDecodeHandle == 0); - mFormattedImage = NULL; - return true; - } - - if (mLastPacket >= mFirstPacket) - { - S32 buffer_size = mFormattedImage->getDataSize(); - for (S32 i = mFirstPacket; i<=mLastPacket; i++) - { - llassert_always((i>=0) && (i<mPackets.size())); - llassert_always(mPackets[i]); - buffer_size += mPackets[i]->mSize; - } - bool have_all_data = mLastPacket >= mTotalPackets-1; - if (mRequestedSize <= 0) - { - // We received a packed but haven't requested anything yet (edge case) - // Return true (we're "done") since we didn't request anything - return true; - } - if (buffer_size >= mRequestedSize || have_all_data) - { - /// We have enough (or all) data - if (have_all_data) - { - mHaveAllData = TRUE; - } - S32 cur_size = mFormattedImage->getDataSize(); - if (buffer_size > cur_size) - { - /// We have new data - U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size); - S32 offset = 0; - if (cur_size > 0 && mFirstPacket > 0) - { - memcpy(buffer, mFormattedImage->getData(), cur_size); - offset = cur_size; - } - for (S32 i=mFirstPacket; i<=mLastPacket; i++) - { - memcpy(buffer + offset, mPackets[i]->mData, mPackets[i]->mSize); - offset += mPackets[i]->mSize; - } - // NOTE: setData releases current data - mFormattedImage->setData(buffer, buffer_size); - } - mLoadedDiscard = mRequestedDiscard; - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////////// - -// Threads: Ttf -// Locks: Mw S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, bool partial, bool success) { @@ -2616,13 +2430,13 @@ LLTextureFetch::~LLTextureFetch() // ~LLQueuedThread() called here } -bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, +S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) { LL_PROFILE_ZONE_SCOPED; if (mDebugPause) { - return false; + return -1; } if (f_type == FTT_SERVER_BAKE) @@ -2638,7 +2452,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const << host << " != " << worker->mHost << LL_ENDL; removeRequest(worker, true); worker = NULL; - return false; + return -1; } } @@ -2691,13 +2505,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const { if (worker->wasAborted()) { - return false; // need to wait for previous aborted request to complete + return -1; // need to wait for previous aborted request to complete } worker->lockWorkMutex(); // +Mw if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) { worker->unlockWorkMutex(); // -Mw - return false; // similar request has failed or is in a transitional state + return -1; // similar request has failed or is in a transitional state } worker->mActiveCount++; worker->mNeedsAux = needs_aux; @@ -2732,49 +2546,13 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const worker->setCanUseHTTP(can_use_http) ; worker->unlockWorkMutex(); // -Mw } - + LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type) << " Discard: " << desired_discard << " size " << desired_size << LL_ENDL; - return true; + return desired_discard; } -// Threads: T* (but Ttf in practice) - -// protected -void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) -{ - LL_PROFILE_ZONE_SCOPED; - lockQueue(); // +Mfq - bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ; - unlockQueue(); // -Mfq - - LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq - if (in_request_map) - { - // only add to the queue if in the request map - // i.e. a delete has not been requested - mNetworkQueue.insert(worker->mID); - } - for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); - iter1 != mCancelQueue.end(); ++iter1) - { - iter1->second.erase(worker->mID); - } -} // -Mfnq - -// Threads: T* -void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel) -{ - LL_PROFILE_ZONE_SCOPED; - LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq - size_t erased = mNetworkQueue.erase(worker->mID); - if (cancel && erased > 0) - { - mCancelQueue[worker->mHost].insert(worker->mID); - } -} // -Mfnq - // Threads: T* // // protected @@ -2811,7 +2589,6 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; worker->scheduleDelete(); @@ -2840,7 +2617,6 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; worker->scheduleDelete(); @@ -3137,17 +2913,6 @@ S32 LLTextureFetch::update(F32 max_time_ms) S32 res = LLWorkerThread::update(max_time_ms); - if (!mDebugPause) - { - // this is the startup state when send_complete_agent_movement() message is sent. - // Before this, the RequestImages message sent by sendRequestListToSimulators - // won't work so don't bother trying - if (LLStartUp::getStartupState() > STATE_AGENT_SEND) - { - sendRequestListToSimulators(); - } - } - if (!mThreaded) { commonUpdate(); @@ -3222,203 +2987,6 @@ void LLTextureFetch::threadedUpdate() ////////////////////////////////////////////////////////////////////////////// -// Threads: Tmain -void LLTextureFetch::sendRequestListToSimulators() -{ - LL_PROFILE_ZONE_SCOPED; - // All requests - const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps - - // Sim requests - const S32 IMAGES_PER_REQUEST = 50; - const F32 SIM_LAZY_FLUSH_TIMEOUT = 10.0f; // temp - const F32 MIN_REQUEST_TIME = 1.0f; - const F32 MIN_DELTA_PRIORITY = 1000.f; - - // Periodically, gather the list of textures that need data from the network - // And send the requests out to the simulators - static LLFrameTimer timer; - if (timer.getElapsedTimeF32() < REQUEST_DELTA_TIME) - { - return; - } - timer.reset(); - - // Send requests - typedef std::set<LLTextureFetchWorker*,LLTextureFetchWorker::Compare> request_list_t; - typedef std::map< LLHost, request_list_t > work_request_map_t; - work_request_map_t requests; - { - LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq - for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); ) - { - queue_t::iterator curiter = iter++; - LLTextureFetchWorker* req = getWorker(*curiter); - if (!req) - { - mNetworkQueue.erase(curiter); - continue; // paranoia - } - if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) && - (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR)) - { - // We already received our URL, remove from the queue - LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL; - mNetworkQueue.erase(curiter); - continue; - } - if (req->mID == mDebugID) - { - mDebugCount++; // for setting breakpoints - } - if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM && - req->mTotalPackets > 0 && - req->mLastPacket >= req->mTotalPackets-1) - { - // We have all the packets... make sure this is high priority - continue; - } - F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32(); - { - F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority); - if ((req->mSimRequestedDiscard != req->mDesiredDiscard) || - (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) || - (elapsed >= SIM_LAZY_FLUSH_TIMEOUT)) - { - requests[req->mHost].insert(req); - } - } - } - } // -Mfnq - - for (work_request_map_t::iterator iter1 = requests.begin(); - iter1 != requests.end(); ++iter1) - { - LLHost host = iter1->first; - // invalid host = use agent host - if (host.isInvalid()) - { - host = gAgent.getRegionHost(); - } - - S32 sim_request_count = 0; - - for (request_list_t::iterator iter2 = iter1->second.begin(); - iter2 != iter1->second.end(); ++iter2) - { - LLTextureFetchWorker* req = *iter2; - if (gMessageSystem) - { - if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM) - { - // Initialize packet data based on data read from cache - req->lockWorkMutex(); // +Mw - req->setupPacketData(); - req->unlockWorkMutex(); // -Mw - } - if (0 == sim_request_count) - { - gMessageSystem->newMessageFast(_PREHASH_RequestImage); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - S32 packet = req->mLastPacket + 1; - LL_INFOS() << req->mID << ": " << req->mImagePriority << LL_ENDL; - gMessageSystem->nextBlockFast(_PREHASH_RequestImage); - gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID); - gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard); - gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority); - gMessageSystem->addU32Fast(_PREHASH_Packet, packet); - gMessageSystem->addU8Fast(_PREHASH_Type, req->mType); -// LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard -// << " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL; - - static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false); - static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false); - if (log_to_viewer_log || log_to_sim) - { - mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime()); - mTextureInfo.setRequestOffset(req->mID, 0); - mTextureInfo.setRequestSize(req->mID, 0); - mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP); - } - - req->lockWorkMutex(); // +Mw - req->mSentRequest = LLTextureFetchWorker::SENT_SIM; - req->mSimRequestedDiscard = req->mDesiredDiscard; - req->mRequestedPriority = req->mImagePriority; - req->mRequestedDeltaTimer.reset(); - req->unlockWorkMutex(); // -Mw - sim_request_count++; - if (sim_request_count >= IMAGES_PER_REQUEST) - { -// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; - - gMessageSystem->sendSemiReliable(host, NULL, NULL); - sim_request_count = 0; - } - } - } - if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST) - { -// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; - gMessageSystem->sendSemiReliable(host, NULL, NULL); - sim_request_count = 0; - } - } - - // Send cancelations - { - LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq - if (gMessageSystem && !mCancelQueue.empty()) - { - for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); - iter1 != mCancelQueue.end(); ++iter1) - { - LLHost host = iter1->first; - if (host.isInvalid()) - { - host = gAgent.getRegionHost(); - } - S32 request_count = 0; - for (queue_t::iterator iter2 = iter1->second.begin(); - iter2 != iter1->second.end(); ++iter2) - { - if (0 == request_count) - { - gMessageSystem->newMessageFast(_PREHASH_RequestImage); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - gMessageSystem->nextBlockFast(_PREHASH_RequestImage); - gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2); - gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1); - gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0); - gMessageSystem->addU32Fast(_PREHASH_Packet, 0); - gMessageSystem->addU8Fast(_PREHASH_Type, 0); -// LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL; - - request_count++; - if (request_count >= IMAGES_PER_REQUEST) - { - gMessageSystem->sendSemiReliable(host, NULL, NULL); - request_count = 0; - } - } - if (request_count > 0 && request_count < IMAGES_PER_REQUEST) - { - gMessageSystem->sendSemiReliable(host, NULL, NULL); - } - } - mCancelQueue.clear(); - } - } // -Mfnq -} - -////////////////////////////////////////////////////////////////////////////// - // Threads: T* // Locks: Mw bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) @@ -3483,138 +3051,6 @@ void LLTextureFetchWorker::setState(e_state new_state) mState = new_state; } -// Threads: T* -bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, - U16 data_size, U8* data) -{ - LL_PROFILE_ZONE_SCOPED; - LLTextureFetchWorker* worker = getWorker(id); - bool res = true; - - ++mPacketCount; - - if (!worker) - { -// LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL; - res = false; - } - else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK || - worker->mSentRequest != LLTextureFetchWorker::SENT_SIM) - { -// LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id -// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] -// << " sent: " << worker->mSentRequest << LL_ENDL; - res = false; - } - else if (worker->mLastPacket != -1) - { - // check to see if we've gotten this packet before -// LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL; - res = false; - } - else if (!data_size) - { -// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; - res = false; - } - if (!res) - { - mNetworkQueueMutex.lock(); // +Mfnq - ++mBadPacketCount; - mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock(); // -Mfnq - return false; - } - - LLViewerStatsRecorder::instance().textureFetch(data_size); - LLViewerStatsRecorder::instance().log(0.1f); - - worker->lockWorkMutex(); - - - // Copy header data into image object - worker->mImageCodec = codec; - worker->mTotalPackets = packets; - worker->mFileSize = (S32)totalbytes; - llassert_always(totalbytes > 0); - llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize); - res = worker->insertPacket(0, data, data_size); - worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR); - worker->unlockWorkMutex(); // -Mw - return res; -} - - -// Threads: T* -bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data) -{ - LL_PROFILE_ZONE_SCOPED; - LLTextureFetchWorker* worker = getWorker(id); - bool res = true; - - ++mPacketCount; - - if (!worker) - { -// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL; - res = false; - } - else if (worker->mLastPacket == -1) - { -// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL; - res = false; - } - else if (!data_size) - { -// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; - res = false; - } - if (!res) - { - mNetworkQueueMutex.lock(); // +Mfnq - ++mBadPacketCount; - mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock(); // -Mfnq - return false; - } - - LLViewerStatsRecorder::instance().textureFetch(data_size); - LLViewerStatsRecorder::instance().log(0.1f); - - worker->lockWorkMutex(); - - - res = worker->insertPacket(packet_num, data, data_size); - - if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) || - (worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK)) - { - worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR); - } - else - { -// LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id -// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL; - removeFromNetworkQueue(worker, true); // failsafe - } - - if (packet_num >= (worker->mTotalPackets - 1)) - { - static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false); - static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false); - - if (log_to_viewer_log || log_to_sim) - { - U64Microseconds timeNow = LLTimer::getTotalTime(); - mTextureInfoMainThread.setRequestSize(id, worker->mFileSize); - mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow); - } - } - worker->unlockWorkMutex(); // -Mw - - return res; -} - ////////////////////////////////////////////////////////////////////////////// // Threads: T* @@ -3666,13 +3102,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32(); if (worker->mFileSize > 0) { - if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) - { - S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE; - data_size = llmax(data_size, 0); - data_progress = (F32)data_size / (F32)worker->mFileSize; - } - else if (worker->mFormattedImage.notNull()) + if (worker->mFormattedImage.notNull()) { data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize; } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 3ca88422a2..4297117f75 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -77,7 +77,7 @@ public: void shutDownImageDecodeThread(); // Threads: T* (but Tmain mostly) - bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, + S32 createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http); // Requests that a fetch operation be deleted from the queue. @@ -102,12 +102,6 @@ public: // Threads: T* bool updateRequestPriority(const LLUUID& id, F32 priority); - // Threads: T* - bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data); - - // Threads: T* - bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data); - // Threads: T* (but not safe) void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; } @@ -229,12 +223,6 @@ public: // ---------------------------------- protected: - // Threads: T* (but Ttf in practice) - void addToNetworkQueue(LLTextureFetchWorker* worker); - - // Threads: T* - void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); - // Threads: T* void addToHTTPQueue(const LLUUID& id); @@ -253,9 +241,6 @@ protected: bool runCondition(); private: - // Threads: Tmain - void sendRequestListToSimulators(); - // Threads: Ttf /*virtual*/ void startThread(void); @@ -321,7 +306,7 @@ public: private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only - LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. + LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue LLTextureCache* mTextureCache; @@ -331,10 +316,8 @@ private: // Set of requests that require network data typedef std::set<LLUUID> queue_t; - queue_t mNetworkQueue; // Mfnq queue_t mHTTPTextureQueue; // Mfnq typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t; - cancel_queue_t mCancelQueue; // Mfnq F32 mTextureBandwidth; // <none> F32 mMaxBandwidth; // Mfnq LLTextureInfo mTextureInfo; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index f0e9cee101..1f4f086352 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -223,7 +223,6 @@ void LLTextureBar::draw() { "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE { "DSK", LLColor4::blue }, // CACHE_POST { "NET", LLColor4::green }, // LOAD_FROM_NETWORK - { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2 { "REQ", LLColor4::yellow },// SEND_HTTP_REQ diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index ab54e2afc6..282c84d7fc 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1114,6 +1114,11 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, for (S32 face = 0; face < num_faces; face++) { // update viewer side material in anticipation of update from simulator + + // TODO: fix this! + // Calling setRenderMaterialID multiple times sends material param + // updates multiple times and can create race condition. + // Send update only once! hit_obj->setRenderMaterialID(face, asset_id); dialog_refresh_all(); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 9682945208..2413d7705a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -381,7 +381,7 @@ static bool handleJoystickChanged(const LLSD& newvalue) static bool handleUseOcclusionChanged(const LLSD& newvalue) { - LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery + LLPipeline::sUseOcclusion = (newvalue.asBoolean() && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0; return true; } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 77b84c6789..7e1f8db9a8 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -748,7 +748,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) glh::matrix4f proj = get_current_projection(); glh::matrix4f mod = get_current_modelview(); glViewport(0,0,512,512); - LLVOAvatar::updateFreezeCounter() ; LLVOAvatar::updateImpostors(); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index f770db31dd..c8d4aae8fd 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -134,6 +134,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary() addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true)); addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); addEntry(LLFolderType::FT_SETTINGS, new ViewerFolderEntry("Settings", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); + addEntry(LLFolderType::FT_MATERIAL, new ViewerFolderEntry("Materials", "Inv_SysOpen", "Inv_SysClosed", FALSE, true)); bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible"); addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Received Items", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible)); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 661f70972d..636909e6f2 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -3194,7 +3194,7 @@ bool LLViewerMediaImpl::isForcedUnloaded() const } // If this media's class is not supposed to be shown, unload - if (!shouldShowBasedOnClass()) + if (!shouldShowBasedOnClass() || isObscured()) { return true; } @@ -3881,6 +3881,26 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const ////////////////////////////////////////////////////////////////////////////////////////// // +bool LLViewerMediaImpl::isObscured() const +{ + if (getUsedInUI() || isParcelMedia()) return false; + + LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (!agent_parcel) + { + return false; + } + + if (agent_parcel->getObscureMOAP() && !isInAgentParcel()) + { + return true; + } + + return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const { bool result = false; diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index 806692929a..b95cfd4c68 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -423,6 +423,7 @@ public: private: bool isAutoPlayable() const; bool shouldShowBasedOnClass() const; + bool isObscured() const; static bool isObjectAttachedToAnotherAvatar(LLVOVolume *obj); static bool isObjectInAgentParcel(LLVOVolume *obj); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index dd82d43ab2..1842c434e7 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -33,10 +33,11 @@ #include "llviewermenu.h" // linden library includes -#include "llavatarnamecache.h" // IDEVO +#include "llavatarnamecache.h" // IDEVO (I Are Not Men!) +#include "llcombobox.h" +#include "llcoros.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" -#include "llcombobox.h" #include "llinventorypanel.h" #include "llnotifications.h" #include "llnotificationsutil.h" @@ -93,6 +94,7 @@ #include "llmarketplacefunctions.h" #include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmoveview.h" +#include "llnavigationbar.h" #include "llparcel.h" #include "llrootview.h" #include "llsceneview.h" @@ -2309,44 +2311,6 @@ class LLAdvancedCheckViewAdminOptions : public view_listener_t } }; -///////////////////////////////////// -// Enable Object Object Occlusion /// -///////////////////////////////////// -class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - - bool new_value = gGLManager.mHasOcclusionQuery; // && LLFeatureManager::getInstance()->isFeatureAvailable(userdata.asString()); - return new_value; -} -}; - -///////////////////////////////////// -// Enable Framebuffer Objects /// -///////////////////////////////////// -class LLAdvancedEnableRenderFBO: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject; - return new_value; - } -}; - -///////////////////////////////////// -// Enable Deferred Rendering /// -///////////////////////////////////// -class LLAdvancedEnableRenderDeferred: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && - LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0; - return new_value; - } -}; - ////////////////// // ADMIN STATUS // ////////////////// @@ -2391,6 +2355,7 @@ class LLAdvancedForceErrorLlerror : public view_listener_t return true; } }; + class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2400,6 +2365,22 @@ class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t } }; +class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLCoros::instance().launch( + "AdvancedForceErrorBadMemoryAccessCoro", + [](){ + // Wait for one mainloop() iteration, letting the enclosing + // handleEvent() method return. + llcoro::suspend(); + force_error_bad_memory_access(NULL); + }); + return true; + } +}; + class LLAdvancedForceErrorInfiniteLoop : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -2418,6 +2399,22 @@ class LLAdvancedForceErrorSoftwareException : public view_listener_t } }; +class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLCoros::instance().launch( + "AdvancedForceErrorSoftwareExceptionCoro", + [](){ + // Wait for one mainloop() iteration, letting the enclosing + // handleEvent() method return. + llcoro::suspend(); + force_error_software_exception(NULL); + }); + return true; + } +}; + class LLAdvancedForceErrorDriverCrash : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -5341,12 +5338,10 @@ class LLToolsEnablePathfindingRebakeRegion : public view_listener_t { bool returnValue = false; - if (LLPathfindingManager::getInstance() != NULL) - { - LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance(); - returnValue = (rebakeInstance->canRebakeRegion() && - (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available)); - } + if (LLNavigationBar::instanceExists()) + { + returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable(); + } return returnValue; } }; @@ -9367,8 +9362,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe"); view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); // Develop > Render - view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion"); - view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame"); @@ -9475,8 +9468,10 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint"); view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror"); view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess"); + view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro"); view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop"); view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException"); + view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro"); view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e959f24f1f..49049a19d9 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3338,13 +3338,6 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) // trigger a control event. U32 control_flags = gAgent.getControlFlags(); - // Rotation into both directions should cancel out - U32 mask = AGENT_CONTROL_YAW_POS | AGENT_CONTROL_YAW_NEG; - if ((control_flags & mask) == mask) - { - control_flags &= ~mask; - } - MASK key_mask = gKeyboard->currentMask(TRUE); if (key_mask & MASK_ALT || key_mask & MASK_CONTROL) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 5829ccb6d8..022c191a65 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -363,6 +363,13 @@ LLViewerObject::~LLViewerObject() mPartSourcep = NULL; } + if (mText) + { + // something recovered LLHUDText when object was already dead + mText->markDead(); + mText = NULL; + } + // Delete memory associated with extra parameters. std::map<U16, ExtraParameter*>::iterator iter; for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter) @@ -2469,11 +2476,19 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, needs_refresh = needs_refresh || child->mUserSelected; } + static LLCachedControl<bool> allow_select_avatar(gSavedSettings, "AllowSelectAvatar", FALSE); if (needs_refresh) { LLSelectMgr::getInstance()->updateSelectionCenter(); dialog_refresh_all(); - } + } + else if (allow_select_avatar && asAvatar()) + { + // Override any avatar position updates received + // Works only if avatar was repositioned using build + // tools and build floater is visible + LLSelectMgr::getInstance()->overrideAvatarUpdates(); + } // Mark update time as approx. now, with the ping delay. @@ -7065,7 +7080,12 @@ void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id) if (id.notNull()) { getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id)); - setHasRenderMaterialParams(true); + + if (!hasRenderMaterialParams()) + { + // make sure param section exists + setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an immediate update*/); + } } else { diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 389f5087e2..768b4f425b 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -571,7 +571,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if(update_cache) { - objectp = regionp->updateCacheEntry(local_id, objectp, update_type); + //update object cache if the object receives a full-update or terse update + objectp = regionp->updateCacheEntry(local_id, objectp); } // This looks like it will break if the local_id of the object doesn't change diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index c785c80cea..a75eb518f3 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -917,15 +917,12 @@ void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, Octr void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames() { - if (gGLManager.mHasOcclusionQuery) + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) + if (mOcclusionQuery[i]) { - if (mOcclusionQuery[i]) - { - releaseOcclusionQueryObjectName(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } + releaseOcclusionQueryObjectName(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; } } } @@ -1129,7 +1126,7 @@ void LLOcclusionCullingGroup::checkOcclusion() GLuint available; { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query available"); - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available); } if (available) @@ -1137,7 +1134,7 @@ void LLOcclusionCullingGroup::checkOcclusion() GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint) { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result"); - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result); + glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT, &query_result); } #if LL_TRACK_PENDING_OCCLUSION_QUERIES sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); @@ -1197,7 +1194,6 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh OCCLUSION_FUDGE_Z = 1.; } - // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension if (earlyFail(camera, bounds)) { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - early fail"); @@ -1221,17 +1217,12 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh // 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 || + bool const use_depth_clamp = (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER); - LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); + LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); -#if !LL_DARWIN - U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; -#else - U32 mode = GL_SAMPLES_PASSED_ARB; -#endif + U32 mode = gGLManager.mGLVersion >= 3.3f ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED; #if LL_TRACK_PENDING_OCCLUSION_QUERIES sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index e69b0347f8..f58eac2ed9 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1553,6 +1553,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use BOOL region_allow_environment_override = true; S32 parcel_environment_version = 0; BOOL agent_parcel_update = false; // updating previous(existing) agent parcel + U32 extended_flags = 0; //obscure MOAP S32 other_clean_time = 0; @@ -1642,6 +1643,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use msg->getBOOLFast(_PREHASH_RegionAllowAccessBlock, _PREHASH_RegionAllowAccessOverride, region_allow_access_override); } + if (msg->getNumberOfBlocks(_PREHASH_ParcelExtendedFlags)) + { + msg->getU32Fast(_PREHASH_ParcelExtendedFlags, _PREHASH_Flags, extended_flags); + } + if (msg->getNumberOfBlocks(_PREHASH_ParcelEnvironmentBlock)) { msg->getS32Fast(_PREHASH_ParcelEnvironmentBlock, _PREHASH_ParcelEnvironmentVersion, parcel_environment_version); @@ -1698,6 +1704,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use parcel->setParcelEnvironmentVersion(cur_parcel_environment_version); parcel->setRegionAllowEnvironmentOverride(region_allow_environment_override); + parcel->setObscureMOAP((bool)extended_flags); + parcel->unpackMessage(msg); if (parcel == parcel_mgr.mAgentParcel) diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 4abf53d1c5..8f56f6110f 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -95,8 +95,6 @@ // The server only keeps our pending agent info for 60 seconds. // We want to allow for seed cap retry, but its not useful after that 60 seconds. -// Give it 3 chances, each at 18 seconds to give ourselves a few seconds to connect anyways if we give up. -const S32 MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN = 3; // Even though we gave up on login, keep trying for caps after we are logged in: const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000; @@ -178,7 +176,6 @@ public: mCompositionp(NULL), mEventPoll(NULL), mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), - mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), mSeedCapAttempts(0), mHttpResponderID(0), mLastCameraUpdate(0), @@ -231,7 +228,6 @@ public: LLEventPoll* mEventPoll; S32 mSeedCapMaxAttempts; - S32 mSeedCapMaxAttemptsBeforeLogin; S32 mSeedCapAttempts; S32 mHttpResponderID; @@ -286,19 +282,13 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) if (url.empty()) { LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL; + regionp->setCapabilitiesError(); return; // this error condition is not recoverable. } // record that we just entered a new region newRegionEntry(*regionp); - // After a few attempts, continue login. But keep trying to get the caps: - if (impl->mSeedCapAttempts >= impl->mSeedCapMaxAttemptsBeforeLogin && - STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) - { - LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); - } - if (impl->mSeedCapAttempts > impl->mSeedCapMaxAttempts) { // *TODO: Give a user pop-up about this error? @@ -394,11 +384,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) << " region name " << regionp->getName() << LL_ENDL; regionp->setCapabilitiesReceived(true); - if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) - { - LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED); - } - break; } while (true); @@ -442,6 +427,11 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle) if (url.empty()) { LL_WARNS("AppInit", "Capabilities") << "Failed to get seed capabilities, and can not determine url!" << LL_ENDL; + if (regionp->getCapability("Seed").empty()) + { + // initial attempt failed to get this cap as well + regionp->setCapabilitiesError(); + } break; // this error condition is not recoverable. } @@ -643,7 +633,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false), + mCapabilitiesState(CAPABILITIES_STATE_INIT), mSimulatorFeaturesReceived(false), mBitsReceived(0.f), mPacketsReceived(0.f), @@ -1818,13 +1808,8 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) //update object cache if the object receives a full-update or terse update //update_type == EObjectUpdateType::OUT_TERSE_IMPROVED or EObjectUpdateType::OUT_FULL -LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type) +LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* objectp) { - if(objectp && update_type != (U32)OUT_TERSE_IMPROVED) - { - return objectp; //no need to access cache - } - LLVOCacheEntry* entry = getCacheEntry(local_id); if (!entry) { @@ -1836,11 +1821,8 @@ LLViewerObject* LLViewerRegion::updateCacheEntry(U32 local_id, LLViewerObject* o objectp = addNewObject(entry); } - //remove from cache if terse update - if(update_type == (U32)OUT_TERSE_IMPROVED) - { - killCacheEntry(entry, true); - } + //remove from cache. + killCacheEntry(entry, true); return objectp; } @@ -2300,6 +2282,11 @@ void LLViewerRegion::requestSimulatorFeatures() std::string coroname = LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro", boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, url, getHandle())); + + // requestSimulatorFeatures can be called from other coros, + // launch() acts like a suspend() + // Make sure we are still good to do + LLCoros::checkStop(); LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL; } @@ -3123,6 +3110,12 @@ void LLViewerRegion::setSeedCapability(const std::string& url) std::string coroname = LLCoros::instance().launch("LLEnvironmentRequest::requestBaseCapabilitiesCompleteCoro", boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro, getHandle())); + + // setSeedCapability can be called from other coros, + // launch() acts like a suspend() + // Make sure we are still good to do + LLCoros::checkStop(); + return; } @@ -3136,6 +3129,11 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro", boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, getHandle())); + // setSeedCapability can be called from other coros, + // launch() acts like a suspend() + // Make sure we are still good to do + LLCoros::checkStop(); + LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL; } @@ -3257,12 +3255,17 @@ bool LLViewerRegion::isCapabilityAvailable(const std::string& name) const bool LLViewerRegion::capabilitiesReceived() const { - return mCapabilitiesReceived; + return mCapabilitiesState == CAPABILITIES_STATE_RECEIVED; +} + +bool LLViewerRegion::capabilitiesError() const +{ + return mCapabilitiesState == CAPABILITIES_STATE_ERROR; } void LLViewerRegion::setCapabilitiesReceived(bool received) { - mCapabilitiesReceived = received; + mCapabilitiesState = received ? CAPABILITIES_STATE_RECEIVED : CAPABILITIES_STATE_INIT; // Tell interested parties that we've received capabilities, // so that they can safely use getCapability(). @@ -3277,6 +3280,11 @@ void LLViewerRegion::setCapabilitiesReceived(bool received) } } +void LLViewerRegion::setCapabilitiesError() +{ + mCapabilitiesState = CAPABILITIES_STATE_ERROR; +} + boost::signals2::connection LLViewerRegion::setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb) { return mCapabilitiesReceivedSignal.connect(cb); diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index fcbf56c81f..d0fa9fea01 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -268,7 +268,9 @@ public: // has region received its final (not seed) capability list? bool capabilitiesReceived() const; + bool capabilitiesError() const; void setCapabilitiesReceived(bool received); + void setCapabilitiesError(); boost::signals2::connection setCapabilitiesReceivedCallback(const caps_received_signal_t::slot_type& cb); static bool isSpecialCapabilityName(const std::string &name); @@ -352,7 +354,7 @@ public: void requestCacheMisses(); void addCacheMissFull(const U32 local_id); //update object cache if the object receives a full-update or terse update - LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp, U32 update_type); + LLViewerObject* updateCacheEntry(U32 local_id, LLViewerObject* objectp); void findOrphans(U32 parent_id); void clearCachedVisibleObjects(); void dumpCache(); @@ -527,12 +529,20 @@ private: BOOL mCacheLoaded; BOOL mCacheDirty; BOOL mAlive; // can become false if circuit disconnects - BOOL mCapabilitiesReceived; BOOL mSimulatorFeaturesReceived; BOOL mReleaseNotesRequested; BOOL mDead; //if true, this region is in the process of deleting. BOOL mPaused; //pause processing the objects in the region + typedef enum + { + CAPABILITIES_STATE_INIT = 0, + CAPABILITIES_STATE_ERROR, + CAPABILITIES_STATE_RECEIVED + } eCababilitiesState; + + eCababilitiesState mCapabilitiesState; + typedef std::map<U32, std::vector<U32> > orphan_list_t; orphan_list_t mOrphanMap; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 391cfab5c0..63d9a03aba 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -70,13 +70,6 @@ bool LLViewerShaderMgr::sSkipReload = false; LLVector4 gShinyOrigin; -//transform shaders -LLGLSLShader gTransformPositionProgram; -LLGLSLShader gTransformTexCoordProgram; -LLGLSLShader gTransformNormalProgram; -LLGLSLShader gTransformColorProgram; -LLGLSLShader gTransformTangentProgram; - //utility shaders LLGLSLShader gOcclusionProgram; LLGLSLShader gSkinnedOcclusionProgram; @@ -259,13 +252,15 @@ LLGLSLShader gDeferredSkinnedFullbrightShinyProgram; LLGLSLShader gDeferredSkinnedFullbrightProgram; LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram; LLGLSLShader gNormalMapGenProgram; +LLGLSLShader gDeferredGenBrdfLutProgram; // Deferred materials shaders LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; LLGLSLShader gDeferredPBROpaqueProgram; LLGLSLShader gDeferredSkinnedPBROpaqueProgram; -LLGLSLShader gDeferredPBRAlphaProgram[2]; // not skinned, skinned +LLGLSLShader gDeferredPBRAlphaProgram; +LLGLSLShader gDeferredSkinnedPBRAlphaProgram; //helper for making a rigged variant of a given shader bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader) @@ -374,7 +369,10 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredWLSkyProgram); mShaderList.push_back(&gDeferredWLCloudProgram); mShaderList.push_back(&gDeferredWLMoonProgram); - mShaderList.push_back(&gDeferredWLSunProgram); + mShaderList.push_back(&gDeferredWLSunProgram); + mShaderList.push_back(&gDeferredPBRAlphaProgram); + mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram); + } LLViewerShaderMgr::~LLViewerShaderMgr() @@ -465,7 +463,7 @@ void LLViewerShaderMgr::setShaders() initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); - LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater; + LLPipeline::sWaterReflections = LLPipeline::sRenderTransparentWater; LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); LLPipeline::updateRenderDeferred(); @@ -509,13 +507,6 @@ void LLViewerShaderMgr::setShaders() S32 wl_class = 1; S32 water_class = 2; S32 deferred_class = 0; - S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; - - static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - if (!use_transform_feedback) - { - transform_class = 0; - } if (useRenderDeferred) { @@ -568,7 +559,6 @@ void LLViewerShaderMgr::setShaders() mShaderLevel[SHADER_EFFECT] = effect_class; mShaderLevel[SHADER_WINDLIGHT] = wl_class; mShaderLevel[SHADER_DEFERRED] = deferred_class; - mShaderLevel[SHADER_TRANSFORM] = transform_class; std::string shader_name = loadBasicShaders(); if (shader_name.empty()) @@ -655,20 +645,6 @@ void LLViewerShaderMgr::setShaders() if (loaded) { - loaded = loadTransformShaders(); - if (loaded) - { - LL_INFOS() << "Loaded transform shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load transform shaders." << LL_ENDL; - llassert(loaded); - } - } - - if (loaded) - { // Load max avatar shaders to set the max level mShaderLevel[SHADER_AVATAR] = 3; mMaxAvatarShaderLevel = 3; @@ -812,12 +788,6 @@ void LLViewerShaderMgr::unloadShaders() gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); - gTransformPositionProgram.unload(); - gTransformTexCoordProgram.unload(); - gTransformNormalProgram.unload(); - gTransformColorProgram.unload(); - gTransformTangentProgram.unload(); - mShaderLevel[SHADER_LIGHTING] = 0; mShaderLevel[SHADER_OBJECT] = 0; mShaderLevel[SHADER_AVATAR] = 0; @@ -826,7 +796,6 @@ void LLViewerShaderMgr::unloadShaders() mShaderLevel[SHADER_INTERFACE] = 0; mShaderLevel[SHADER_EFFECT] = 0; mShaderLevel[SHADER_WINDLIGHT] = 0; - mShaderLevel[SHADER_TRANSFORM] = 0; gPipeline.mShadersLoaded = false; } @@ -1276,6 +1245,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredHighlightSpecularProgram.unload(); gNormalMapGenProgram.unload(); + gDeferredGenBrdfLutProgram.unload(); + for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i) { gDeferredMaterialProgram[i].unload(); @@ -1284,8 +1255,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBROpaqueProgram.unload(); gDeferredSkinnedPBROpaqueProgram.unload(); - gDeferredPBRAlphaProgram[0].unload(); - gDeferredPBRAlphaProgram[1].unload(); + gDeferredPBRAlphaProgram.unload(); + gDeferredSkinnedPBRAlphaProgram.unload(); return TRUE; } @@ -1622,76 +1593,70 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { - for (int rigged = 0; rigged < 2 && success; ++rigged) - { - LLGLSLShader* shader = &gDeferredPBRAlphaProgram[rigged]; - shader->mName = rigged - ? "Skinned Deferred PBR Alpha Shader" - : "Deferred PBR Alpha Shader"; - shader->mRiggedVariant = rigged - ? &gDeferredPBRAlphaProgram[1] - : nullptr; - shader->mFeatures.hasObjectSkinning = (bool)rigged; - shader->mFeatures.calculatesLighting = false; - shader->mFeatures.hasLighting = false; - shader->mFeatures.isAlphaLighting = true; - shader->mFeatures.hasSrgb = true; - shader->mFeatures.encodesNormal = true; - shader->mFeatures.calculatesAtmospherics = true; - shader->mFeatures.hasAtmospherics = true; - shader->mFeatures.hasGamma = true; - shader->mFeatures.hasTransport = true; - shader->mFeatures.hasShadows = use_sun_shadow; - shader->mFeatures.isDeferred = true; // include deferredUtils - shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; + LLGLSLShader* shader = &gDeferredPBRAlphaProgram; + shader->mName = "Deferred PBR Alpha Shader"; + + shader->mFeatures.calculatesLighting = false; + shader->mFeatures.hasLighting = false; + shader->mFeatures.isAlphaLighting = true; + shader->mFeatures.hasSrgb = true; + shader->mFeatures.encodesNormal = true; + shader->mFeatures.calculatesAtmospherics = true; + shader->mFeatures.hasAtmospherics = true; + shader->mFeatures.hasGamma = true; + shader->mFeatures.hasTransport = true; + shader->mFeatures.hasShadows = use_sun_shadow; + shader->mFeatures.isDeferred = true; // include deferredUtils + shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; + + shader->mShaderFiles.clear(); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER)); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER)); + + shader->clearPermutations(); + + U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; + shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + shader->addPermutation("HAS_NORMAL_MAP", "1"); + shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness + shader->addPermutation("HAS_EMISSIVE_MAP", "1"); + shader->addPermutation("USE_VERTEX_COLOR", "1"); - shader->mShaderFiles.clear(); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER_ARB)); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER_ARB)); - - shader->clearPermutations(); - - U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND; - shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); - shader->addPermutation("HAS_NORMAL_MAP", "1"); - shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness - shader->addPermutation("HAS_EMISSIVE_MAP", "1"); - shader->addPermutation("USE_VERTEX_COLOR", "1"); - if (use_sun_shadow) - { - shader->addPermutation("HAS_SHADOW", "1"); - } - - if (ambient_kill) - { - shader->addPermutation("AMBIENT_KILL", "1"); - } - - if (sunlight_kill) - { - shader->addPermutation("SUNLIGHT_KILL", "1"); - } + if (use_sun_shadow) + { + shader->addPermutation("HAS_SHADOW", "1"); + } - if (local_light_kill) - { - shader->addPermutation("LOCAL_LIGHT_KILL", "1"); - } + if (ambient_kill) + { + shader->addPermutation("AMBIENT_KILL", "1"); + } - if (rigged) - { - shader->addPermutation("HAS_SKIN", "1"); - } + if (sunlight_kill) + { + shader->addPermutation("SUNLIGHT_KILL", "1"); + } - shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + if (local_light_kill) + { + shader->addPermutation("LOCAL_LIGHT_KILL", "1"); + } + shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram); + if (success) + { success = shader->createShader(NULL, NULL); - llassert(success); - - // Alpha Shader Hack - // See: LLRender::syncMatrices() - shader->mFeatures.calculatesLighting = true; - shader->mFeatures.hasLighting = true; } + llassert(success); + + // Alpha Shader Hack + // See: LLRender::syncMatrices() + shader->mFeatures.calculatesLighting = true; + shader->mFeatures.hasLighting = true; + + shader->mRiggedVariant->mFeatures.calculatesLighting = true; + shader->mRiggedVariant->mFeatures.hasLighting = true; } @@ -2439,10 +2404,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER)); gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram; success = gDeferredShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2458,10 +2420,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER)); gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL); llassert(success); } @@ -2474,10 +2433,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowCubeProgram.mShaderFiles.clear(); gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER)); gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredShadowCubeProgram.createShader(NULL, NULL); llassert(success); @@ -2493,10 +2449,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations(); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } + gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram; @@ -2514,10 +2467,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations(); - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL); @@ -2532,10 +2482,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER)); gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram; success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL); @@ -2550,10 +2496,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear(); gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER)); gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL); llassert(success); @@ -2567,10 +2509,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarShadowProgram.mShaderFiles.clear(); gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2583,7 +2521,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear(); gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2596,7 +2533,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear(); gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2610,10 +2546,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAttachmentShadowProgram.mShaderFiles.clear(); gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2626,7 +2558,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAttachmentAlphaShadowProgram.mShaderFiles.clear(); gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAttachmentAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2639,7 +2570,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.clear(); gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAttachmentAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2928,6 +2858,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gNormalMapGenProgram.createShader(NULL, NULL); } + if (success && gGLManager.mHasCubeMapArray) + { + gDeferredGenBrdfLutProgram.mName = "Brdf Gen Shader"; + gDeferredGenBrdfLutProgram.mShaderFiles.clear(); + gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutV.glsl", GL_VERTEX_SHADER)); + gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutF.glsl", GL_FRAGMENT_SHADER)); + gDeferredGenBrdfLutProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL); + } + + return success; } @@ -3978,95 +3919,6 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() return success; } -BOOL LLViewerShaderMgr::loadTransformShaders() -{ - BOOL success = TRUE; - - if (mShaderLevel[SHADER_TRANSFORM] < 1) - { - gTransformPositionProgram.unload(); - gTransformTexCoordProgram.unload(); - gTransformNormalProgram.unload(); - gTransformColorProgram.unload(); - gTransformTangentProgram.unload(); - return TRUE; - } - - if (success) - { - gTransformPositionProgram.mName = "Position Transform Shader"; - gTransformPositionProgram.mShaderFiles.clear(); - gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER)); - gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "position_out", - "texture_index_out", - }; - - success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings); - } - - if (success) - { - gTransformTexCoordProgram.mName = "TexCoord Transform Shader"; - gTransformTexCoordProgram.mShaderFiles.clear(); - gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER)); - gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "texcoord_out", - }; - - success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformNormalProgram.mName = "Normal Transform Shader"; - gTransformNormalProgram.mShaderFiles.clear(); - gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER)); - gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "normal_out", - }; - - success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformColorProgram.mName = "Color Transform Shader"; - gTransformColorProgram.mShaderFiles.clear(); - gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER)); - gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "color_out", - }; - - success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformTangentProgram.mName = "Binormal Transform Shader"; - gTransformTangentProgram.mShaderFiles.clear(); - gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER)); - gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "tangent_out", - }; - - success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings); - } - - - return success; -} - std::string LLViewerShaderMgr::getShaderDirPrefix(void) { return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 38f67cd23c..a2ae984caa 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -62,7 +62,6 @@ public: BOOL loadShadersWater(); BOOL loadShadersInterface(); BOOL loadShadersWindLight(); - BOOL loadTransformShaders(); std::vector<S32> mShaderLevel; S32 mMaxAvatarShaderLevel; @@ -78,7 +77,6 @@ public: SHADER_WINDLIGHT, SHADER_WATER, SHADER_DEFERRED, - SHADER_TRANSFORM, SHADER_COUNT }; @@ -150,15 +148,6 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade extern LLVector4 gShinyOrigin; -//transform shaders -extern LLGLSLShader gTransformPositionProgram; -extern LLGLSLShader gTransformTexCoordProgram; -extern LLGLSLShader gTransformNormalProgram; -extern LLGLSLShader gTransformColorProgram; -extern LLGLSLShader gTransformTangentProgram; - - - //utility shaders extern LLGLSLShader gOcclusionProgram; extern LLGLSLShader gOcclusionCubeProgram; @@ -316,11 +305,12 @@ extern LLGLSLShader gDeferredWLMoonProgram; extern LLGLSLShader gDeferredStarProgram; extern LLGLSLShader gDeferredFullbrightShinyProgram; extern LLGLSLShader gNormalMapGenProgram; +extern LLGLSLShader gDeferredGenBrdfLutProgram; // Deferred materials shaders extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2]; extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2]; extern LLGLSLShader gDeferredPBROpaqueProgram; -extern LLGLSLShader gDeferredPBRAlphaProgram[2]; // not skinned, skinned +extern LLGLSLShader gDeferredPBRAlphaProgram; #endif diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 796ff04a41..5d936dfc90 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -488,6 +488,7 @@ void send_viewer_stats(bool include_preferences) system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value(); system["os"] = LLOSInfo::instance().getOSStringSimple(); system["cpu"] = gSysCPU.getCPUString(); + system["cpu_sse"] = gSysCPU.getSSEVersions(); system["address_size"] = ADDRESS_SIZE; system["os_bitness"] = LLOSInfo::instance().getOSBitness(); unsigned char MACAddress[MAC_ADDRESS_BYTES]; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 52294ec487..6cf9665e3e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -2060,7 +2060,7 @@ bool LLViewerFetchedTexture::updateFetch() if (!mIsFetching) { - if ((decode_priority > 0) && (mRawDiscardLevel < 0)) + if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL)) { // We finished but received no data if (getDiscardLevel() < 0) @@ -2115,7 +2115,7 @@ bool LLViewerFetchedTexture::updateFetch() desired_discard = llmin(desired_discard, getMaxDiscardLevel()); bool make_request = true; - /*if (decode_priority <= 0) + if (decode_priority <= 0) { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0"); make_request = false; @@ -2125,7 +2125,7 @@ bool LLViewerFetchedTexture::updateFetch() LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max"); make_request = false; } - else */ if (mNeedsCreateTexture || mIsMissingAsset) + else if (mNeedsCreateTexture || mIsMissingAsset) { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing"); make_request = false; @@ -2206,16 +2206,18 @@ bool LLViewerFetchedTexture::updateFetch() } // bypass texturefetch directly by pulling from LLTextureCache - bool fetch_request_created = false; - fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority, + S32 fetch_request_discard = -1; + fetch_request_discard = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority, w, h, c, desired_discard, needsAux(), mCanUseHTTP); - if (fetch_request_created) + if (fetch_request_discard >= 0) { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created"); mHasFetcher = TRUE; mIsFetching = TRUE; - mRequestedDiscardLevel = desired_discard; + // in some cases createRequest can modify discard, as an example + // bake textures are always at discard 0 + mRequestedDiscardLevel = llmin(desired_discard, fetch_request_discard); mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 511df4bd79..7445475360 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1262,152 +1262,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage /////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data) -{ - static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - - // Receive image header, copy into image object and decompresses - // if this is a one-packet image. - - LLUUID id; - - char ip_string[256]; - u32_to_ip_string(msg->getSenderIP(),ip_string); - - U32Bytes received_size ; - if (msg->getReceiveCompressedSize()) - { - received_size = (U32Bytes)msg->getReceiveCompressedSize() ; - } - else - { - received_size = (U32Bytes)msg->getReceiveSize() ; - } - add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, received_size); - add(LLStatViewer::TEXTURE_PACKETS, 1); - - U8 codec; - U16 packets; - U32 totalbytes; - msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); - msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec); - msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets); - msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes); - - S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); - if (!data_size) - { - return; - } - if (data_size < 0) - { - // msg->getSizeFast() is probably trying to tell us there - // was an error. - LL_ERRS() << "image header chunk size was negative: " - << data_size << LL_ENDL; - return; - } - - // this buffer gets saved off in the packet list - U8 *data = new U8[data_size]; - msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); - - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - if (!image) - { - delete [] data; - return; - } - if(log_texture_traffic) - { - gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ; - } - - //image->getLastPacketTimer()->reset(); - bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data); - if (!res) - { - delete[] data; - } -} - -// static -void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data) -{ - static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - - // Receives image packet, copy into image object, - // checks if all packets received, decompresses if so. - - LLUUID id; - U16 packet_num; - - char ip_string[256]; - u32_to_ip_string(msg->getSenderIP(),ip_string); - - U32Bytes received_size ; - if (msg->getReceiveCompressedSize()) - { - received_size = (U32Bytes)msg->getReceiveCompressedSize() ; - } - else - { - received_size = (U32Bytes)msg->getReceiveSize() ; - } - - add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, F64Bytes(received_size)); - add(LLStatViewer::TEXTURE_PACKETS, 1); - - //llprintline("Start decode, image header..."); - msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); - msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num); - S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); - - if (!data_size) - { - return; - } - if (data_size < 0) - { - // msg->getSizeFast() is probably trying to tell us there - // was an error. - LL_ERRS() << "image data chunk size was negative: " - << data_size << LL_ENDL; - return; - } - if (data_size > MTUBYTES) - { - LL_ERRS() << "image data chunk too large: " << data_size << " bytes" << LL_ENDL; - return; - } - U8 *data = new U8[data_size]; - msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); - - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - if (!image) - { - delete [] data; - return; - } - if(log_texture_traffic) - { - gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ; - } - - //image->getLastPacketTimer()->reset(); - bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data); - if (!res) - { - delete[] data; - } -} - - // We've been that the asset server does not contain the requested image id. // static void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data) diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 4116be6528..b921225e39 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -98,8 +98,6 @@ public: const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT, bool force_lossless = false); static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); - static void receiveImageHeader(LLMessageSystem *msg, void **user_data); - static void receiveImagePacket(LLMessageSystem *msg, void **user_data); public: LLViewerTextureList(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e9815a7872..b2728b294e 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -597,29 +597,6 @@ public: { LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); - if (gGLManager.mHasATIMemInfo) - { - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - - addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f)); - ypos += y_inc; - - if (gGLManager.mHasVertexBufferObject) - { - glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo); - addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f)); - ypos += y_inc; - } - } - else if (gGLManager.mHasNVXMemInfo) - { - S32 free_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); - addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f)); - ypos += y_inc; - } - //show streaming cost/triangle count of known prims in current region OR selection { F32 cost = 0.f; @@ -761,6 +738,12 @@ public: ypos += y_inc; addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f))); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Skins/Decompositions Memory", LLMeshRepository::sCacheBytesSkins / (1024.f*1024.f), LLMeshRepository::sCacheBytesDecomps / (1024.f*1024.f))); + ypos += y_inc; + + addText(xpos, ypos, llformat("%.3f MB Mesh Headers Memory", LLMeshRepository::sCacheBytesHeaders / (1024.f*1024.f))); ypos += y_inc; } @@ -1556,9 +1539,11 @@ void LLViewerWindow::handleFocusLost(LLWindow *window) showCursor(); getWindow()->setMouseClipping(FALSE); - // If losing focus while keys are down, reset them. + // If losing focus while keys are down, handle them as + // an 'up' to correctly release states, then reset states if (gKeyboard) { + gKeyboard->resetKeyDownAndHandle(); gKeyboard->resetKeys(); } @@ -1979,11 +1964,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL; // Initialize OpenGL Renderer - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || - !gGLManager.mHasVertexBufferObject) - { - gSavedSettings.setBOOL("RenderVBOEnable", FALSE); - } LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; gGL.init() ; @@ -1997,11 +1977,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); } - if (!gGLManager.mHasDepthClamp) - { - LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL; - } - // If we crashed while initializng GL stuff last time, disable certain features if (gSavedSettings.getBOOL("RenderInitError")) { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 30e3d77d29..77b689751a 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1,4 +1,4 @@ -/** +/** * @File llvoavatar.cpp * @brief Implementation of LLVOAvatar class which is a derivation of LLViewerObject * @@ -183,8 +183,6 @@ const F32 MAX_STANDOFF_DISTANCE_CHANGE = 32; // Should probably be 4 or 3, but didn't want to change it while change other logic - SJB const S32 SWITCH_TO_BAKED_DISCARD = 5; -const F32 FOOT_COLLIDE_FUDGE = 0.04f; - const F32 HOVER_EFFECT_MAX_SPEED = 3.f; const F32 HOVER_EFFECT_STRENGTH = 0.f; const F32 UNDERWATER_EFFECT_STRENGTH = 0.1f; @@ -585,7 +583,6 @@ private: //----------------------------------------------------------------------------- // Static Data //----------------------------------------------------------------------------- -S32 LLVOAvatar::sFreezeCounter = 0; U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited) F32 LLVOAvatar::sRenderDistance = 256.f; @@ -610,7 +607,6 @@ S32 LLVOAvatar::sNumVisibleChatBubbles = 0; BOOL LLVOAvatar::sDebugInvisible = FALSE; BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; BOOL LLVOAvatar::sShowAnimationDebug = FALSE; -BOOL LLVOAvatar::sShowFootPlane = FALSE; BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; F32 LLVOAvatar::sLODFactor = 1.f; F32 LLVOAvatar::sPhysicsLODFactor = 1.f; @@ -779,6 +775,13 @@ std::string LLVOAvatar::avString() const void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment) { + if (gDisconnected) + { + // If we disconected, these values are likely to be invalid and + // avString() might crash due to a dead sAvatarDictionary + return; + } + LL_INFOS("Avatar") << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ]" << avString() @@ -4107,8 +4110,7 @@ void LLVOAvatar::computeUpdatePeriod() && (!isSelf() || visually_muted) && !isUIAvatar() && (sLimitNonImpostors || visually_muted) - && !mNeedsAnimUpdate - && !sFreezeCounter) + && !mNeedsAnimUpdate) { const LLVector4a* ext = mDrawable->getSpatialExtents(); LLVector4a size; @@ -5081,42 +5083,6 @@ U32 LLVOAvatar::renderSkinned() return num_indices; } - // render collision normal - // *NOTE: this is disabled (there is no UI for enabling sShowFootPlane) due - // to DEV-14477. the code is left here to aid in tracking down the cause - // of the crash in the future. -brad - if (sShowFootPlane && mDrawable.notNull()) - { - LLVector3 slaved_pos = mDrawable->getPositionAgent(); - LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]); - F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW]; - LLVector3 collide_point = slaved_pos; - collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE); - - gGL.begin(LLRender::LINES); - { - F32 SQUARE_SIZE = 0.2f; - gGL.color4f(1.f, 0.f, 0.f, 1.f); - - gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - - gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - - gGL.vertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - - gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); - - gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]); - gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]); - - } - gGL.end(); - gGL.flush(); - } //-------------------------------------------------------------------- // render all geometry attached to the skeleton //-------------------------------------------------------------------- @@ -7233,6 +7199,14 @@ LLViewerJoint* LLVOAvatar::getViewerJoint(S32 idx) } //----------------------------------------------------------------------------- +// hideHair() +//----------------------------------------------------------------------------- +void LLVOAvatar::hideHair() +{ + mMeshLOD[MESH_ID_HAIR]->setVisible(FALSE, TRUE); +} + +//----------------------------------------------------------------------------- // hideSkirt() //----------------------------------------------------------------------------- void LLVOAvatar::hideSkirt() @@ -10237,23 +10211,6 @@ LLHost LLVOAvatar::getObjectHost() const } } -//static -void LLVOAvatar::updateFreezeCounter(S32 counter) -{ - if(counter) - { - sFreezeCounter = counter; - } - else if(sFreezeCounter > 0) - { - sFreezeCounter--; - } - else - { - sFreezeCounter = 0; - } -} - BOOL LLVOAvatar::updateLOD() { if (mDrawable.isNull()) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index a085d773dc..df3eebee2c 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -328,7 +328,6 @@ public: static bool sLimitNonImpostors; // use impostors for far away avatars static F32 sRenderDistance; // distance at which avatars will render. static BOOL sShowAnimationDebug; // show animation debug info - static BOOL sShowFootPlane; // show foot collision plane reported by server static BOOL sShowCollisionVolumes; // show skeletal collision volumes static BOOL sVisibleInFirstPerson; static S32 sNumLODChangesThisFrame; @@ -620,14 +619,6 @@ private: BOOL mCulled; //-------------------------------------------------------------------- - // Freeze counter - //-------------------------------------------------------------------- -public: - static void updateFreezeCounter(S32 counter = 0); -private: - static S32 sFreezeCounter; - - //-------------------------------------------------------------------- // Constants //-------------------------------------------------------------------- public: @@ -810,6 +801,7 @@ public: void parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg); void processAvatarAppearance(LLMessageSystem* mesgsys); void applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params); + void hideHair(); void hideSkirt(); void startAppearanceAnimation(); diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index f971554c9d..b0eb8d962c 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -770,8 +770,6 @@ LLVoiceChannelP2P::LLVoiceChannelP2P(const LLUUID& session_id, const std::string mReceivedCall(FALSE) { // make sure URI reflects encoded version of other user's agent id - // *NOTE: in case of Avaline call generated SIP URL will be incorrect. - // But it will be overridden in LLVoiceChannelP2P::setSessionHandle() called when agent accepts call setURI(LLVoiceClient::getInstance()->sipURIFromID(other_user_id)); } @@ -911,8 +909,6 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s else { LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL; - // In the case of an incoming AvaLine call, the generated URI will be different from the - // original one. This is because the P2P URI is based on avatar UUID but Avaline is not. // See LLVoiceClient::sessionAddedEvent() setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); } @@ -947,22 +943,5 @@ void LLVoiceChannelP2P::setState(EState state) void LLVoiceChannelP2P::addToTheRecentPeopleList() { - bool avaline_call = LLIMModel::getInstance()->findIMSession(mSessionID)->isAvalineSessionType(); - - if (avaline_call) - { - LLSD call_data; - std::string call_number = LLVoiceChannel::getSessionName(); - - call_data["avaline_call"] = true; - call_data["session_id"] = mSessionID; - call_data["call_number"] = call_number; - call_data["date"] = LLDate::now(); - - LLRecentPeople::instance().add(mOtherUserID, call_data); - } - else - { - LLRecentPeople::instance().add(mOtherUserID); - } + LLRecentPeople::instance().add(mOtherUserID); } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index e2bd1a39c7..d8b8b8749f 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -200,6 +200,7 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion() LLVoiceVersionInfo result; result.serverVersion = std::string(); result.serverType = std::string(); + result.mBuildVersion = std::string(); return result; } } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index cf527a4464..246883b611 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -95,6 +95,7 @@ struct LLVoiceVersionInfo { std::string serverType; std::string serverVersion; + std::string mBuildVersion; }; ////////////////////////////////// diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 19036a3f77..735bb4ad94 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -690,6 +690,10 @@ void LLVivoxVoiceClient::voiceControlCoro() // surviving longer than LLVivoxVoiceClient voiceControlStateMachine(state); } + catch (const LLCoros::Stop&) + { + LL_DEBUGS("LLVivoxVoiceClient") << "Received a shutdown exception" << LL_ENDL; + } catch (const LLContinueError&) { LOG_UNHANDLED_EXCEPTION("LLVivoxVoiceClient"); @@ -4572,6 +4576,23 @@ void LLVivoxVoiceClient::sessionNotificationEvent(std::string &sessionHandle, st } } +void LLVivoxVoiceClient::voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id) +{ + // We don't generally need to process this. However, one occurence is when we first connect, and so it is the + // earliest opportunity to learn what we're connected to. + if (statusCode) + { + LL_WARNS("Voice") << "VoiceServiceConnectionStateChangedEvent statusCode: " << statusCode << + "statusString: " << statusString << LL_ENDL; + return; + } + if (build_id.empty()) + { + return; + } + mVoiceVersion.mBuildVersion = build_id; +} + void LLVivoxVoiceClient::auxAudioPropertiesEvent(F32 energy) { LL_DEBUGS("VoiceEnergy") << "got energy " << energy << LL_ENDL; @@ -4758,7 +4779,7 @@ void LLVivoxVoiceClient::sessionState::VerifySessions() if ((*it).expired()) { LL_WARNS("Voice") << "Expired session found! removing" << LL_ENDL; - mSession.erase(it++); + it = mSession.erase(it); } else ++it; @@ -6815,7 +6836,7 @@ void LLVivoxVoiceClient::deleteVoiceFont(const LLUUID& id) if (list_iter->second == id) { LL_DEBUGS("VoiceFont") << "Removing " << id << " from the voice font list." << LL_ENDL; - mVoiceFontList.erase(list_iter++); + list_iter = mVoiceFontList.erase(list_iter); mVoiceFontListDirty = true; } else @@ -7554,6 +7575,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag) connectorHandle = string; else if (!stricmp("VersionID", tag)) versionID = string; + else if (!stricmp("Version", tag)) + mBuildID = string; else if (!stricmp("AccountHandle", tag)) accountHandle = string; else if (!stricmp("State", tag)) @@ -7856,7 +7879,8 @@ void LLVivoxProtocolParser::processResponse(std::string tag) // We don't need to process this, but we also shouldn't warn on it, since that confuses people. } else if (!stricmp(eventTypeCstr, "VoiceServiceConnectionStateChangedEvent")) - { // Yet another ignored event + { + LLVivoxVoiceClient::getInstance()->voiceServiceConnectionStateChangedEvent(statusCode, statusString, mBuildID); } else if (!stricmp(eventTypeCstr, "AudioDeviceHotSwapEvent")) { diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index cf30a4e86a..ebc3a62c35 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -465,6 +465,7 @@ protected: void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType); void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString); void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy); + void voiceServiceConnectionStateChangedEvent(int statusCode, std::string &statusString, std::string &build_id); void auxAudioPropertiesEvent(F32 energy); void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString); void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string ¬ificationType); @@ -969,6 +970,7 @@ protected: std::string actionString; std::string connectorHandle; std::string versionID; + std::string mBuildID; std::string accountHandle; std::string sessionHandle; std::string sessionGroupHandle; diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index b7a5a0667b..9f43fb9b82 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -531,7 +531,7 @@ void LLVOSky::initCubeMap() images.push_back(mShinyTex[side].getImageRaw()); } - if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps) { mCubeMap = new LLCubeMap(false); } @@ -576,7 +576,7 @@ void LLVOSky::restoreGL() updateDirections(psky); - if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps) { initCubeMap(); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index b2365653ba..ad1711d3fb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1121,27 +1121,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } - static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - - bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && - (!mVolumeImpl || !mVolumeImpl->isVolumeUnique()); - - if (cache_in_vram) - { //this volume might be used as source data for a transform object, put it in vram - LLVolume* volume = getVolume(); - for (S32 i = 0; i < volume->getNumFaces(); ++i) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - if (face.mVertexBuffer.notNull()) - { //already cached - break; - } - volume->genTangents(i); - LLFace::cacheFaceInVRAM(face); - } - } - - return TRUE; + return TRUE; } else if (NO_LOD == lod) { @@ -5243,6 +5223,11 @@ bool can_batch_texture(LLFace* facep) return false; } + if (facep->getTextureEntry()->getGLTFMaterial() != nullptr) + { // PBR materials break indexed texture batching + return false; + } + return true; } @@ -5539,6 +5524,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mNormalMap = vobj->getGLTFNormalMap(te); draw_info->mSpecularMap = vobj->getGLTFMetallicRoughnessMap(te); draw_info->mEmissiveMap = vobj->getGLTFEmissiveMap(te); + if (draw_info->mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) + { + draw_info->mAlphaMaskCutoff = gltf_mat->mAlphaCutoff * gltf_mat->mAlbedoColor.mV[3]; + } + else + { + draw_info->mAlphaMaskCutoff = 1.f; + } } else if (mat) { @@ -6404,16 +6397,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace U32 geometryBytes = 0; U32 buffer_usage = group->mBufferUsage; - static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - - if (use_transform_feedback && - gTransformPositionProgram.mProgramObject && //transform shaders are loaded - buffer_usage == GL_DYNAMIC_DRAW && //target buffer is in VRAM - !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights - { - buffer_usage = GL_DYNAMIC_COPY; - } - #if LL_DARWIN // HACK from Leslie: // Disable VBO usage for alpha on Mac OS X because it kills the framerate diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 2b400c5586..80e94c37f2 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -40,6 +40,7 @@ #include "httpoptions.h" #include "httpheaders.h" #include "bufferarray.h" +#include "llversioninfo.h" #include "llviewercontrol.h" // Have to include these last to avoid queue redefinition! @@ -378,6 +379,15 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML); + std::string user_agent = llformat("%s %d.%d.%d (%d)", + LLVersionInfo::instance().getChannel().c_str(), + LLVersionInfo::instance().getMajor(), + LLVersionInfo::instance().getMinor(), + LLVersionInfo::instance().getPatch(), + LLVersionInfo::instance().getBuild()); + + httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent); + ///* Setting the DNS cache timeout to -1 disables it completely. //This might help with bug #503 */ //httpOpts->setDNSCacheTimeout(-1); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d66f11d247..dd15b63fab 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -893,15 +893,6 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (!addDeferredAttachments(mRT->deferredScreen)) return false; GLuint screenFormat = GL_RGBA16; - if (gGLManager.mIsAMD) - { - screenFormat = GL_RGBA12; - } - - if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA) - { - screenFormat = GL_RGBA16F_ARB; - } if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; if (samples > 0) @@ -1065,8 +1056,7 @@ void LLPipeline::refreshCachedSettings() LLPipeline::sUseOcclusion = (!gUseWireframe && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gSavedSettings.getBOOL("UseOcclusion") - && gGLManager.mHasOcclusionQuery) ? 2 : 0; + && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0; WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders"); RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred"); @@ -1192,6 +1182,8 @@ void LLPipeline::releaseLUTBuffers() LLImageGL::deleteTextures(1, &mLightFunc); mLightFunc = 0; } + + mPbrBrdfLut.release(); } void LLPipeline::releaseShadowBuffers() @@ -1373,6 +1365,21 @@ void LLPipeline::createLUTBuffers() delete [] ls; } + + mPbrBrdfLut.allocate(512, 512, GL_RG16F, false, false); + mPbrBrdfLut.bindTarget(); + gDeferredGenBrdfLutProgram.bind(); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1, -1); + gGL.vertex2f(-1, 1); + gGL.vertex2f(1, -1); + gGL.vertex2f(1, 1); + gGL.end(); + gGL.flush(); + + gDeferredGenBrdfLutProgram.unbind(); + mPbrBrdfLut.flush(); } } @@ -2355,8 +2362,7 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep) { static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion"); - static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gGLManager.mHasOcclusionQuery; + static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion"); LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL); @@ -6381,6 +6387,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light_state->setDiffuse(light_color); light_state->setAmbient(LLColor4::black); light_state->setConstantAttenuation(0.f); + light_state->setSize(light->getLightRadius() * 1.5f); + light_state->setFalloff(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); + if (sRenderDeferred) { light_state->setLinearAttenuation(linatten); @@ -8173,6 +8182,13 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ deferred_target->bindTexture(3, channel, LLTexUnit::TFO_POINT); // frag_data[3] } + channel = shader.enableTexture(LLShaderMgr::DEFERRED_BRDF_LUT, LLTexUnit::TT_TEXTURE); + if (channel > -1) + { + mPbrBrdfLut.bindTexture(0, channel); + } + + channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); if (channel > -1) { @@ -8312,7 +8328,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_ } bindReflectionProbes(shader); - + if (gAtmosphere) { // bind precomputed textures necessary for calculating sun and sky luminance @@ -9220,6 +9236,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT); shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage()); shader.disableTexture(LLShaderMgr::DIFFUSE_MAP); @@ -9750,15 +9767,13 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLRenderPass::PASS_NORMMAP, LLRenderPass::PASS_NORMMAP_EMISSIVE, LLRenderPass::PASS_NORMSPEC, - LLRenderPass::PASS_NORMSPEC_EMISSIVE, - LLRenderPass::PASS_PBR_OPAQUE, // NOTE: Assumes PASS_PBR_OPAQUE_RIGGED is consecutive - //LLRenderPass::PASS_PBR_OPAQUE_RIGGED, + LLRenderPass::PASS_NORMSPEC_EMISSIVE }; LLGLEnable cull(GL_CULL_FACE); //enable depth clamping if available - LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); + //LLGLEnable depth_clamp(GL_DEPTH_CLAMP); if (use_shader) { @@ -9836,7 +9851,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera if (use_shader) { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); gDeferredShadowProgram.unbind(); renderGeomShadow(shadow_cam); @@ -9845,13 +9860,13 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera } else { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); renderGeomShadow(shadow_cam); } { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); LL_PROFILE_GPU_ZONE("shadow alpha"); for (int i = 0; i < 2; ++i) { @@ -9867,19 +9882,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLVertexBuffer::MAP_TEXTURE_INDEX; { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged); } { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f); renderAlphaObjects(mask, TRUE, TRUE, rigged); } { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged); LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); @@ -9888,7 +9903,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera { - LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS); + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); gDeferredTreeShadowProgram.bind(rigged); if (i == 0) { @@ -9901,6 +9916,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, no_idx_mask, true, false, rigged); renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, no_idx_mask, true, false, rigged); renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_PBR_OPAQUE, no_idx_mask, true, false, rigged); } } } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index cd7d0b88d8..5665469c1a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -682,6 +682,7 @@ public: LLRenderTarget mHighlight; LLRenderTarget mPhysicsDisplay; + LLRenderTarget mPbrBrdfLut; LLCullResult mSky; LLCullResult mReflectedObjects; diff --git a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg b/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg Binary files differdeleted file mode 100644 index 3bb7f7183c..0000000000 --- a/indra/newview/skins/default/textures/icons/avaline_default_icon.jpg +++ /dev/null diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 65faea48a0..5bf27bb64d 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -67,8 +67,6 @@ with the same filename but different name <texture name="Audio_Off" file_name="icons/Audio_Off.png" preload="false" /> <texture name="Audio_Press" file_name="icons/Audio_Press.png" preload="false" /> - <texture name="Avaline_Icon" file_name="icons/avaline_default_icon.jpg" preload="true" /> - <texture name="BackArrow_Off" file_name="icons/BackArrow_Off.png" preload="false" /> <texture name="BackButton_Off" file_name="icons/back_arrow_off.png" preload="false" scale.left="22" scale.top="12" scale.right="25" scale.bottom="12" /> diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml index 45946fd222..c8a3ad328e 100644 --- a/indra/newview/skins/default/xui/da/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml @@ -7,8 +7,8 @@ ukendt </text> <text name="detail_texture_text"> - Terræn teksturer (kræver 512x512, 24 bit .tga filer) - </text> + Terræn teksturer (kræver 1024x1024, 24 bit .tga filer) + </text> <text name="height_text_lbl"> 1 (Lav) </text> diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 5f1bf73f26..e4f99d14e9 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -443,9 +443,6 @@ Prøv venligst om lidt igen. <string name="GroupNameNone"> (ingen) </string> - <string name="AvalineCaller"> - Avaline opkalder [ORDER] - </string> <string name="AssetErrorNone"> Ingen fejl </string> diff --git a/indra/newview/skins/default/xui/de/panel_region_terrain.xml b/indra/newview/skins/default/xui/de/panel_region_terrain.xml index 7801be30e4..42ba5b5269 100644 --- a/indra/newview/skins/default/xui/de/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/de/panel_region_terrain.xml @@ -10,8 +10,8 @@ <spinner label="Obere Terraingrenze" name="terrain_raise_spin"/> <spinner label="Untere Terraingrenze" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 512x512) - </text> + Terraintexturen (erfordert 24-Bit-.tga-Dateien mit einer Größe von 1024x1024) + </text> <text name="height_text_lbl"> 1 (niedrig) </text> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 4625c48714..0120f7e5bd 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -691,9 +691,6 @@ nächsten Eigentümer angehängt werden. <string name="GroupNameNone"> (keiner) </string> - <string name="AvalineCaller"> - Avaline-Anfrufer [ORDER] - </string> <string name="AssetErrorNone"> Kein Fehler </string> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index dee5e29a3c..4678d65b85 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -1893,7 +1893,29 @@ Only large parcels can be listed in search. left="110" name="parcel_enable_voice_channel_local" width="300" /> - </panel> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + left="10" + mouse_opaque="false" + name="media" + top_pad="10" + width="100"> + Media: + </text> + <check_box + height="16" + label="Obscure MOAP" + layout="topleft" + left="110" + left_pad="0" + name="obscure_moap" + tool_tip="Media on a prim located outside the parcel should not play automatically for an agent within this parcel and vice versa." + width="300" /> + </panel> <panel border="true" follows="all" diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml index d07e3cb31b..343e72f057 100644 --- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml @@ -11,6 +11,11 @@ name="Screenshot"> Screenshot </floater.string> + <floater.string + name="chat_report_format"> +Time: [MSG_TIME] +Text: [MSG_DESCRIPTION] + </floater.string> <texture_picker allow_no_texture="true" default_image_name="None" @@ -19,7 +24,7 @@ layout="topleft" left="60" name="screenshot" - top="15" + top="20" width="220" /> <text type="string" diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index b6a2aaf31b..0cb69137e3 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -139,77 +139,28 @@ visible="false" width="87" /> - <layout_stack name="inventory_stack" - width="231" - height="276" - top="20" - left="175" - follows="all" - animate="false" - orientation="vertical"> - <layout_panel name="combo_layout" - border="false" - bevel_style="in" - auto_resize="false" - user_resize="false" - visible="false" - width="231" - height="24"> - <combo_box - follows="left|top|right" - height="23" - label="Choose Textures, Materials or LIFE!" - layout="topleft" - left="0" - name="textures_material_combo" - top="0" - width="231"> - <combo_box.item - label="Materials & Textures" - name="Materials_Textures" - value="0" /> - <combo_box.item - label="Textures" - name="Textures" - value="1" /> - <combo_box.item - label="Materials" - name="Materials" - value="2" /> - </combo_box> - </layout_panel> - <layout_panel name="inventory_layout" - border="false" - bevel_style="in" - auto_resize="true" - user_resize="false" - visible="true" - width="231" - height="252"> - <filter_editor - follows="left|top|right" - height="23" - label="Filter Textures" - layout="topleft" - left="0" - name="inventory search editor" - top="4" - width="231" /> - <asset_filtered_inv_panel - allow_multi_select="false" - bg_visible="true" - bg_alpha_color="DkGray2" - border="false" - follows="all" - height="221" - layout="topleft" - left_delta="0" - name="inventory panel" - top_pad="4" - width="231" - filter_asset_types="texture|material"/> - </layout_panel> - </layout_stack> + <filter_editor + follows="left|top|right" + height="23" + label="Filter Textures" + layout="topleft" + left="175" + name="inventory search editor" + top="20" + width="231" /> + <asset_filtered_inv_panel + allow_multi_select="false" + bg_visible="true" + bg_alpha_color="DkGray2" + border="false" + follows="all" + height="242" + layout="topleft" + left_delta="0" + name="inventory panel" + top_pad="4" + width="231" + filter_asset_types="texture|material"/> <!-- middle: local mode --> <button diff --git a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml index 05ab4d35a0..9f394a4c74 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_icon.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_icon.xml @@ -96,6 +96,13 @@ name="Pay"> <on_click function="AvatarIcon.Action" parameter="pay" /> </menu_item_call> + <menu_item_call + label="Report Abuse" + layout="topleft" + name="Report Abuse"> + <on_click function="AvatarIcon.Action" parameter="report_abuse" /> + <on_enable function="AvatarIcon.Enable" parameter="report_abuse" /> + </menu_item_call> <menu_item_check label="Block Voice" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml index ed362b36e5..59e6106a28 100644 --- a/indra/newview/skins/default/xui/en/menu_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_conversation.xml @@ -132,6 +132,13 @@ <on_click function="Avatar.DoToSelected" parameter="pay" /> <on_enable function="Avatar.EnableItem" parameter="can_pay" /> </menu_item_call> + <menu_item_call + label="Report Abuse" + layout="topleft" + name="report_abuse"> + <on_click function="Avatar.DoToSelected" parameter="report_abuse" /> + <on_enable function="Avatar.EnableItem" parameter="report_abuse" /> + </menu_item_call> <menu_item_check label="Block Voice" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml index 43287c6ec3..b38fae4404 100644 --- a/indra/newview/skins/default/xui/en/menu_im_conversation.xml +++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml @@ -79,6 +79,13 @@ </menu_item_call> <menu_item_separator layout="topleft"/> + <menu_item_call + label="Report Abuse" + layout="topleft" + name="Report Abuse"> + <on_click function="Avatar.GearDoToSelected" parameter="report_abuse" /> + <on_enable function="Avatar.EnableGearItem" parameter="report_abuse" /> + </menu_item_call> <menu_item_check label="Block Voice" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index c7c1e1d75a..46dd0ada5d 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -692,6 +692,14 @@ function="Inventory.FileUploadLocation" parameter="model" /> </menu_item_call> + <menu_item_call + label="PBR material uploads" + layout="topleft" + name="PBR uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="pbr_material" /> + </menu_item_call> </menu> <menu_item_separator layout="topleft" /> diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml index e8b6116026..5ca8be2123 100644 --- a/indra/newview/skins/default/xui/en/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml @@ -29,7 +29,14 @@ name="remove_friend"> <menu_item_call.on_click function="Url.RemoveFriend" /> - </menu_item_call> + </menu_item_call> + <menu_item_call + label="Report Abuse" + layout="topleft" + name="report_abuse"> + <menu_item_call.on_click + function="Url.ReportAbuse" /> + </menu_item_call> <menu_item_separator layout="topleft" /> <menu_item_call diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index eb4f9f16fa..eef8195580 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -422,7 +422,9 @@ </menu_item_call> <menu_item_call label="Stop animations" - name="Stop Animating My Avatar"> + name="Stop Animating My Avatar" + allow_key_repeat="true" + shortcut="alt|shift|A"> <menu_item_call.on_click function="Tools.StopAllAnimations" /> </menu_item_call> @@ -2659,6 +2661,12 @@ function="World.EnvPreset" function="Advanced.ForceErrorBadMemoryAccess" /> </menu_item_call> <menu_item_call + label="Force Bad Memory Access in Coroutine" + name="Force Bad Memory Access in Coroutine"> + <menu_item_call.on_click + function="Advanced.ForceErrorBadMemoryAccessCoro" /> + </menu_item_call> + <menu_item_call label="Force Infinite Loop" name="Force Infinite Loop"> <menu_item_call.on_click @@ -3099,8 +3107,6 @@ function="World.EnvPreset" <menu_item_check.on_click function="ToggleControl" parameter="UseOcclusion" /> - <menu_item_check.on_enable - function="Advanced.EnableObjectObjectOcclusion" /> </menu_item_check> <menu_item_separator /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index d2a35241ba..07ad2838b0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1521,7 +1521,7 @@ Delete pick <nolink>[PICK]</nolink>? <notification icon="alert.tga" name="ProfileUnpublishedClassified" - type="alert"> + type="alertmodal"> You have unpublished classifieds. They will be lost if you close the window. <tag>confirm</tag> <usetemplate @@ -1533,7 +1533,7 @@ Delete pick <nolink>[PICK]</nolink>? <notification icon="alert.tga" name="ProfileUnsavedChanges" - type="alert"> + type="alertmodal"> You have usaved changes. <tag>confirm</tag> <tag>save</tag> @@ -3945,7 +3945,7 @@ Are you sure you want to return objects owned by [USER_NAME]? Couldn't set region textures: Terrain texture [TEXTURE_NUM] has an invalid bit depth of [TEXTURE_BIT_DEPTH]. -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. <tag>fail</tag> </notification> @@ -3956,7 +3956,7 @@ Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click Couldn't set region textures: Terrain texture [TEXTURE_NUM] is too large at [TEXTURE_SIZE_X]x[TEXTURE_SIZE_Y]. -Replace texture [TEXTURE_NUM] with a 24-bit 512x512 or smaller image then click "Apply" again. +Replace texture [TEXTURE_NUM] with a 24-bit [MAX_SIZE]x[MAX_SIZE] or smaller image then click "Apply" again. </notification> <notification diff --git a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml index 67eff2b762..08ff3d4d53 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml @@ -126,6 +126,31 @@ type="string" length="1" follows="left|top" + height="12" + layout="topleft" + left="37" + name="title_pbr" + top_pad="7" + width="100"> + PBR Materials + </text> + <text + type="string" + use_ellipses="true" + follows="left|top" + height="27" + layout="topleft" + font.style="BOLD" + left="37" + name="upload_pbr" + top_pad="5" + width="370" + word_wrap="true"/> + + <text + type="string" + length="1" + follows="left|top" height="30" layout="topleft" font.style="ITALIC" diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index 8243c2715d..2aaea04a6d 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -86,7 +86,7 @@ name="detail_texture_text" top="110" width="300"> - Terrain Textures (requires 512x512, 24 bit .tga files) + Terrain Textures (requires 1024x1024, 24 bit .tga files) </text> <texture_picker follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 9bdfff41d8..30774ab18e 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -594,10 +594,7 @@ top_pad="4" tool_tip="Add Media" label="Choose..." - width="85"> - <button.commit_callback - function="BuildTool.AddMedia"/> - </button> + width="85"/> <button follows="top|left" height="18" @@ -607,10 +604,7 @@ tool_tip="Delete this media texture" top_delta="0" label="Remove" - width="85"> - <button.commit_callback - function="BuildTool.DeleteMedia"/> - </button> + width="85"/> <button follows="left|top" height="18" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 960faabcfd..9f183d137d 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -348,8 +348,6 @@ can be attached to notecards. <!-- Group name: text shown for LLUUID::null --> <string name="GroupNameNone">(none)</string> - <string name="AvalineCaller">Avaline Caller [ORDER]</string> - <!-- Asset errors. Used in llassetstorage.cpp, translation from error code to error message. --> <string name="AssetErrorNone">No error</string> <string name="AssetErrorRequestFailed">Asset request: failed</string> @@ -2343,6 +2341,14 @@ The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors. An error occurred while opening Marketplace Listings. If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com </string> + <string name="InventoryMarketplaceConnectionError"> +Marketplace Listings failed to connect. +If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com + </string> + <string name="InventoryMarketplaceConnectionErrorReason"> +Marketplace Listings failed to connect. Reason: [REASON] +If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com + </string> <string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string> <string name="InventoryMarketplaceListingsNoItemsTooltip"></string> <string name="InventoryMarketplaceListingsNoItems"> @@ -2467,6 +2473,8 @@ If you continue to receive this message, please contact Second Life support for <string name="InvFolder Meshes">Meshes</string> <string name="InvFolder Received Items">Received Items</string> <string name="InvFolder Merchant Outbox">Merchant Outbox</string> + <string name="InvFolder Settings">Settings</string> + <string name="InvFolder Materials">Materials</string> <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694--> <string name="InvFolder Friends">Friends</string> diff --git a/indra/newview/skins/default/xui/es/panel_region_terrain.xml b/indra/newview/skins/default/xui/es/panel_region_terrain.xml index cb6c03dbb5..9aba5299cb 100644 --- a/indra/newview/skins/default/xui/es/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/es/panel_region_terrain.xml @@ -12,8 +12,8 @@ del terreno" name="terrain_raise_spin"/> <spinner bottom_delta="-34" label="Límite de bajada del terreno" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Texturas del terreno (requiere archivos .tga de 512x512, 24 bits) - </text> + Texturas del terreno (requiere archivos .tga de 1024x1024, 24 bits) + </text> <text name="height_text_lbl"> 1 (bajo) </text> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 20f7f81962..5a03e65b49 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -680,9 +680,6 @@ pueden adjuntarse a las notas. <string name="GroupNameNone"> (ninguno) </string> - <string name="AvalineCaller"> - Avaline: [ORDER] - </string> <string name="AssetErrorNone"> No hay ningún error </string> diff --git a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml index 97f486d3a3..bbab00ca24 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_terrain.xml @@ -12,8 +12,8 @@ terrain" name="terrain_raise_spin"/> <spinner bottom_delta="-34" label="Limite d'abaissement du terrain" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Textures du terrain (fichiers .tga 512 x 512, 24 bit requis) - </text> + Textures du terrain (fichiers .tga 1024 x 1024, 24 bit requis) + </text> <text name="height_text_lbl"> 1 (Bas) </text> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 943d1635cd..21825c6b2f 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -692,9 +692,6 @@ peuvent être joints aux notes. <string name="GroupNameNone"> (aucun) </string> - <string name="AvalineCaller"> - Appelant Avaline [ORDER] - </string> <string name="AssetErrorNone"> Aucune erreur </string> diff --git a/indra/newview/skins/default/xui/it/panel_region_terrain.xml b/indra/newview/skins/default/xui/it/panel_region_terrain.xml index c61ac3ecce..e08c55f63b 100644 --- a/indra/newview/skins/default/xui/it/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/it/panel_region_terrain.xml @@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/> <spinner bottom_delta="-34" label="Limite di abbassamento del terreno" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Texture terreno (richiede file 512x512, 24 bit .tga) - </text> + Texture terreno (richiede file 1024x1024, 24 bit .tga) + </text> <text name="height_text_lbl"> 1 (basso) </text> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 52f5f7af18..1ebdadb930 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -685,9 +685,6 @@ possono essere allegati ai biglietti. <string name="GroupNameNone"> (nessuno) </string> - <string name="AvalineCaller"> - Chiamante Avaline [ORDER] - </string> <string name="AssetErrorNone"> Nessun errore </string> diff --git a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml index fb853c1925..c1080a7d7b 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_terrain.xml @@ -10,8 +10,8 @@ <spinner label="地形の上昇限度" name="terrain_raise_spin"/> <spinner label="地形の下降限度" name="terrain_lower_spin"/> <text name="detail_texture_text"> - 地形テクスチャ(512x512 の 24 bit .tga ファイル) - </text> + 地形テクスチャ(1024x1024 の 24 bit .tga ファイル) + </text> <text name="height_text_lbl"> 1(低) </text> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index c5bba021ac..d90772ab0a 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -691,9 +691,6 @@ support@secondlife.com にお問い合わせください。 <string name="GroupNameNone"> (なし) </string> - <string name="AvalineCaller"> - Avaline コール [ORDER] - </string> <string name="AssetErrorNone"> エラーなし </string> diff --git a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml index f086a52dcd..2d4286334f 100644 --- a/indra/newview/skins/default/xui/pl/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_terrain.xml @@ -7,7 +7,7 @@ <spinner label="Górny limit terenu" name="terrain_raise_spin" /> <spinner label="Dolny limit terenu" name="terrain_lower_spin" /> <text name="detail_texture_text"> - Tekstury terenu (512x512 / 1024x1024, 24 bitowy plik .tga) + Tekstury terenu (1024x1024, 24 bitowy plik .tga) </text> <text name="height_text_lbl"> 1 (Nisko) diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 2b182dc3cc..90d2d86c02 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -596,9 +596,6 @@ Spróbuj zalogować się ponownie za minutę. <string name="GroupNameNone"> (brak danych) </string> - <string name="AvalineCaller"> - Avaline [ORDER] - </string> <string name="AssetErrorNone"> Brak błędu </string> diff --git a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml index 74330a8946..1d312aeed9 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_terrain.xml @@ -12,8 +12,8 @@ terreno" name="terrain_raise_spin"/> <spinner bottom_delta="-34" label="Limite mais baixo do terreno" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Texturas de terreno (exige arquivos .tga 512x512, 24 bit) - </text> + Texturas de terreno (exige arquivos .tga 1024x1024, 24 bit) + </text> <text name="height_text_lbl"> 1 (Baixo) </text> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 7a425a2622..ae452d6a4d 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -47,7 +47,7 @@ Placa de vídeo: [GRAPHICS_CARD_VENDOR] Placa gráfica: [GRAPHICS_CARD] </string> <string name="AboutDriver"> - Versão do driver de vídeo Windows: [GRAPHICS_CARD_VENDOR] + Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION] </string> <string name="AboutOGL"> Versão do OpenGL: [OPENGL_VERSION] @@ -645,9 +645,6 @@ ser anexado às anotações. <string name="GroupNameNone"> (nenhum) </string> - <string name="AvalineCaller"> - Interlocutor Avaline [ORDER] - </string> <string name="AssetErrorNone"> Nenhum erro </string> diff --git a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml index af25565226..76b4f513a8 100644 --- a/indra/newview/skins/default/xui/ru/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/ru/panel_region_terrain.xml @@ -10,8 +10,8 @@ <spinner label="Верх. точка ландшафта" name="terrain_raise_spin"/> <spinner label="Ниж. точка ландшафта" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Текстуры ландшафта (требования: 512x512, 24-битные, TGA) - </text> + Текстуры ландшафта (требования: 1024x1024, 24-битные, TGA) + </text> <text name="height_text_lbl"> 1 (Низ) </text> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index c0dc32340a..61d836a2d1 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -689,9 +689,6 @@ support@secondlife.com. <string name="GroupNameNone"> (нет) </string> - <string name="AvalineCaller"> - [ORDER] абонента Avaline - </string> <string name="AssetErrorNone"> Ошибок нет </string> diff --git a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml index 3226ee008e..e25047301d 100644 --- a/indra/newview/skins/default/xui/tr/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/tr/panel_region_terrain.xml @@ -10,8 +10,8 @@ <spinner label="Yüzey Yükslt. Limiti" name="terrain_raise_spin"/> <spinner label="Yüzey Alçatma Limiti" name="terrain_lower_spin"/> <text name="detail_texture_text"> - Yüzey Dokuları (512x512, 24 bit .tga dosyalar gerektirir) - </text> + Yüzey Dokuları (1024x1024, 24 bit .tga dosyalar gerektirir) + </text> <text name="height_text_lbl"> 1 (Düşük) </text> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index d1076b8b79..e709a4c5d6 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -689,9 +689,6 @@ kartlarına eklenebilir. <string name="GroupNameNone"> (hiçbiri) </string> - <string name="AvalineCaller"> - Avaline Arayanı [ORDER] - </string> <string name="AssetErrorNone"> Hata yok </string> diff --git a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml index 85e759e445..81bce46876 100644 --- a/indra/newview/skins/default/xui/zh/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/zh/panel_region_terrain.xml @@ -10,7 +10,7 @@ <spinner label="地形提升限制" name="terrain_raise_spin"/> <spinner label="地形降低限制" name="terrain_lower_spin"/> <text name="detail_texture_text"> - 地形材質(須 512x512,24 位元 .tga 檔格式) + 地形材質(須 1024x1024,24 位元 .tga 檔格式) </text> <text name="height_text_lbl"> 1(低) diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index a4e1b21ce6..bdb16c9bf1 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -685,9 +685,6 @@ http://secondlife.com/viewer-access-faq <string name="GroupNameNone"> (無) </string> - <string name="AvalineCaller"> - Avaline 通話者 [ORDER] - </string> <string name="AssetErrorNone"> 無錯誤 </string> diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp index 8a7e6407ed..5d50d1e182 100644 --- a/indra/viewer_components/login/lllogin.cpp +++ b/indra/viewer_components/login/lllogin.cpp @@ -257,21 +257,25 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params) if (printable_params["wait_for_updater"].asBoolean()) { std::string reason_response = responses["data"]["reason"].asString(); - if (reason_response == "update") // No point waiting if not an update + // Timeout should produce the isUndefined() object passed here. + if (reason_response == "update") { - // Timeout should produce the isUndefined() object passed here. LL_INFOS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL; updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD()); - - if (updater.isUndefined()) - { - LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login" - << LL_ENDL; - } - else - { - LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL; - } + } + else + { + LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL; + updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 3, LLSD()); + } + if (updater.isUndefined()) + { + LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login" + << LL_ENDL; + } + else + { + LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL; } } |