diff options
author | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-11-11 09:57:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-11 09:57:49 +0200 |
commit | 814d6d43f0720bda2e74a0ecedb560ad8fcf10a9 (patch) | |
tree | 3db2802f0ab39f2d7b1264e2ac1d3599f1a3bd5a /indra | |
parent | eccc9057d9d9799d3d5056bdfe255bd9e5e2be6a (diff) | |
parent | 32df877cd73b5b6a3672d0159c982077a4b67a9d (diff) |
Merge pull request #3067 from secondlife/marchcat/c-develop
develop → Maint C sync
Diffstat (limited to 'indra')
144 files changed, 2318 insertions, 1849 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index fc18ffebb5..1b138eaeaa 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -35,7 +35,7 @@ add_compile_definitions(BOOST_BIND_GLOBAL_PLACEHOLDERS) # Force enable SSE2 instructions in GLM per the manual # https://github.com/g-truc/glm/blob/master/manual.md#section2_10 -add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_SSE2=1) +add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_SSE2=1 GLM_ENABLE_EXPERIMENTAL=1) # Configure crash reporting set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds") @@ -49,6 +49,11 @@ if(NON_RELEASE_CRASH_REPORTING) add_compile_definitions( LL_SEND_CRASH_REPORTS=1) endif() +set(USE_LTO OFF CACHE BOOL "Enable Link Time Optimization") +if(USE_LTO) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) +endif() + # Don't bother with a MinSizeRel or Debug builds. set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release" CACHE STRING "Supported build types." FORCE) @@ -102,7 +107,7 @@ if (WINDOWS) #ND: When using something like buildcache (https://github.com/mbitsnbites/buildcache) # to make those wrappers work /Zi must be changed to /Z7, as /Zi due to it's nature is not compatible with caching - if( ${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*") + if(${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*") add_compile_options( /Z7 ) string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 9017fc2fb4..1083d7f2c4 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -43,6 +43,7 @@ set(cmake_SOURCE_FILES Lualibs.cmake Meshoptimizer.cmake NDOF.cmake + NFDE.cmake OPENAL.cmake OpenGL.cmake OpenJPEG.cmake @@ -56,6 +57,7 @@ set(cmake_SOURCE_FILES TemplateCheck.cmake TinyEXR.cmake TinyGLTF.cmake + Tracy.cmake Tut.cmake UI.cmake UnixInstall.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index e98c77497b..bae3dc5d94 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -200,7 +200,6 @@ elseif(LINUX) libortp.so libvivoxoal.so.1 libvivoxsdk.so - libSDL2.so ) set(slvoice_files SLVoice) @@ -214,7 +213,8 @@ elseif(LINUX) set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") # *FIX - figure out what to do with duplicate libalut.so here -brad set(release_files - ) + libSDL2-2.0.so.0 + ) if( USE_AUTOBUILD_3P ) list( APPEND release_files diff --git a/indra/cmake/LLKDU.cmake b/indra/cmake/LLKDU.cmake index 668b07ffab..6d27dcc286 100644 --- a/indra/cmake/LLKDU.cmake +++ b/indra/cmake/LLKDU.cmake @@ -23,4 +23,5 @@ if (USE_KDU) ${AUTOBUILD_INSTALL_DIR}/include/kdu ${LIBS_OPEN_DIR}/llkdu ) + target_compile_definitions(ll::kdu INTERFACE KDU_X86_INTRINSICS=1 KDU_NO_THREADS=1) endif (USE_KDU) diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake index a5791f1bef..3bdca544ac 100644 --- a/indra/cmake/LLWindow.cmake +++ b/indra/cmake/LLWindow.cmake @@ -9,5 +9,5 @@ include_guard() if (LINUX) # linux uses SDL2 for window and keyboard - target_compile_definitions( ll::SDL2 INTERFACE LL_USE_SDL_KEYBOARD=1 ) + target_compile_definitions( ll::SDL2 INTERFACE LL_USE_SDL_WINDOW=1 LL_USE_SDL_KEYBOARD=1 ) endif (LINUX) diff --git a/indra/cmake/NFDE.cmake b/indra/cmake/NFDE.cmake new file mode 100644 index 0000000000..196ba575b2 --- /dev/null +++ b/indra/cmake/NFDE.cmake @@ -0,0 +1,42 @@ +# -*- cmake -*- +if(LINUX) + set(USE_NFDE ON CACHE BOOL "Use Native File Dialog wrapper library") + set(USE_NFDE_PORTAL ON CACHE BOOL "Use NFDE XDG Portals") +endif() + +include_guard() + +add_library(ll::nfde INTERFACE IMPORTED) +if(USE_NFDE) + include(Prebuilt) + use_prebuilt_binary(nfde) + + target_compile_definitions( ll::nfde INTERFACE LL_NFD=1) + + if (WINDOWS) + target_link_libraries( ll::nfde INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/nfd.lib) + elseif (DARWIN) + target_link_libraries( ll::nfde INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libnfd.a) + elseif (LINUX) + if(USE_NFDE_PORTAL) + target_link_libraries( ll::nfde INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libnfd_portal.a) + else() + target_link_libraries( ll::nfde INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libnfd_gtk.a) + endif() + endif () + + if (LINUX) + find_package(PkgConfig REQUIRED) + if(NOT USE_NFDE_PORTAL) + pkg_check_modules(GTK3 REQUIRED gtk+-3.0) + target_link_libraries(ll::nfde INTERFACE ${GTK3_LINK_LIBRARIES}) + else() + pkg_check_modules(DBUS REQUIRED dbus-1) + target_link_libraries(ll::nfde INTERFACE ${DBUS_LINK_LIBRARIES}) + endif() + endif() + + target_include_directories( ll::nfde SYSTEM INTERFACE + ${LIBS_PREBUILT_DIR}/include/nfde + ) +endif() diff --git a/indra/cmake/SDL2.cmake b/indra/cmake/SDL2.cmake index 87195ed108..a464133f3f 100644 --- a/indra/cmake/SDL2.cmake +++ b/indra/cmake/SDL2.cmake @@ -12,11 +12,8 @@ use_prebuilt_binary( SDL2 ) find_library( SDL2_LIBRARY NAMES SDL2 - PATHS "${LIBS_PREBUILT_DIR}/lib/release") -if ( "${SDL2_LIBRARY}" STREQUAL "SDL2_LIBRARY-NOTFOUND" ) - message( FATAL_ERROR "unable to find SDL2_LIBRARY" ) -endif() + PATHS "${LIBS_PREBUILT_DIR}/lib/release" REQUIRED) target_link_libraries( ll::SDL2 INTERFACE "${SDL2_LIBRARY}" ) -target_include_directories( ll::SDL2 SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include" ) +target_include_directories( ll::SDL2 SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/SDL2" ) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index 9eee9eb57f..e3f46cca9b 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -20,6 +20,7 @@ endif(LINUX) if (USE_TRACY) option(USE_TRACY_ON_DEMAND "Use on-demand Tracy profiling." ON) option(USE_TRACY_LOCAL_ONLY "Disallow remote Tracy profiling." OFF) + option(USE_TRACY_GPU "Use Tracy GPU profiling" OFF) use_system_binary(tracy) use_prebuilt_binary(tracy) @@ -36,9 +37,8 @@ if (USE_TRACY) target_compile_definitions(ll::tracy INTERFACE -DTRACY_NO_BROADCAST=1 -DTRACY_ONLY_LOCALHOST=1) endif () - # GHA runners don't always provide invariant TSC support, but always build with LL_TESTS enabled - if (DARWIN AND LL_TESTS) - target_compile_definitions(ll::tracy INTERFACE -DTRACY_TIMER_FALLBACK=1) + if (USE_TRACY_GPU AND NOT DARWIN) # Tracy OpenGL mode is incompatible with macOS/iOS + target_compile_definitions(ll::tracy INTERFACE -DLL_PROFILER_ENABLE_TRACY_OPENGL=1) endif () # See: indra/llcommon/llprofiler.h diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index 0798d4f51f..8916cb282c 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -5,14 +5,15 @@ if (INSTALL_PROPRIETARY AND NOT LINUX) else (BUGSPLAT_DB) set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system") endif (BUGSPLAT_DB) -else (INSTALL_PROPRIETARY AND NOT LINUX) +else () set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system") -endif (INSTALL_PROPRIETARY AND NOT LINUX) + set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name") +endif () include_guard() add_library( ll::bugsplat INTERFACE IMPORTED ) -if (USE_BUGSPLAT) +if (USE_BUGSPLAT AND NOT LINUX) include(Prebuilt) use_prebuilt_binary(bugsplat) if (WINDOWS) @@ -36,6 +37,7 @@ if (USE_BUGSPLAT) set_property( TARGET ll::bugsplat APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS LL_BUGSPLAT) else() + set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system" FORCE) set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name" FORCE) -endif (USE_BUGSPLAT) +endif () diff --git a/indra/integration_tests/CMakeLists.txt b/indra/integration_tests/CMakeLists.txt index ced2b3dbcf..1d5f0772b5 100644 --- a/indra/integration_tests/CMakeLists.txt +++ b/indra/integration_tests/CMakeLists.txt @@ -1,8 +1,3 @@ # -*- cmake -*- add_subdirectory(llui_libtest) -IF (LLIMAGE_LIBTEST) - MESSAGE(STATUS "Build llimage_libtest") - add_subdirectory(llimage_libtest) -ELSE (LLIMAGE_LIBTEST) - MESSAGE(STATUS "Skip llimage_libtest") -ENDIF (LLIMAGE_LIBTEST) +add_subdirectory(llimage_libtest) diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt index ee2890778b..e6ff142626 100644 --- a/indra/integration_tests/llimage_libtest/CMakeLists.txt +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -1,6 +1,7 @@ # -*- cmake -*- # Integration tests of the llimage library (JPEG2000, PNG, jpeg, etc... images reading and writing) +if (LL_TESTS) project (llimage_libtest) @@ -8,9 +9,7 @@ include(00-Common) include(LLCommon) include(LLImage) include(LLMath) -include(LLImageJ2COJ) include(LLKDU) -include(LLFileSystem) set(llimage_libtest_SOURCE_FILES llimage_libtest.cpp @@ -24,17 +23,9 @@ set(llimage_libtest_HEADER_FILES list(APPEND llimage_libtest_SOURCE_FILES ${llimage_libtest_HEADER_FILES}) add_executable(llimage_libtest - WIN32 - MACOSX_BUNDLE ${llimage_libtest_SOURCE_FILES} ) -set_target_properties(llimage_libtest - PROPERTIES - WIN32_EXECUTABLE - FALSE -) - # Libraries on which this application depends on # Sort by high-level to low-level target_link_libraries(llimage_libtest @@ -42,64 +33,9 @@ target_link_libraries(llimage_libtest llfilesystem llmath llimage - llkdu - llimagej2coj ) - -if (DARWIN) - # Path inside the app bundle where we'll need to copy libraries - set(LLIMAGE_LIBTEST_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/llimage_libtest.app/Contents/Resources - ) - # Create the Contents/Resources directory - add_custom_command( - TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - make_directory - ${LLIMAGE_LIBTEST_DESTINATION_DIR} - COMMENT "Creating Resources directory in app bundle." - ) -else (DARWIN) - set(LLIMAGE_LIBTEST_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ - ) -endif (DARWIN) - -get_target_property(BUILT_LLCOMMON llcommon LOCATION) -add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON} ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${BUILT_LLCOMMON} -) - -if (DARWIN) - # Copy the required libraries to the package app - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib - ) - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib - ) - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib - ) - foreach(expat ${EXPAT_COPY}) - add_custom_command(TARGET llimage_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} ${LLIMAGE_LIBTEST_DESTINATION_DIR} - DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} - ) - endforeach(expat) -endif (DARWIN) - -if (WINDOWS) - # Check indra/test_apps/llplugintest/CMakeLists.txt for an example of what to copy over for Windows and how -endif (WINDOWS) # Ensure people working on the viewer don't break this library -# *NOTE: This could be removed, or only built by TeamCity, if the build -# and link times become too long. add_dependencies(viewer llimage_libtest) + +endif(LL_TESTS) diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 95102094ae..c45bd6fd01 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -43,6 +43,8 @@ #include "v4coloru.h" #include "llsdserialize.h" #include "llcleanup.h" +#include "lltrace.h" +#include "llfasttimer.h" // system libraries #include <iostream> @@ -573,10 +575,10 @@ int main(int argc, char** argv) // Create the logging thread if required - if (LLFastTimer::sMetricLog) + if (LLTrace::BlockTimer::sMetricLog) { - LLFastTimer::sLogLock = new LLMutex(NULL); - fast_timer_log_thread = new LogThread(LLFastTimer::sLogName); + LLTrace::BlockTimer::setLogLock(new LLMutex()); + fast_timer_log_thread = new LogThread(LLTrace::BlockTimer::sLogName); fast_timer_log_thread->start(); } @@ -618,9 +620,9 @@ int main(int argc, char** argv) // Output perf data if requested by user if (analyze_performance) { - std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp"; - std::string current_name = LLFastTimer::sLogName + ".slp"; - std::string report_name = LLFastTimer::sLogName + "_report.csv"; + std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp"; + std::string current_name = LLTrace::BlockTimer::sLogName + ".slp"; + std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv"; std::cout << "Analyzing performance, check report in : " << report_name << std::endl; @@ -628,9 +630,9 @@ int main(int argc, char** argv) } // Stop the perf gathering system if needed - if (LLFastTimer::sMetricLog) + if (LLTrace::BlockTimer::sMetricLog) { - LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName); + LLMetricPerformanceTesterBasic::deleteTester(LLTrace::BlockTimer::sLogName); sAllDone = true; } diff --git a/indra/llcommon/linden_common.h b/indra/llcommon/linden_common.h index a918caa2e8..a41af153fe 100644 --- a/indra/llcommon/linden_common.h +++ b/indra/llcommon/linden_common.h @@ -28,12 +28,6 @@ #define LL_LINDEN_COMMON_H #include "llprofiler.h" -#if TRACY_ENABLE && !defined(LL_PROFILER_ENABLE_TRACY_OPENGL) // hooks for memory profiling -void *tracy_aligned_malloc(size_t size, size_t alignment); -void tracy_aligned_free(void *memblock); -#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y)) -#define _aligned_free(X) tracy_aligned_free((X)) -#endif // *NOTE: Please keep includes here to a minimum! // diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index f1f3958fe0..110a1c32a1 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -33,23 +33,23 @@ #include "lltracethreadrecorder.h" #include "llcleanup.h" -thread_local bool gProfilerEnabled = false; - -#if (TRACY_ENABLE) +#if LL_PROFILER_CONFIGURATION > 1 && TRACY_ENABLE // Override new/delete for tracy memory profiling void* ll_tracy_new(size_t size) { - void* ptr; - if (gProfilerEnabled) - { - //LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; - ptr = (malloc)(size); - } - else + void* ptr = (malloc)(size); + if (!ptr) { - ptr = (malloc)(size); + throw std::bad_alloc(); } + TracyAlloc(ptr, size); + return ptr; +} + +void* ll_tracy_aligned_new(size_t size, size_t alignment) +{ + void* ptr = ll_aligned_malloc_fallback(size, alignment); if (!ptr) { throw std::bad_alloc(); @@ -58,6 +58,18 @@ void* ll_tracy_new(size_t size) return ptr; } +void ll_tracy_delete(void* ptr) +{ + TracyFree(ptr); + (free)(ptr); +} + +void ll_tracy_aligned_delete(void* ptr) +{ + TracyFree(ptr); + ll_aligned_free_fallback(ptr); +} + void* operator new(size_t size) { return ll_tracy_new(size); @@ -68,18 +80,14 @@ void* operator new[](std::size_t count) return ll_tracy_new(count); } -void ll_tracy_delete(void* ptr) +void* operator new(size_t size, std::align_val_t align) { - TracyFree(ptr); - if (gProfilerEnabled) - { - //LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; - (free)(ptr); - } - else - { - (free)(ptr); - } + return ll_tracy_aligned_new(size, (size_t)align); +} + +void* operator new[](std::size_t count, std::align_val_t align) +{ + return ll_tracy_aligned_new(count, (size_t)align); } void operator delete(void *ptr) noexcept @@ -92,27 +100,17 @@ void operator delete[](void* ptr) noexcept ll_tracy_delete(ptr); } -// C-style malloc/free can't be so easily overridden, so we define tracy versions and use -// a pre-processor #define in linden_common.h to redirect to them. The parens around the native -// functions below prevents recursive substitution by the preprocessor. -// -// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at -// you, Havok), so we'll only capture the aligned version. - -void *tracy_aligned_malloc(size_t size, size_t alignment) +void operator delete(void *ptr, std::align_val_t align) noexcept { - auto ptr = ll_aligned_malloc_fallback(size, alignment); - if (ptr) TracyAlloc(ptr, size); - return ptr; + ll_tracy_aligned_delete(ptr); } -void tracy_aligned_free(void *memblock) +void operator delete[](void* ptr, std::align_val_t align) noexcept { - TracyFree(memblock); - ll_aligned_free_fallback(memblock); + ll_tracy_aligned_delete(ptr); } -#endif +#endif // TRACY_ENABLE && !LL_PROFILER_ENABLE_TRACY_OPENGL //static bool LLCommon::sAprInitialized = false; diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 5a3cbd2ef1..d188520652 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -472,7 +472,7 @@ LLBoundListener LLCoros::getStopListener(const std::string& caller, // This overload responds to viewer shutdown and to killreq(consumer). return LLEventPumps::instance().obtain("LLCoros") .listen( - LLEventPump::inventName(caller), + caller, [consumer, cleanup](const LLSD& event) { auto status{ event["status"].asString() }; diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 33db27a116..2ad0aa5eff 100644 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -168,7 +168,7 @@ postAndSuspendSetup(const std::string& callerName, // notice the pending LLApp status first. LLBoundListener stopper( LLCoros::getStopListener( - listenerName, + LLEventPump::ANONYMOUS, LLCoros::instance().getName(), [&promise, listenerName](const LLSD& status) { diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 80cfe554c4..72aec57080 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -222,7 +222,7 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r ll_aligned_free_16(ptr); } #endif - LL_PROFILE_ALLOC(ptr, size); + LL_PROFILE_ALLOC(ret, size); return ret; } @@ -231,8 +231,6 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; #if defined(LL_WINDOWS) void* ret = _aligned_malloc(size, 32); -#elif defined(LL_DARWIN) - void* ret = ll_aligned_malloc_fallback( size, 32 ); #else void *ret; if (0 != posix_memalign(&ret, 32, size)) @@ -248,8 +246,31 @@ inline void ll_aligned_free_32(void *p) LL_PROFILE_FREE(p); #if defined(LL_WINDOWS) _aligned_free(p); -#elif defined(LL_DARWIN) - ll_aligned_free_fallback( p ); +#else + free(p); // posix_memalign() is compatible with heap deallocator +#endif +} + +inline void* ll_aligned_malloc_64(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; +#if defined(LL_WINDOWS) + void* ret = _aligned_malloc(size, 64); +#else + void *ret; + if (0 != posix_memalign(&ret, 64, size)) + return nullptr; +#endif + LL_PROFILE_ALLOC(ret, size); + return ret; +} + +inline void ll_aligned_free_64(void *p) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; + LL_PROFILE_FREE(p); +#if defined(LL_WINDOWS) + _aligned_free(p); #else free(p); // posix_memalign() is compatible with heap deallocator #endif @@ -261,19 +282,23 @@ LL_FORCE_INLINE void* ll_aligned_malloc(size_t size) { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; void* ret; - if (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0) + if constexpr (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0) { ret = malloc(size); LL_PROFILE_ALLOC(ret, size); } - else if (ALIGNMENT == 16) + else if constexpr (ALIGNMENT == 16) { ret = ll_aligned_malloc_16(size); } - else if (ALIGNMENT == 32) + else if constexpr (ALIGNMENT == 32) { ret = ll_aligned_malloc_32(size); } + else if constexpr (ALIGNMENT == 64) + { + ret = ll_aligned_malloc_64(size); + } else { ret = ll_aligned_malloc_fallback(size, ALIGNMENT); @@ -285,16 +310,20 @@ template<size_t ALIGNMENT> LL_FORCE_INLINE void ll_aligned_free(void* ptr) { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY; - if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) + if constexpr (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN) { LL_PROFILE_FREE(ptr); free(ptr); } - else if (ALIGNMENT == 16) + else if constexpr (ALIGNMENT == 16) { ll_aligned_free_16(ptr); } - else if (ALIGNMENT == 32) + else if constexpr (ALIGNMENT == 32) + { + return ll_aligned_free_32(ptr); + } + else if constexpr (ALIGNMENT == 64) { return ll_aligned_free_32(ptr); } diff --git a/indra/llcommon/llprofiler.h b/indra/llcommon/llprofiler.h index f6a4d24747..6ff4341b69 100644 --- a/indra/llcommon/llprofiler.h +++ b/indra/llcommon/llprofiler.h @@ -74,23 +74,18 @@ #define LL_PROFILER_CONFIGURATION LL_PROFILER_CONFIG_FAST_TIMER #endif -extern thread_local bool gProfilerEnabled; - #if defined(LL_PROFILER_CONFIGURATION) && (LL_PROFILER_CONFIGURATION > LL_PROFILER_CONFIG_NONE) #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY || LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #include "tracy/Tracy.hpp" - // Enable OpenGL profiling - #define LL_PROFILER_ENABLE_TRACY_OPENGL 0 - // Enable RenderDoc labeling - #define LL_PROFILER_ENABLE_RENDER_DOC 0 + //#define LL_PROFILER_ENABLE_RENDER_DOC 0 #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY #define LL_PROFILER_FRAME_END FrameMark - #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true; + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); #define LL_RECORD_BLOCK_TIME(name) ZoneScoped // Want descriptive names; was: ZoneNamedN( ___tracy_scoped_zone, #name, true ); #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, name, true ); #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB @@ -133,7 +128,7 @@ extern thread_local bool gProfilerEnabled; #endif #if LL_PROFILER_CONFIGURATION == LL_PROFILER_CONFIG_TRACY_FAST_TIMER #define LL_PROFILER_FRAME_END FrameMark - #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); gProfilerEnabled = true; + #define LL_PROFILER_SET_THREAD_NAME( name ) tracy::SetThreadName( name ); #define LL_RECORD_BLOCK_TIME(name) ZoneNamedN(___tracy_scoped_zone, #name, true); const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(name)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); #define LL_PROFILE_ZONE_NAMED(name) ZoneNamedN( ___tracy_scoped_zone, #name, true ); #define LL_PROFILE_ZONE_NAMED_COLOR(name,color) ZoneNamedNC( ___tracy_scopped_zone, name, color, true ) // RGB @@ -158,23 +153,20 @@ extern thread_local bool gProfilerEnabled; #endif // LL_PROFILER #if LL_PROFILER_ENABLE_TRACY_OPENGL -#define LL_PROFILE_GPU_ZONE(name) TracyGpuZone(name) -#define LL_PROFILE_GPU_ZONEC(name,color) TracyGpuZoneC(name,color) +#define LL_PROFILE_GPU_ZONE(name) TracyGpuZone(name) +#define LL_PROFILE_GPU_ZONEC(name,color) TracyGpuZoneC(name,color) #define LL_PROFILER_GPU_COLLECT TracyGpuCollect #define LL_PROFILER_GPU_CONTEXT TracyGpuContext - -// disable memory tracking (incompatible with GPU tracing -#define LL_PROFILE_ALLOC(ptr, size) (void)(ptr); (void)(size); -#define LL_PROFILE_FREE(ptr) (void)(ptr); +#define LL_PROFILER_GPU_CONTEXT_NAMED TracyGpuContextName #else -#define LL_PROFILE_GPU_ZONE(name) (void)name; -#define LL_PROFILE_GPU_ZONEC(name,color) (void)name;(void)color; +#define LL_PROFILE_GPU_ZONE(name) (void)name; +#define LL_PROFILE_GPU_ZONEC(name,color) (void)name;(void)color; #define LL_PROFILER_GPU_COLLECT #define LL_PROFILER_GPU_CONTEXT +#define LL_PROFILER_GPU_CONTEXT_NAMED(name) (void)name; +#endif // LL_PROFILER_ENABLE_TRACY_OPENGL -#define LL_LABEL_OBJECT_GL(type, name, length, label) - -#if !LL_DARWIN && LL_PROFILER_CONFIGURATION > 1 +#if LL_PROFILER_CONFIGURATION > 1 #define LL_PROFILE_ALLOC(ptr, size) TracyAlloc(ptr, size) #define LL_PROFILE_FREE(ptr) TracyFree(ptr) #else @@ -182,9 +174,7 @@ extern thread_local bool gProfilerEnabled; #define LL_PROFILE_FREE(ptr) (void)(ptr); #endif -#endif - -#if LL_PROFILER_ENABLE_RENDER_DOC +#ifdef LL_PROFILER_ENABLE_RENDER_DOC #define LL_LABEL_OBJECT_GL(type, name, length, label) glObjectLabel(type, name, length, label) #else #define LL_LABEL_OBJECT_GL(type, name, length, label) diff --git a/indra/llcommon/lualistener.cpp b/indra/llcommon/lualistener.cpp index 94085c6798..188445a460 100644 --- a/indra/llcommon/lualistener.cpp +++ b/indra/llcommon/lualistener.cpp @@ -40,7 +40,7 @@ LuaListener::LuaListener(lua_State* L): // Listen for shutdown events. mShutdownConnection( LLCoros::getStopListener( - "LuaState", + LLEventPump::ANONYMOUS, mCoroName, [this](const LLSD&) { diff --git a/indra/llcommon/resultset.cpp b/indra/llcommon/resultset.cpp index 4d7b00eabd..8bdfbec272 100644 --- a/indra/llcommon/resultset.cpp +++ b/indra/llcommon/resultset.cpp @@ -61,20 +61,6 @@ LLSD ResultSet::getSlice(int index, int count) const return getSliceStart(index, count).first; } -/*==========================================================================*| -LLSD ResultSet::getSingle(int index) const -{ - if (0 <= index && index < getLength()) - { - return getSingle_(index); - } - else - { - return {}; - } -} -|*==========================================================================*/ - ResultSet::ResultSet(const std::string& name): mName(name) { diff --git a/indra/llcommon/resultset.h b/indra/llcommon/resultset.h index 90d52b6fe4..10d84c038f 100644 --- a/indra/llcommon/resultset.h +++ b/indra/llcommon/resultset.h @@ -17,6 +17,7 @@ #include "llsd.h" #include <iosfwd> // std::ostream #include <utility> // std::pair +#include <vector> namespace LL { @@ -41,11 +42,6 @@ struct ResultSet: public LLIntTracker<ResultSet> LLSD getSlice(int index, int count) const; // Like getSlice(), but also return adjusted start position. std::pair<LLSD, int> getSliceStart(int index, int count) const; -/*==========================================================================*| - // Retrieve LLSD corresponding to a single entry from the result set, - // with index validation. - LLSD getSingle(int index) const; -|*==========================================================================*/ /*---------------- the rest is solely for debug logging ----------------*/ std::string mName; @@ -54,6 +50,21 @@ struct ResultSet: public LLIntTracker<ResultSet> virtual ~ResultSet(); }; +// VectorResultSet is for the simple case of a ResultSet managing a single +// std::vector<T>. +template <typename T> +struct VectorResultSet: public ResultSet +{ + using super = VectorResultSet<T>; + + VectorResultSet(const std::string& name): ResultSet(name) {} + int getLength() const override { return narrow(mVector.size()); } + LLSD getSingle(int index) const override { return getSingleFrom(mVector[index]); } + virtual LLSD getSingleFrom(const T&) const = 0; + + std::vector<T> mVector; +}; + } // namespace LL std::ostream& operator<<(std::ostream& out, const LL::ResultSet& self); diff --git a/indra/llcorehttp/examples/http_texture_load.cpp b/indra/llcorehttp/examples/http_texture_load.cpp index 72e0c29a24..986e675d00 100644 --- a/indra/llcorehttp/examples/http_texture_load.cpp +++ b/indra/llcorehttp/examples/http_texture_load.cpp @@ -52,8 +52,6 @@ void init_curl(); void term_curl(); -void ssl_thread_id_callback(CRYPTO_THREADID*); -void ssl_locking_callback(int mode, int type, const char * file, int line); void usage(std::ostream & out); // Default command line settings @@ -606,63 +604,15 @@ void WorkingSet::loadAssetUuids(FILE * in) } -int ssl_mutex_count(0); -LLCoreInt::HttpMutex ** ssl_mutex_list = NULL; - void init_curl() { curl_global_init(CURL_GLOBAL_ALL); - - ssl_mutex_count = CRYPTO_num_locks(); - if (ssl_mutex_count > 0) - { - ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count]; - - for (int i(0); i < ssl_mutex_count; ++i) - { - ssl_mutex_list[i] = new LLCoreInt::HttpMutex; - } - - CRYPTO_set_locking_callback(ssl_locking_callback); - CRYPTO_THREADID_set_callback(ssl_thread_id_callback); - } } void term_curl() { - CRYPTO_set_locking_callback(NULL); - for (int i(0); i < ssl_mutex_count; ++i) - { - delete ssl_mutex_list[i]; - } - delete [] ssl_mutex_list; -} - - -void ssl_thread_id_callback(CRYPTO_THREADID* pthreadid) -{ -#if defined(WIN32) - CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread()); -#else - CRYPTO_THREADID_set_pointer(pthreadid, pthread_self()); -#endif -} - - -void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */) -{ - if (type >= 0 && type < ssl_mutex_count) - { - if (mode & CRYPTO_LOCK) - { - ssl_mutex_list[type]->lock(); - } - else - { - ssl_mutex_list[type]->unlock(); - } - } + curl_global_cleanup(); } diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp index 8a788e5a93..7ca67fd569 100755 --- a/indra/llcorehttp/tests/llcorehttp_test.cpp +++ b/indra/llcorehttp/tests/llcorehttp_test.cpp @@ -41,13 +41,7 @@ #include "test_httpstatus.hpp" #include "test_refcounted.hpp" #include "test_httpoperation.hpp" -// As of 2019-06-28, test_httprequest.hpp consistently crashes on Mac Release -// builds for reasons not yet diagnosed. -// On Linux too, this is likely to badly handling (p)thread creation and not waiting -// for threads to properly shutdown -#if LL_WINDOWS #include "test_httprequest.hpp" -#endif #include "test_httpheaders.hpp" #include "test_httprequestqueue.hpp" @@ -56,9 +50,6 @@ #include "llproxy.h" #include "llcleanup.h" -void ssl_thread_id_callback(CRYPTO_THREADID*); -void ssl_locking_callback(int mode, int type, const char * file, int line); - #if 0 // lltut provides main and runner namespace tut @@ -83,27 +74,10 @@ int main() #endif // 0 -int ssl_mutex_count(0); -LLCoreInt::HttpMutex ** ssl_mutex_list = NULL; - void init_curl() { curl_global_init(CURL_GLOBAL_ALL); - ssl_mutex_count = CRYPTO_num_locks(); - if (ssl_mutex_count > 0) - { - ssl_mutex_list = new LLCoreInt::HttpMutex * [ssl_mutex_count]; - - for (int i(0); i < ssl_mutex_count; ++i) - { - ssl_mutex_list[i] = new LLCoreInt::HttpMutex; - } - - CRYPTO_set_locking_callback(ssl_locking_callback); - CRYPTO_THREADID_set_callback(ssl_thread_id_callback); - } - LLProxy::getInstance(); } @@ -111,39 +85,6 @@ void init_curl() void term_curl() { SUBSYSTEM_CLEANUP(LLProxy); - - CRYPTO_set_locking_callback(NULL); - for (int i(0); i < ssl_mutex_count; ++i) - { - delete ssl_mutex_list[i]; - } - delete [] ssl_mutex_list; -} - - -void ssl_thread_id_callback(CRYPTO_THREADID* pthreadid) -{ -#if defined(WIN32) - CRYPTO_THREADID_set_pointer(pthreadid, GetCurrentThread()); -#else - CRYPTO_THREADID_set_pointer(pthreadid, pthread_self()); -#endif -} - - -void ssl_locking_callback(int mode, int type, const char * /* file */, int /* line */) -{ - if (type >= 0 && type < ssl_mutex_count) - { - if (mode & CRYPTO_LOCK) - { - ssl_mutex_list[type]->lock(); - } - else - { - ssl_mutex_list[type]->unlock(); - } - } } diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index aed906bb8f..347fe04c74 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -454,6 +454,10 @@ void HttpRequestTestObjectType::test<4>() template <> template <> void HttpRequestTestObjectType::test<5>() { +#ifndef LL_WINDOWS + skip("Skip due to issues with testing thread cancellation"); +#endif + ScopedCurlInit ready; set_test_name("HttpRequest Spin (soft) + NoOp + hard termination"); @@ -517,6 +521,9 @@ void HttpRequestTestObjectType::test<5>() template <> template <> void HttpRequestTestObjectType::test<6>() { +#ifndef LL_WINDOWS + skip("Skip due to issues with testing thread cancellation"); +#endif ScopedCurlInit ready; set_test_name("HttpRequest Spin + NoOp + hard termination"); @@ -2737,13 +2744,6 @@ void HttpRequestTestObjectType::test<22>() set_test_name("BUG-2295"); -#if LL_WINDOWS && ADDRESS_SIZE == 64 - // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it - if (getenv("TEAMCITY_PROJECT_NAME")) - { - skip("BUG-2295 - partial load on W64 causes freeze"); - } -#endif // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -2779,7 +2779,7 @@ void HttpRequestTestObjectType::test<22>() for (int i(0); i < test_count; ++i) { char buffer[128]; - sprintf(buffer, "/bug2295/%d/", i); + snprintf(buffer, sizeof(buffer), "/bug2295/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, url_base + buffer, 0, @@ -2810,7 +2810,7 @@ void HttpRequestTestObjectType::test<22>() for (int i(0); i < test2_count; ++i) { char buffer[128]; - sprintf(buffer, "/bug2295/00000012/%d/", i); + snprintf(buffer, sizeof(buffer), "/bug2295/00000012/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, url_base + buffer, 0, @@ -2841,7 +2841,7 @@ void HttpRequestTestObjectType::test<22>() for (int i(0); i < test3_count; ++i) { char buffer[128]; - sprintf(buffer, "/bug2295/inv_cont_range/%d/", i); + snprintf(buffer, sizeof(buffer), "/bug2295/inv_cont_range/%d/", i); HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID, url_base + buffer, 0, @@ -2917,14 +2917,6 @@ void HttpRequestTestObjectType::test<23>() set_test_name("HttpRequest GET 503s with 'Retry-After'"); -#if LL_WINDOWS && ADDRESS_SIZE == 64 - // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it - if (getenv("TEAMCITY_PROJECT_NAME")) - { - skip("llcorehttp 503-with-retry test hangs on Windows 64"); - } -#endif - // This tests mainly that the code doesn't fall over if // various well- and mis-formed Retry-After headers are // sent along with the response. Direct inspection of diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py index b2805fda11..38688a3da6 100755 --- a/indra/llcorehttp/tests/test_llcorehttp_peer.py +++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """\ -@file test_llsdmessage_peer.py +@file test_llcorehttp_peer.py @author Nat Goodspeed @date 2008-10-09 @brief This script asynchronously runs the executable (with args) specified on diff --git a/indra/llcorehttp/tests/test_refcounted.hpp b/indra/llcorehttp/tests/test_refcounted.hpp index c0c8e78413..eb23a25545 100644 --- a/indra/llcorehttp/tests/test_refcounted.hpp +++ b/indra/llcorehttp/tests/test_refcounted.hpp @@ -28,8 +28,6 @@ #include "_refcounted.h" -// disable all of this because it's hanging win64 builds? -#if ! (LL_WINDOWS && ADDRESS_SIZE == 64) using namespace LLCoreInt; namespace tut @@ -122,5 +120,4 @@ namespace tut ensure(rc->getRefCount() == RefCounted::NOT_REF_COUNTED); } } -#endif // disabling on Win64 #endif // TEST_LLCOREINT_REF_COUNTED_H_ diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index 7cd9f5eb24..230803a630 100644 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -42,10 +42,7 @@ if (USE_KDU) target_include_directories( llkdu INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Add tests - # ND: llkdu tests are very strange as they include stubs for KDU classes/methods - # if not having access to the right KDU version this test will fail to compile, incidentally I do not - # have access to a matching version of KDU and thus cannot get this tests to compile - if (LL_TESTS_KDU) + if (LL_TESTS) include(LLAddBuildTest) include(Tut) SET(llkdu_TEST_SOURCE_FILES @@ -62,6 +59,6 @@ if (USE_KDU) set_property( SOURCE ${llkdu_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_INCLUDE_DIRS ${llimage_include_dir}) LL_ADD_PROJECT_UNIT_TESTS(llkdu "${llkdu_TEST_SOURCE_FILES}") - endif (LL_TESTS_KDU) + endif (LL_TESTS) endif (USE_KDU) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index bf7cfbe071..8e2bd5b2d9 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -163,6 +163,7 @@ private: S32 mNumComponents; bool mUseYCC; kdu_dims mDims; + kdu_push_pull_params mParams; kdu_sample_allocator mAllocator; kdu_tile_comp mComps[4]; kdu_line_buf mLines[4]; @@ -255,7 +256,7 @@ LLImageJ2CKDU::LLImageJ2CKDU() : LLImageJ2CImpl(), mCodeStreamp(), mTPosp(), mTileIndicesp(), - mRawImagep(NULL), + mRawImagep(nullptr), mDecodeState(), mBlocksSize(-1), mPrecinctsSize(-1), @@ -292,17 +293,17 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod // two U32s and a pointer, so it's not as if it would be a huge overhead // to allocate a new one every time. // Also -- why is base.getData() tested specifically here? If that returns - // NULL, shouldn't we bail out of the whole method? + // nullptr, shouldn't we bail out of the whole method? if (!mInputp && base.getData()) { // The compressed data has been loaded // Setup the source for the codestream - mInputp.reset(new LLKDUMemSource(base.getData(), data_size)); + mInputp = std::make_unique<LLKDUMemSource>(base.getData(), data_size); } if (mInputp) { - // This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset(). + // This is LLKDUMemSource::reset(), not std::unique_ptr::reset(). mInputp->reset(); } @@ -312,7 +313,7 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod // *TODO: This seems to be wrong. The base class should have no idea of // how j2c compression works so no good way of computing what's the byte // range to be used. - mCodeStreamp->set_max_bytes(max_bytes,true); + mCodeStreamp->set_max_bytes(max_bytes); // If you want to flip or rotate the image for some reason, change // the resolution, or identify a restricted region of interest, this is @@ -446,8 +447,8 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco mCodeStreamp->change_appearance(false, true, false); // Apply loading discard level and cropping if required - kdu_dims* region_kdu = NULL; - if (region != NULL) + kdu_dims* region_kdu = nullptr; + if (region != nullptr) { region_kdu = new kdu_dims; region_kdu->pos.x = region[0]; @@ -464,7 +465,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco if (region_kdu) { delete region_kdu; - region_kdu = NULL; + region_kdu = nullptr; } // Resize raw_image according to the image to be decoded @@ -475,12 +476,12 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco if (!mTileIndicesp) { - mTileIndicesp.reset(new kdu_dims); + mTileIndicesp = std::make_unique<kdu_dims>(); } mCodeStreamp->get_valid_tiles(*mTileIndicesp); if (!mTPosp) { - mTPosp.reset(new kdu_coords); + mTPosp = std::make_unique<kdu_coords>(); mTPosp->y = 0; mTPosp->x = 0; } @@ -490,7 +491,7 @@ bool LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco base.setLastError(msg.what()); return false; } - catch (kdu_exception kdu_value) + catch (const kdu_exception& kdu_value) { // KDU internally throws kdu_exception. It's possible that such an // exception might leak out into our code. Catch kdu_exception @@ -581,8 +582,7 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco kdu_coords offset = tile_dims.pos - dims.pos; int row_gap = channels*dims.size.x; // inter-row separation kdu_byte *buf = buffer + offset.y*row_gap + offset.x*channels; - mDecodeState.reset(new LLKDUDecodeState(tile, buf, row_gap, - mCodeStreamp.get())); + mDecodeState = std::make_unique<LLKDUDecodeState>(tile, buf, row_gap, mCodeStreamp.get()); } // Do the actual processing F32 remaining_time = limit_time ? decode_time - decode_timer.getElapsedTimeF32().value() : 0.0f; @@ -607,7 +607,7 @@ bool LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco cleanupCodeStream(); return true; // done } - catch (kdu_exception kdu_value) + catch (const kdu_exception& kdu_value) { // KDU internally throws kdu_exception. It's possible that such an // exception might leak out into our code. Catch kdu_exception @@ -810,7 +810,7 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co base.setLastError(msg.what()); return false; } - catch (kdu_exception kdu_value) + catch (const kdu_exception& kdu_value) { // KDU internally throws kdu_exception. It's possible that such an // exception might leak out into our code. Catch kdu_exception @@ -844,7 +844,7 @@ bool LLImageJ2CKDU::getMetadata(LLImageJ2C &base) base.setLastError(msg.what()); return false; } - catch (kdu_exception kdu_value) + catch (const kdu_exception& kdu_value) { // KDU internally throws kdu_exception. It's possible that such an // exception might leak out into our code. Catch kdu_exception @@ -976,8 +976,8 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) //std::cout << "Parsing discard level = " << discard_level << std::endl; // Create the input codestream object. setupCodeStream(base, true, MODE_FAST); - mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, NULL); - mCodeStreamp->set_max_bytes(KDU_LONG_MAX,true); + mCodeStreamp->apply_input_restrictions(0, 4, discard_level, 0, nullptr); + mCodeStreamp->set_max_bytes(KDU_LONG_MAX,false); siz_params *siz_in = mCodeStreamp->access_siz(); // Create the output codestream object. @@ -1073,8 +1073,10 @@ void LLImageJ2CKDU::findDiscardLevelsBoundaries(LLImageJ2C &base) void set_default_colour_weights(kdu_params *siz) { + kdu_params *enc = siz->access_cluster(ENC_params); + assert(enc != nullptr); kdu_params *cod = siz->access_cluster(COD_params); - assert(cod != NULL); + assert(cod != nullptr); bool can_use_ycc = true; bool rev0 = false; @@ -1111,7 +1113,7 @@ void set_default_colour_weights(kdu_params *siz) return; } float weight; - if (cod->get(Clev_weights,0,0,weight) || cod->get(Cband_weights,0,0,weight)) + if (enc->get(Clev_weights,0,0,weight) || enc->get(Cband_weights,0,0,weight)) { // Weights already specified explicitly -> nothing to do return; @@ -1120,17 +1122,16 @@ void set_default_colour_weights(kdu_params *siz) // These example weights are adapted from numbers generated by Marcus Nadenau // at EPFL, for a viewing distance of 15 cm and a display resolution of // 300 DPI. - - cod->parse_string("Cband_weights:C0=" + enc->parse_string("Cband_weights:C0=" "{0.0901},{0.2758},{0.2758}," "{0.7018},{0.8378},{0.8378},{1}"); - cod->parse_string("Cband_weights:C1=" + enc->parse_string("Cband_weights:C1=" "{0.0263},{0.0863},{0.0863}," "{0.1362},{0.2564},{0.2564}," "{0.3346},{0.4691},{0.4691}," "{0.5444},{0.6523},{0.6523}," "{0.7078},{0.7797},{0.7797},{1}"); - cod->parse_string("Cband_weights:C2=" + enc->parse_string("Cband_weights:C2=" "{0.0773},{0.1835},{0.1835}," "{0.2598},{0.4130},{0.4130}," "{0.5040},{0.6464},{0.6464}," @@ -1149,7 +1150,7 @@ byte buffer, spacing successive output samples apart by `gap' bytes all necessary level shifting, type conversion, rounding and truncation. */ { int width = src.get_width(); - if (src.get_buf32() != NULL) + if (src.get_buf32() != nullptr) { // Decompressed samples have a 32-bit representation (integer or float) assert(precision >= 8); // Else would have used 16 bit representation kdu_sample32 *sp = src.get_buf32(); @@ -1312,11 +1313,11 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap, mLines[c].pre_create(&mAllocator,mDims.size.x,mReversible[c],use_shorts,0,0); if (res.which() == 0) // No DWT levels used { - mEngines[c] = kdu_decoder(res.access_subband(LL_BAND),&mAllocator,use_shorts); + mEngines[c] = kdu_decoder(res.access_subband(LL_BAND), &mAllocator, mParams, use_shorts); } else { - mEngines[c] = kdu_synthesis(res,&mAllocator,use_shorts); + mEngines[c] = kdu_synthesis(res, &mAllocator, mParams, use_shorts); } } mAllocator.finalize(*codestreamp); // Actually creates buffering resources @@ -1394,7 +1395,7 @@ kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_cod this->codestream = codestream; codestream.get_valid_tiles(valid_tile_indices); tile_idx = valid_tile_indices.pos; - tile = codestream.open_tile(tile_idx,NULL); + tile = codestream.open_tile(tile_idx, nullptr); // Set up the individual components num_components = codestream.get_num_components(true); @@ -1403,7 +1404,7 @@ kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_cod kdc_component_flow_control *comp = components; for (n = 0; n < num_components; n++, comp++) { - comp->line = NULL; + comp->line = nullptr; comp->reader = img_in; kdu_coords subsampling; codestream.get_subsampling(n,subsampling,true); @@ -1420,12 +1421,12 @@ kdc_flow_control::kdc_flow_control (kdu_supp::kdu_image_in_base *img_in, kdu_cod assert(num_components >= 0); tile.set_components_of_interest(num_components); - max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false); + max_buffer_memory = engine.create(codestream, tile, false, nullptr, false, 1, nullptr, nullptr,false); } kdc_flow_control::~kdc_flow_control() { - if (components != NULL) + if (components != nullptr) { delete[] components; } @@ -1452,8 +1453,8 @@ bool kdc_flow_control::advance_components() if (comp->ratio_counter < 0) { found_line = true; - comp->line = engine.exchange_line(n,NULL,NULL); - assert(comp->line != NULL); + comp->line = engine.exchange_line(n,nullptr,nullptr); + assert(comp->line != nullptr); if (comp->line->get_width()) { comp->reader->get(n,*(comp->line),0); @@ -1480,9 +1481,9 @@ void kdc_flow_control::process_components() assert(comp->ratio_counter >= 0); assert(comp->remaining_lines > 0); comp->remaining_lines--; - assert(comp->line != NULL); - engine.exchange_line(n,comp->line,NULL); - comp->line = NULL; + assert(comp->line != nullptr); + engine.exchange_line(n,comp->line,nullptr); + comp->line = nullptr; } } } diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 8037c81868..8481201cbc 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -32,7 +32,6 @@ // // KDU core header files // -#define KDU_NO_THREADS #include "kdu_elementary.h" #include "kdu_messaging.h" #include "kdu_params.h" @@ -41,7 +40,6 @@ #include "include_kdu_xxxx.h" #include "kdu_sample_processing.h" -#include <boost/scoped_ptr.hpp> #include <boost/noncopyable.hpp> class LLKDUDecodeState; diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index 177a8ea976..0ad67a3f92 100644 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -28,8 +28,6 @@ #define LL_LLKDUMEM_H // Support classes for reading and writing from memory buffers in KDU -#define KDU_NO_THREADS - #define kdu_xxxx "kdu_image.h" #include "include_kdu_xxxx.h" @@ -54,9 +52,7 @@ public: mCurPos = 0; } - ~LLKDUMemSource() - { - } + ~LLKDUMemSource() = default; int read(kdu_core::kdu_byte *buf, int num_bytes) { @@ -94,9 +90,7 @@ public: mOutputSize = &output_size; } - ~LLKDUMemTarget() - { - } + ~LLKDUMemTarget() = default; bool write(const kdu_core::kdu_byte *buf, int num_bytes) { diff --git a/indra/llkdu/tests/llimagej2ckdu_test.cpp b/indra/llkdu/tests/llimagej2ckdu_test.cpp index db81d60d9e..36b79047b6 100644 --- a/indra/llkdu/tests/llimagej2ckdu_test.cpp +++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp @@ -139,18 +139,19 @@ int kdu_tile_comp::get_bit_depth(bool ) { return 8; } bool kdu_tile_comp::get_reversible() { return false; } int kdu_tile_comp::get_num_resolutions() { return 1; } kdu_subband kdu_resolution::access_subband(int ) { kdu_subband a; return a; } -void kdu_resolution::get_dims(kdu_dims& ) { } -int kdu_resolution::which() { return 0; } -int kdu_resolution::get_valid_band_indices(int &) { return 1; } -kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, bool, float, kdu_thread_env*, kdu_thread_queue*) { } +void kdu_resolution::get_dims(kdu_dims& ) const { } +int kdu_resolution::which() const { return 0; } +int kdu_resolution::get_valid_band_indices(int &) const { return 1; } +kdu_synthesis::kdu_synthesis(kdu_resolution, kdu_sample_allocator*, kdu_push_pull_params&, bool, float, kdu_thread_env*, kdu_thread_queue*) { } //kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) { } -kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool, kd_core_local::kd_coremem*) {} +kdu_params::kdu_params(const char*, bool, bool, bool, bool, bool) {} kdu_params::~kdu_params() { } +void kdu_params::destroy() { } void kdu_params::set(const char* , int , int , bool ) { } void kdu_params::set(const char* , int , int , int ) { } void kdu_params::finalize_all(bool ) { } void kdu_params::finalize_all(int, bool ) { } -void kdu_params::copy_from(kdu_params*, int, int, int, int, int, bool, bool, bool) { } +void kdu_params::copy_from(kdu_params*, int, int, int, int, int, bool, bool, bool, bool) { } bool kdu_params::parse_string(const char*) { return false; } bool kdu_params::get(const char*, int, int, bool&, bool, bool, bool) { return false; } bool kdu_params::get(const char*, int, int, float&, bool, bool, bool) { return false; } @@ -159,13 +160,13 @@ kdu_params* kdu_params::access_relation(int, int, int, bool) { return NULL; } kdu_params* kdu_params::access_cluster(const char*) { return NULL; } void kdu_codestream::set_fast() { } void kdu_codestream::set_fussy() { } -void kdu_codestream::get_dims(int, kdu_dims&, bool ) { } +void kdu_codestream::get_dims(int, kdu_dims&, bool ) const { } int kdu_codestream::get_min_dwt_levels() { return 5; } int kdu_codestream::get_max_tile_layers() { return 1; } void kdu_codestream::change_appearance(bool, bool, bool, kdu_thread_env *) {} void kdu_codestream::get_tile_dims(kdu_coords, int, kdu_dims&, bool ) { } void kdu_codestream::destroy() { } -void kdu_codestream::collect_timing_stats(int ) { } +void kdu_codestream::collect_timing_stats(int ) const { } void kdu_codestream::set_max_bytes(kdu_long, bool, bool ) { } void kdu_codestream::get_valid_tiles(kdu_dims& ) { } void kdu_codestream::create( @@ -182,19 +183,21 @@ void kdu_codestream::get_subsampling(int , kdu_coords&, bool ) { } void kdu_codestream::flush(kdu_long *, int, kdu_uint16 *, bool, bool, double, kdu_thread_env*, int) { } void kdu_codestream::set_resilient(bool ) { } int kdu_codestream::get_num_components(bool ) { return 0; } -kdu_long kdu_codestream::get_total_bytes(bool ) { return 0; } +kdu_long kdu_codestream::get_total_bytes(bool ) const { return 0; } kdu_long kdu_codestream::get_compressed_data_memory(bool ) const {return 0; } void kdu_codestream::share_buffering(kdu_codestream ) { } -int kdu_codestream::get_num_tparts() { return 0; } +int kdu_codestream::get_num_tparts() const { return 0; } int kdu_codestream::trans_out(kdu_long, kdu_long*, int, bool, kdu_thread_env* ) { return 0; } bool kdu_codestream::ready_for_flush(kdu_thread_env*) { return false; } siz_params* kdu_codestream::access_siz() { return NULL; } kdu_tile kdu_codestream::open_tile(kdu_coords , kdu_thread_env* ) { kdu_tile a; return a; } kdu_codestream_comment kdu_codestream::add_comment(kdu_thread_env*) { kdu_codestream_comment a; return a; } +kdu_codestream_comment kdu_codestream::get_comment(kdu_codestream_comment) { kdu_codestream_comment a; return a; }; void kdu_subband::close_block(kdu_block*, kdu_thread_env*) { } void kdu_subband::get_valid_blocks(kdu_dims &indices) const { } kdu_block * kdu_subband::open_block(kdu_coords, int *, kdu_thread_env *, int, bool) { return NULL; } bool kdu_codestream_comment::put_text(const char*) { return false; } +const char *kdu_codestream_comment::get_text() { return nullptr; }; void kdu_customize_warnings(kdu_message*) { } void kdu_customize_errors(kdu_message*) { } kdu_long kdu_multi_analysis::create( @@ -209,16 +212,18 @@ kdu_long kdu_multi_analysis::create( const kdu_push_pull_params*, kdu_membroker*) { return kdu_long(0); } void kdu_multi_analysis::destroy(kdu_thread_env *) {} +siz_params::siz_params() : kdu_params(NULL, false, false, false, false, false) { } siz_params::siz_params(kd_core_local::kd_coremem*) : kdu_params(NULL, false, false, false, false, false) { } siz_params::~siz_params() {} void siz_params::finalize(bool ) { } void siz_params::copy_with_xforms(kdu_params*, int, int, bool, bool, bool) { } -int siz_params::write_marker_segment(kdu_output*, kdu_params*, int) { return 0; } +int siz_params::write_marker_segment(kdu_output*, kdu_params*, int, int&) { return 0; } bool siz_params::check_marker_segment(kdu_uint16, int, kdu_byte a[], int&) { return false; } -bool siz_params::read_marker_segment(kdu_uint16, int, kdu_byte a[], int) { return false; } +int siz_params::read_marker_segment(kdu_uint16 code, int num_bytes, kdu_byte bytes[], int tpart_idx) { return false; } kdu_decoder::kdu_decoder( kdu_subband subband, kdu_sample_allocator*, + kdu_push_pull_params&, bool, float, int, kdu_thread_env*, kdu_thread_queue*, diff --git a/indra/llmath/llmatrix3a.cpp b/indra/llmath/llmatrix3a.cpp index 48a72e71e1..c0b00201cf 100644 --- a/indra/llmath/llmatrix3a.cpp +++ b/indra/llmath/llmatrix3a.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmath.h" static LL_ALIGN_16(const F32 M_IDENT_3A[12]) = diff --git a/indra/llmath/llmatrix4a.cpp b/indra/llmath/llmatrix4a.cpp index 00e30a248b..bfb4c2b07a 100644 --- a/indra/llmath/llmatrix4a.cpp +++ b/indra/llmath/llmatrix4a.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmath.h" #include "llmatrix4a.h" diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 23dbddd78e..2f59f685d5 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmath.h" #include "llrigginginfo.h" diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index 0ac91366b6..b81d50f0f9 100644 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmemory.h" #include "llmath.h" #include "llquantize.h" diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index 71288daa89..141317ee8d 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llvolumeoctree.h" #include "llvector4a.h" diff --git a/indra/llmath/v3colorutil.h b/indra/llmath/v3colorutil.h index 1378d46450..4dc3100443 100644 --- a/indra/llmath/v3colorutil.h +++ b/indra/llmath/v3colorutil.h @@ -28,6 +28,7 @@ #define LL_V3COLORUTIL_H #include "v3color.h" +#include "v4color.h" inline LLColor3 componentDiv(const LLColor3& left, const LLColor3& right) { diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp index d4cf95c1e3..b626637862 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -331,7 +331,7 @@ bool LLPartSysData::isNullPS(const S32 block_num) S32 size; // Check size of block - size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock"); + size = gMessageSystem->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_PSBlock); if (!size) { @@ -344,7 +344,7 @@ bool LLPartSysData::isNullPS(const S32 block_num) return true; } - gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); + gMessageSystem->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_PSBlock, ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); LLDataPackerBinaryBuffer dp(ps_data_block, size); if (size > PS_LEGACY_DATA_BLOCK_SIZE) @@ -373,7 +373,7 @@ bool LLPartSysData::unpackBlock(const S32 block_num) U8 ps_data_block[PS_MAX_DATA_BLOCK_SIZE]; // Check size of block - S32 size = gMessageSystem->getSize("ObjectData", block_num, "PSBlock"); + S32 size = gMessageSystem->getSizeFast(_PREHASH_ObjectData, block_num, _PREHASH_PSBlock); if (size > PS_MAX_DATA_BLOCK_SIZE) { @@ -382,7 +382,7 @@ bool LLPartSysData::unpackBlock(const S32 block_num) } // Get from message - gMessageSystem->getBinaryData("ObjectData", "PSBlock", ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); + gMessageSystem->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_PSBlock, ps_data_block, size, block_num, PS_MAX_DATA_BLOCK_SIZE); LLDataPackerBinaryBuffer dp(ps_data_block, size); diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index b838e05560..a79774e900 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -400,9 +400,14 @@ void LLPluginProcessParent::idle(void) apr_sockaddr_t* addr = NULL; mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); mBoundPort = 0; + if (!mListenSocket) + { + killSockets(); + errorState(); + break; + } // This code is based on parts of LLSocket::create() in lliosocket.cpp. - status = apr_sockaddr_info_get( &addr, "127.0.0.1", diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp index 963aab7121..5bd1ca5eed 100644 --- a/indra/llrender/llfontvertexbuffer.cpp +++ b/indra/llrender/llfontvertexbuffer.cpp @@ -144,6 +144,8 @@ S32 LLFontVertexBuffer::render( || mLastShadow != shadow // ex: buttons change shadow state || mLastScaleX != LLFontGL::sScaleX || mLastScaleY != LLFontGL::sScaleY + || mLastVertDPI != LLFontGL::sVertDPI + || mLastHorizDPI != LLFontGL::sHorizDPI || mLastOrigin != LLFontGL::sCurOrigin) { genBuffers(fontp, text, begin_offset, x, y, color, halign, valign, @@ -196,6 +198,8 @@ void LLFontVertexBuffer::genBuffers( mLastScaleX = LLFontGL::sScaleX; mLastScaleY = LLFontGL::sScaleY; + mLastVertDPI = LLFontGL::sVertDPI; + mLastHorizDPI = LLFontGL::sHorizDPI; mLastOrigin = LLFontGL::sCurOrigin; if (right_x) diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h index 59cb536b74..af195dfff9 100644 --- a/indra/llrender/llfontvertexbuffer.h +++ b/indra/llrender/llfontvertexbuffer.h @@ -115,6 +115,8 @@ private: // LLFontGL's statics F32 mLastScaleX = 1.f; F32 mLastScaleY = 1.f; + F32 mLastVertDPI = 0.f; + F32 mLastHorizDPI = 0.f; LLCoordGL mLastOrigin; static bool sEnableBufferCollection; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 9209cdcb51..7bc9124ac1 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -2750,7 +2750,7 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d) if(cplane[2] < 0) cplane *= -1; - glm::mat4 suffix; + glm::mat4 suffix = glm::identity<glm::mat4>(); suffix = glm::row(suffix, 2, cplane); glm::mat4 newP = suffix * P; gGL.matrixMode(LLRender::MM_PROJECTION); diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 13a0250fe5..1753eeeee9 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -283,10 +283,8 @@ if(LL_TESTS) ) set_property( SOURCE ${llui_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_LIBRARIES ${test_libs}) LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}") - # INTEGRATION TESTS - if(NOT LINUX) - set(test_libs llui llmessage llcorehttp llxml llrender llcommon ll::hunspell ll::SDL2) - LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}") - endif(NOT LINUX) + # INTEGRATION TESTS + set(test_libs llui llmessage llcorehttp llxml llrender llcommon ll::hunspell ll::SDL2) + LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}") endif(LL_TESTS) diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index fd07b2ec5d..92059f0753 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -247,6 +247,7 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p) mTitle(p.title), mShortTitle(p.short_title), mSingleInstance(p.single_instance), + mIsReuseInitialized(p.reuse_instance.isProvided()), mReuseInstance(p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance), // reuse single-instance floaters by default mKey(key), mCanTearOff(p.can_tear_off), @@ -3350,6 +3351,7 @@ void LLFloater::initFromParams(const LLFloater::Params& p) mHeaderHeight = p.header_height; mLegacyHeaderHeight = p.legacy_header_height; mSingleInstance = p.single_instance; + mIsReuseInitialized = p.reuse_instance.isProvided(); mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance; mDefaultRelativeX = p.rel_x; diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 5592bb4b5c..b5c8ecf966 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -23,7 +23,7 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#include "../newview/llviewerprecompiledheaders.h" +#include "linden_common.h" #include "llflashtimer.h" diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 2a8b71055d..08d49aef3c 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2110,7 +2110,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) // set up the callbacks for all of the potential menu items, N.B. we // don't use const ref strings in callbacks in case url goes out of scope - CommitRegistrarHelper registrar(LLUICtrl::CommitCallbackRegistry::currentRegistrar()); + ScopedRegistrarHelper registrar; registrar.add("Url.Open", boost::bind(&LLUrlAction::openURL, url)); registrar.add("Url.OpenInternal", boost::bind(&LLUrlAction::openURLInternal, url)); registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url)); diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 6e6e332632..0af587eb0d 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -144,7 +144,7 @@ void LLToolBar::createContextMenu() { // Setup bindings specific to this instance for the context menu options - CommitRegistrarHelper commit_reg(LLUICtrl::CommitCallbackRegistry::currentRegistrar()); + ScopedRegistrarHelper commit_reg; commit_reg.add("Toolbars.EnableSetting", boost::bind(&LLToolBar::onSettingEnable, this, _2)); commit_reg.add("Toolbars.RemoveSelectedCommand", boost::bind(&LLToolBar::onRemoveSelectedCommand, this)); diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 051ecc4405..b2dcb6dc88 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -31,8 +31,6 @@ #include "llrect.h" #include "llcoord.h" #include "llcontrol.h" -#include "llcoord.h" -#include "llcontrol.h" #include "llinitparam.h" #include "llregistry.h" #include "llrender2dutils.h" diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index a73962f3d6..e02bf5919b 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -246,10 +246,10 @@ void LLWebRTCImpl::init() apm_config.gain_controller1.enabled = false; apm_config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog; apm_config.gain_controller2.enabled = false; - apm_config.high_pass_filter.enabled = true; + apm_config.high_pass_filter.enabled = false; apm_config.noise_suppression.enabled = true; apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kVeryHigh; - apm_config.transient_suppression.enabled = true; + apm_config.transient_suppression.enabled = false; apm_config.pipeline.multi_channel_render = true; apm_config.pipeline.multi_channel_capture = false; @@ -362,14 +362,13 @@ void LLWebRTCImpl::setAudioConfig(LLWebRTCDeviceInterface::AudioConfig config) { webrtc::AudioProcessing::Config apm_config; apm_config.echo_canceller.enabled = config.mEchoCancellation; - apm_config.echo_canceller.mobile_mode = false; + apm_config.echo_canceller.mobile_mode = false; // don't use mobile hardware echo cancellation. apm_config.gain_controller1.enabled = config.mAGC; apm_config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog; - apm_config.gain_controller2.enabled = false; - apm_config.high_pass_filter.enabled = true; - apm_config.transient_suppression.enabled = true; - apm_config.pipeline.multi_channel_render = true; - apm_config.pipeline.multi_channel_capture = true; + apm_config.gain_controller2.enabled = false; // use the main gain controller. + apm_config.high_pass_filter.enabled = false; // don't filter, to improve quality for music and other pure sources. + apm_config.transient_suppression.enabled = false; // transient suppression may increase latency. + apm_config.pipeline.multi_channel_render = true; // stereo apm_config.pipeline.multi_channel_capture = true; switch (config.mNoiseSuppressionLevel) @@ -750,7 +749,7 @@ void LLWebRTCPeerConnectionImpl::init(LLWebRTCImpl * webrtc_impl) } void LLWebRTCPeerConnectionImpl::terminate() { - mWebRTCImpl->SignalingBlockingCall( + mWebRTCImpl->PostSignalingTask( [this]() { if (mPeerConnection) @@ -875,6 +874,13 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti codecparam.parameters["stereo"] = "1"; codecparam.parameters["sprop-stereo"] = "1"; params.codecs.push_back(codecparam); + + // Fixed bitrates result in lower CPU cost + for (auto&& encoding : params.encodings) + { + encoding.max_bitrate_bps = 64000; + encoding.min_bitrate_bps = 64000; + } sender->SetParameters(params); } @@ -959,7 +965,7 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute) mMute = mute; mute |= mWebRTCImpl->isCaptureNoDevice(); mWebRTCImpl->PostSignalingTask( - [&]() + [this, mute]() { if (mPeerConnection) { @@ -1231,7 +1237,7 @@ void LLWebRTCPeerConnectionImpl::OnSuccess(webrtc::SessionDescriptionInterface * else if (sdp_line.find("a=fmtp:" + opus_payload) == 0) { sdp_mangled_stream << sdp_line << "a=fmtp:" << opus_payload - << " minptime=10;useinbandfec=1;stereo=1;sprop-stereo=1;maxplaybackrate=48000;sprop-maxplaybackrate=48000;sprop-maxcapturerate=48000\n"; + << " minptime=10;useinbandfec=1;stereo=1;sprop-stereo=1;maxplaybackrate=48000;sprop-maxplaybackrate=48000;sprop-maxcapturerate=48000;complexity=4\n"; } else { diff --git a/indra/llwindow/llsdl.cpp b/indra/llwindow/llsdl.cpp index 3f7992a1d7..6161bd2972 100644 --- a/indra/llwindow/llsdl.cpp +++ b/indra/llwindow/llsdl.cpp @@ -56,7 +56,6 @@ void init_sdl() std::initializer_list<std::tuple< char const*, char const * > > hintList = { {SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR,"0"}, - {SDL_HINT_VIDEODRIVER,"wayland,x11"}, {SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH,"1"}, {SDL_HINT_IME_INTERNAL_EDITING,"1"} }; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 4793ab4fc7..68704e65bb 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -114,18 +114,6 @@ Display* LLWindowSDL::get_SDL_Display(void) #include <wayland-client-protocol.h> #include <dlfcn.h> -bool LLWindowSDL::isWaylandWindowNotDrawing() const -{ - if( Wayland != mServerProtocol || mWaylandData.mLastFrameEvent == 0 ) - return false; - - auto currentTime = LLTimer::getTotalTime(); - if( (currentTime - mWaylandData.mLastFrameEvent) > 250000 ) - return true; - - return false; -} - uint32_t (*ll_wl_proxy_get_version)(struct wl_proxy *proxy); void (*ll_wl_proxy_destroy)(struct wl_proxy *proxy); int (*ll_wl_proxy_add_listener)(struct wl_proxy *proxy, void (**implementation)(void), void *data); @@ -210,8 +198,22 @@ void LLWindowSDL::waylandFrameDoneCB(void *data, struct wl_callback *cb, uint32_ pThis->setupWaylandFrameCallback(); // ask for a new frame } +bool LLWindowSDL::isWaylandWindowNotDrawing() const +{ + if(!mWaylandLoaded || Wayland != mServerProtocol || mWaylandData.mLastFrameEvent == 0) + return false; + + auto currentTime = LLTimer::getTotalTime(); + if( (currentTime - mWaylandData.mLastFrameEvent) > 250000 ) + return true; + + return false; +} + void LLWindowSDL::setupWaylandFrameCallback() { + if(!mWaylandLoaded) return; + static wl_callback_listener frame_listener { nullptr }; frame_listener.done = &LLWindowSDL::waylandFrameDoneCB; @@ -403,12 +405,14 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b if(!mContext) { LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL; + close(); setupFailure("GL Context creation error", "Error", OSMB_OK); } if (SDL_GL_MakeCurrent(mWindow, mContext) != 0) { LL_WARNS() << "Failed to make context current. SDL: " << SDL_GetError() << LL_ENDL; + close(); setupFailure("GL Context failed to set current failure", "Error", OSMB_OK); } @@ -443,14 +447,6 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b setupFailure( error, "Error", OSMB_OK ); } } - else - { - if (!mWindow) - { - LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL; - setupFailure("Window creation error", "Error", OSMB_OK); - } - } SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits); @@ -468,9 +464,6 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b LL_INFOS() << " Stencil Bits " << S32(stencilBits) << LL_ENDL; GLint colorBits = redBits + greenBits + blueBits + alphaBits; - // fixme: actually, it's REALLY important for picking that we get at - // least 8 bits each of red,green,blue. Alpha we can be a bit more - // relaxed about if we have to. if (colorBits < 32) { close(); @@ -504,26 +497,26 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b if ( SDL_GetWindowWMInfo(mWindow, &info) ) { /* Save the information for later use */ - if ( info.subsystem == SDL_SYSWM_X11 ) + if (info.subsystem == SDL_SYSWM_X11) { - SDL_SetHint(SDL_HINT_VIDEODRIVER, "x11"); mX11Data.mDisplay = info.info.x11.display; mX11Data.mXWindowID = info.info.x11.window; mServerProtocol = X11; LL_INFOS() << "Running under X11" << LL_ENDL; } - else if ( info.subsystem == SDL_SYSWM_WAYLAND ) + else if (info.subsystem == SDL_SYSWM_WAYLAND) { #ifdef LL_WAYLAND - if( !loadWaylandClient() ) { - SDL_SetHint(SDL_HINT_VIDEODRIVER, "x11"); - LL_ERRS() << "Failed to load wayland-client.so or grab required functions" << LL_ENDL; - } else { - SDL_SetHint(SDL_HINT_VIDEODRIVER, "wayland"); + mWaylandLoaded = loadWaylandClient(); + if(!mWaylandLoaded) + { + LL_WARNS() << "Failed to load wayland-client.so or grab required functions" << LL_ENDL; } +#endif mWaylandData.mSurface = info.info.wl.surface; mServerProtocol = Wayland; + setupWaylandFrameCallback(); // If set (XWayland) remove DISPLAY, this will prompt dullahan to also use Wayland @@ -531,15 +524,11 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b unsetenv("DISPLAY"); LL_INFOS() << "Running under Wayland" << LL_ENDL; - LL_WARNS() << "Be aware that with at least SDL2 the window will not receive minimizing events, thus minimized state can only be estimated." - "also setting the application icon via SDL_SetWindowIcon does not work." << LL_ENDL; -#else - setupFailure("Viewer is running under Wayland, but was not compiled with full wayland support!\nYou can compile the viewer with wayland prelimiary support using COMPILE_WAYLAND_SUPPORT", "Error", OSMB_OK); -#endif + LL_WARNS() << "Be aware that with at least SDL2 the window will not receive minimizing events, thus minimized state can only be estimated." << LL_ENDL; } else { - LL_WARNS() << "We're not running under X11 or Wayland? Wild." << LL_ENDL; + LL_WARNS() << "Unsupported windowing system" << LL_ENDL; } } else @@ -1268,6 +1257,7 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(U32 keysym, bool gain) void check_vm_bloat() { +#if LL_LINUX // watch our own VM and RSS sizes, warn if we bloated rapidly static const std::string STATS_FILE = "/proc/self/stat"; FILE *fp = fopen(STATS_FILE.c_str(), "r"); @@ -1351,6 +1341,7 @@ finally: free(ptr); fclose(fp); } +#endif } @@ -1949,9 +1940,9 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) LL_INFOS() << "spawn_web_browser returning." << LL_ENDL; } -void *LLWindowSDL::getPlatformWindow() +void* LLWindowSDL::getPlatformWindow() { - return nullptr; + return (void*)mWindow; } void LLWindowSDL::bringToFront() @@ -1968,6 +1959,8 @@ void LLWindowSDL::bringToFront() //static std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() { + std::vector<std::string> rtns; +#if LL_LINUX // Use libfontconfig to find us a nice ordered list of fallback fonts // specific to this system. std::string final_fallback("/usr/share/fonts/truetype/kochi/kochi-gothic.ttf"); @@ -1984,7 +1977,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() // renderable range if for some reason our FreeType actually fails // to use some of the fonts we want it to. const bool elide_unicode_coverage = true; - std::vector<std::string> rtns; + FcFontSet *fs = nullptr; FcPattern *sortpat = nullptr; @@ -2058,6 +2051,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() LL_INFOS() << "Using " << rtns.size() << "/" << found_font_count << " system fonts." << LL_ENDL; rtns.push_back(final_fallback); +#endif return rtns; } diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 974ba69b61..c3b2f32cf7 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -254,6 +254,8 @@ private: uint64_t mLastFrameEvent = 0; } mWaylandData; + bool mWaylandLoaded = false; + bool isWaylandWindowNotDrawing() const; void setupWaylandFrameCallback(); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 70bdb25415..20049adb58 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1673,6 +1673,11 @@ const S32 max_format = (S32)num_formats - 1; return false; } + // Setup Tracy gpu context + { + LL_PROFILER_GPU_CONTEXT; + } + // Disable vertical sync for swap toggleVSync(enable_vsync); @@ -1704,8 +1709,6 @@ const S32 max_format = (S32)num_formats - 1; swapBuffers(); } - LL_PROFILER_GPU_CONTEXT; - return true; } diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index e695035461..92bcb1a2ae 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -3256,6 +3256,27 @@ std::string LLXMLNode::getTextContents() const return msg; } +std::string LLXMLNode::getXMLRPCTextContents() const +{ + std::string msg; + std::string::size_type start = mValue.find_first_not_of(" \t\n"); + if (start != mValue.npos) + { + std::string::size_type end = mValue.find_last_not_of(" \t\n"); + if (end != mValue.npos) + { + msg = mValue.substr(start, end + 1 - start); + } + else + { + msg = mValue.substr(start); + } + } + // Convert any internal CR to LF + msg = utf8str_removeCRLF(msg); + return msg; +} + void LLXMLNode::setLineNumber(S32 line_number) { mLineNumber = line_number; @@ -3365,7 +3386,7 @@ bool LLXMLNode::fromXMLRPCValue(LLSD& target) if (childp->hasName("string")) { - target.assign(LLStringFn::xml_decode(childp->getTextContents())); + target.assign(LLStringFn::xml_decode(childp->getXMLRPCTextContents())); return true; } diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index 3769ec8293..09c7c4fdad 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -295,6 +295,7 @@ protected: bool removeChild(LLXMLNode* child); bool isFullyDefault(); + std::string getXMLRPCTextContents() const; bool parseXmlRpcArrayValue(LLSD& target); bool parseXmlRpcStructValue(LLSD& target); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b0f5116215..9317b77208 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -30,6 +30,7 @@ include(LLPrimitive) include(LLWindow) include(SDL2) include(NDOF) +include(NFDE) include(NVAPI) include(OPENAL) include(OpenGL) @@ -1440,11 +1441,24 @@ if (DARWIN) LIST(APPEND viewer_SOURCE_FILES llfilepicker_mac.mm) LIST(APPEND viewer_HEADER_FILES llfilepicker_mac.h) + set_source_files_properties( + llappviewermacosx-objc.mm + PROPERTIES + SKIP_PRECOMPILE_HEADERS TRUE + ) + + set_source_files_properties( + llfilepicker_mac.mm + PROPERTIES + SKIP_PRECOMPILE_HEADERS TRUE + ) + # This should be compiled with the viewer. LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm) set_source_files_properties( llappdelegate-objc.mm PROPERTIES + SKIP_PRECOMPILE_HEADERS TRUE COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" # BugsplatMac is a module, imported with @import. That language feature # demands these -f switches. @@ -1674,6 +1688,7 @@ set(viewer_APPSETTINGS_FILES packages-info.txt featuretable.txt featuretable_mac.txt + featuretable_linux.txt ) source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES}) @@ -1735,6 +1750,10 @@ list(APPEND EVENT_HOST_SCRIPTS ${EVENT_HOST_SCRIPT_GLOB_LIST}) set(PACKAGE ON CACHE BOOL "Add a package target that builds an installer package.") +if(USE_PRECOMPILED_HEADERS) + target_precompile_headers( ${VIEWER_BINARY_NAME} PRIVATE llviewerprecompiledheaders.h ) +endif(USE_PRECOMPILED_HEADERS) + if (WINDOWS) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES @@ -1745,10 +1764,6 @@ if (WINDOWS) ) target_compile_options(${VIEWER_BINARY_NAME} PRIVATE /bigobj) - if(USE_PRECOMPILED_HEADERS) - target_precompile_headers( ${VIEWER_BINARY_NAME} PRIVATE llviewerprecompiledheaders.h ) - endif(USE_PRECOMPILED_HEADERS) - # If adding a file to viewer_manifest.py in the WindowsManifest.construct() method, be sure to add the dependency # here. # *NOTE:Mani - This is a crappy hack to have important dependencies for the viewer_manifest copy action @@ -1946,6 +1961,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ll::ndof ll::tracy ll::openxr + ll::nfde ) if( TARGET ll::intel_memops ) diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 09b0e1ec1b..53a2590c20 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -28,8 +28,6 @@ <string>${VIEWER_VERSION_MAJOR}.${VIEWER_VERSION_MINOR}.${VIEWER_VERSION_PATCH}.${VIEWER_VERSION_REVISION}</string> <key>CSResourcesFileMapped</key> <true/> - <key>LSRequiresCarbon</key> - <true/> <key>NSHumanReadableCopyright</key> <string>${MACOSX_BUNDLE_COPYRIGHT}</string> <key>NSMicrophoneUsageDescription</key> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index a810e72aac..00ab0a8b40 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9300,7 +9300,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>1.5</real> + <real>1.0</real> </map> <key>RenderReflectionProbeDrawDistance</key> @@ -10091,6 +10091,17 @@ <key>Value</key> <string>00000000-0000-0000-0000-000000000000</string> </map> + <key>RenderCAS</key> + <map> + <key>Comment</key> + <string>Use Contrast Adaptive Sharpening post process effect</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>RenderCASSharpness</key> <map> <key>Comment</key> @@ -11782,6 +11793,28 @@ <key>Value</key> <integer>0</integer> </map> + <key>TextureDiscardBackgroundedTime</key> + <map> + <key>Comment</key> + <string>Specify how long to wait before discarding texture data after viewer is backgrounded. (zero or negative to disable)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>60.0</real> + </map> + <key>TextureDiscardMinimizedTime</key> + <map> + <key>Comment</key> + <string>Specify how long to wait before discarding texture data after viewer is minimized. (zero or negative to disable)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>1.0</real> + </map> <key>TextureFetchConcurrency</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl b/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl index e80c59b39f..abab71e5ce 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/CASF.glsl @@ -38,6 +38,7 @@ uniform sampler2D diffuseRect; uniform vec2 out_screen_res; uniform uvec4 cas_param_0; uniform uvec4 cas_param_1; +uniform float gamma; vec3 srgb_to_linear(vec3 cs); vec3 linear_to_srgb(vec3 cl); @@ -2545,11 +2546,69 @@ A_STATIC void CasSetup( #endif #ifdef A_GPU + +//================================= +// borrowed noise from: +// <https://www.shadertoy.com/view/4dS3Wd> +// By Morgan McGuire @morgan3d, http://graphicscodex.com +// +float hash(float n) { return fract(sin(n) * 1e4); } +float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } + +float noise(float x) { + float i = floor(x); + float f = fract(x); + float u = f * f * (3.0 - 2.0 * f); + return mix(hash(i), hash(i + 1.0), u); +} + +float noise(vec2 x) { + vec2 i = floor(x); + vec2 f = fract(x); + + // Four corners in 2D of a tile + float a = hash(i); + float b = hash(i + vec2(1.0, 0.0)); + float c = hash(i + vec2(0.0, 1.0)); + float d = hash(i + vec2(1.0, 1.0)); + + // Simple 2D lerp using smoothstep envelope between the values. + // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)), + // mix(c, d, smoothstep(0.0, 1.0, f.x)), + // smoothstep(0.0, 1.0, f.y))); + + // Same code, with the clamps in smoothstep and common subexpressions + // optimized away. + vec2 u = f * f * (3.0 - 2.0 * f); + return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; +} + +//=============================================================== + +vec3 legacyGamma(vec3 color) +{ + vec3 c = 1. - clamp(color, vec3(0.), vec3(1.)); + c = 1. - pow(c, vec3(gamma)); // s/b inverted already CPU-side + + return c; +} + void main() { vec4 diff = vec4(0.f); uvec2 point = uvec2(vary_fragcoord * out_screen_res.xy); CasFilter(diff.r, diff.g, diff.b, point, cas_param_0, cas_param_1, true); + diff.rgb = linear_to_srgb(diff.rgb); + +#ifdef LEGACY_GAMMA + diff.rgb = legacyGamma(diff.rgb); +#endif + + vec2 tc = vary_fragcoord.xy*out_screen_res.xy*4.0; + vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y); + vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); + diff.rgb += nz*0.003; + diff.a = texture(diffuseRect, vary_fragcoord).a; frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/SMAANeighborhoodBlendF.glsl b/indra/newview/app_settings/shaders/class1/deferred/SMAANeighborhoodBlendF.glsl index 3276405447..6b8e7b1ffe 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/SMAANeighborhoodBlendF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/SMAANeighborhoodBlendF.glsl @@ -31,10 +31,12 @@ in vec2 vary_texcoord0; in vec4 vary_offset; uniform sampler2D diffuseRect; +uniform sampler2D emissiveRect; uniform sampler2D blendTex; #if SMAA_REPROJECTION uniform sampler2D velocityTex; #endif +uniform sampler2D depthMap; #define float4 vec4 #define float2 vec2 @@ -51,7 +53,7 @@ float4 SMAANeighborhoodBlendingPS(float2 texcoord, void main() { - frag_color = SMAANeighborhoodBlendingPS(vary_texcoord0, + vec4 diff = SMAANeighborhoodBlendingPS(vary_texcoord0, vary_offset, diffuseRect, blendTex @@ -59,5 +61,11 @@ void main() , velocityTex #endif ); +#ifndef NO_GLOW + diff.rgb += texture(emissiveRect, vary_texcoord0).rgb; +#endif + frag_color = diff; + + gl_FragDepth = texture(depthMap, vary_texcoord0.xy).r; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl index 4a26b8924a..7b196f7da8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl @@ -29,6 +29,7 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D depthMap; +uniform sampler2D emissiveRect; uniform float focal_distance; uniform float blur_constant; @@ -66,12 +67,13 @@ void main() vec4 p = inv_proj*ndc; float depth = p.z/p.w; - vec4 diff = texture(diffuseRect, vary_fragcoord.xy); + vec4 diff = texture(diffuseRect, tc); float sc = calc_cof(depth); sc = min(sc, max_cof); sc = max(sc, -max_cof); - frag_color.rgb = diff.rgb; + vec4 bloom = texture(emissiveRect, tc); + frag_color.rgb = diff.rgb + bloom.rgb; frag_color.a = sc/max_cof*0.5+0.5; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl deleted file mode 100644 index befd2ae6da..0000000000 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file postDeferredGammaCorrect.glsl - * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2007, 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$ - */ - -/*[EXTRA_CODE_HERE]*/ - -out vec4 frag_color; - -uniform sampler2D diffuseRect; - -uniform float gamma; -uniform vec2 screen_res; -in vec2 vary_fragcoord; - -vec3 linear_to_srgb(vec3 cl); - -vec3 legacyGamma(vec3 color) -{ - vec3 c = 1. - clamp(color, vec3(0.), vec3(1.)); - c = 1. - pow(c, vec3(gamma)); // s/b inverted already CPU-side - - return c; -} - -void main() -{ - //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB) - vec4 diff = texture(diffuseRect, vary_fragcoord); - diff.rgb = linear_to_srgb(diff.rgb); - -#ifdef LEGACY_GAMMA - diff.rgb = legacyGamma(diff.rgb); -#endif - - frag_color = max(diff, vec4(0)); -} - diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl index 32b0a1ac8e..cb0a6edea9 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl @@ -30,60 +30,12 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D depthMap; -uniform vec2 screen_res; in vec2 vary_fragcoord; -//================================= -// borrowed noise from: -// <https://www.shadertoy.com/view/4dS3Wd> -// By Morgan McGuire @morgan3d, http://graphicscodex.com -// -float hash(float n) { return fract(sin(n) * 1e4); } -float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } - -float noise(float x) { - float i = floor(x); - float f = fract(x); - float u = f * f * (3.0 - 2.0 * f); - return mix(hash(i), hash(i + 1.0), u); -} - -float noise(vec2 x) { - vec2 i = floor(x); - vec2 f = fract(x); - - // Four corners in 2D of a tile - float a = hash(i); - float b = hash(i + vec2(1.0, 0.0)); - float c = hash(i + vec2(0.0, 1.0)); - float d = hash(i + vec2(1.0, 1.0)); - - // Simple 2D lerp using smoothstep envelope between the values. - // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)), - // mix(c, d, smoothstep(0.0, 1.0, f.x)), - // smoothstep(0.0, 1.0, f.y))); - - // Same code, with the clamps in smoothstep and common subexpressions - // optimized away. - vec2 u = f * f * (3.0 - 2.0 * f); - return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; -} - -//============================= - - - void main() { vec4 diff = texture(diffuseRect, vary_fragcoord.xy); -#ifdef HAS_NOISE - vec2 tc = vary_fragcoord.xy*screen_res*4.0; - vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y); - vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); - diff.rgb += nz*0.003; -#endif - frag_color = diff; gl_FragDepth = texture(depthMap, vary_fragcoord.xy).r; diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl index fc6d4d7727..9d449a5ae2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl @@ -30,6 +30,7 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D exposureMap; +uniform float gamma; uniform vec2 screen_res; in vec2 vary_fragcoord; @@ -149,6 +150,42 @@ vec3 toneMap(vec3 color) return color; } +//================================= +// borrowed noise from: +// <https://www.shadertoy.com/view/4dS3Wd> +// By Morgan McGuire @morgan3d, http://graphicscodex.com +// +float hash(float n) { return fract(sin(n) * 1e4); } +float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); } + +float noise(float x) { + float i = floor(x); + float f = fract(x); + float u = f * f * (3.0 - 2.0 * f); + return mix(hash(i), hash(i + 1.0), u); +} + +float noise(vec2 x) { + vec2 i = floor(x); + vec2 f = fract(x); + + // Four corners in 2D of a tile + float a = hash(i); + float b = hash(i + vec2(1.0, 0.0)); + float c = hash(i + vec2(0.0, 1.0)); + float d = hash(i + vec2(1.0, 1.0)); + + // Simple 2D lerp using smoothstep envelope between the values. + // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)), + // mix(c, d, smoothstep(0.0, 1.0, f.x)), + // smoothstep(0.0, 1.0, f.y))); + + // Same code, with the clamps in smoothstep and common subexpressions + // optimized away. + vec2 u = f * f * (3.0 - 2.0 * f); + return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y; +} + //=============================================================== void debugExposure(inout vec3 color) @@ -161,16 +198,40 @@ void debugExposure(inout vec3 color) } } +vec3 legacyGamma(vec3 color) +{ + vec3 c = 1. - clamp(color, vec3(0.), vec3(1.)); + c = 1. - pow(c, vec3(gamma)); // s/b inverted already CPU-side + + return c; +} + void main() { //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB) vec4 diff = texture(diffuseRect, vary_fragcoord); +#ifdef TONEMAP #ifndef NO_POST diff.rgb = toneMap(diff.rgb); -#else +#endif +#ifndef GAMMA_CORRECT diff.rgb = clamp(diff.rgb, vec3(0.0), vec3(1.0)); #endif +#endif + +#ifdef GAMMA_CORRECT + diff.rgb = linear_to_srgb(diff.rgb); + +#ifdef LEGACY_GAMMA + diff.rgb = legacyGamma(diff.rgb); +#endif + + vec2 tc = vary_fragcoord.xy*screen_res*4.0; + vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y); + vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); + diff.rgb += nz*0.003; +#endif //debugExposure(diff.rgb); frag_color = max(diff, vec4(0)); diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl index ca000dcb23..0e7858743c 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl @@ -29,10 +29,12 @@ out vec4 frag_color; uniform sampler2D diffuseRect; uniform sampler2D emissiveRect; +uniform sampler2D depthMap; in vec2 tc; void main() { frag_color = texture(diffuseRect, tc) + texture(emissiveRect, tc); + gl_FragDepth = texture(depthMap, tc.xy).r; } diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl index 6d34c8aefa..a0d11bb026 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl @@ -28,6 +28,7 @@ out vec4 frag_color; uniform sampler2D diffuseRect; +uniform sampler2D emissiveRect; uniform vec2 screen_res; @@ -36,6 +37,8 @@ in vec2 vary_tc; void main() { vec3 col = texture(diffuseRect, vary_tc).rgb; - - frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144))); +#ifndef NO_GLOW + col += texture(emissiveRect, vary_tc).rgb; +#endif + frag_color = vec4(col, dot(col, vec3(0.299, 0.587, 0.144))); } diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 553d6c1d32..ce9fc853c8 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 63 +version 65 // 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 @@ -80,8 +80,11 @@ RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 RenderDownScaleMethod 1 1 +RenderCAS 1 1 RenderCASSharpness 1 1 - +RenderExposure 1 4 +RenderTonemapType 1 1 +RenderTonemapMix 1 1 // // Low Graphics Settings @@ -118,7 +121,11 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 4 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium Low Graphics Settings @@ -155,7 +162,11 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium Graphics Settings (standard) @@ -192,7 +203,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium High Graphics Settings @@ -229,7 +244,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // High Graphics Settings (SSAO + sun shadows) @@ -266,7 +285,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 1 RenderCASSharpness 1 0.4 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // High Ultra Graphics Settings (deferred + SSAO + all shadows) @@ -303,7 +326,11 @@ RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Ultra graphics (REALLY PURTY!) @@ -340,7 +367,11 @@ RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Class Unknown Hardware (unknown) diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index dc5d1ff6c4..e8004bc1db 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,10 +1,10 @@ -version 29 +version 31 // 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 // defaults. This should be as rare an event as we can manage. -// NOTE: This is mostly identical to featuretable_mac.txt with a few differences +// NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table // @@ -77,11 +77,14 @@ RenderScreenSpaceReflections 1 1 RenderMirrors 1 1 RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 -RenderHeroProbeUpdateRate 1 4 +RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 RenderDownScaleMethod 1 1 +RenderCAS 1 1 RenderCASSharpness 1 1 - +RenderExposure 1 4 +RenderTonemapType 1 1 +RenderTonemapMix 1 1 // // Low Graphics Settings @@ -118,7 +121,11 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 4 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium Low Graphics Settings @@ -155,7 +162,11 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium Graphics Settings (standard) @@ -192,7 +203,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium High Graphics Settings @@ -229,7 +244,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // High Graphics Settings (SSAO + sun shadows) @@ -266,7 +285,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 1 RenderCASSharpness 1 0.4 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // High Ultra Graphics Settings (deferred + SSAO + all shadows) @@ -303,7 +326,11 @@ RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Ultra graphics (REALLY PURTY!) @@ -340,7 +367,11 @@ RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Class Unknown Hardware (unknown) diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index b1359f8b91..26ccb17f27 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 61 +version 63 // 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 @@ -79,7 +79,11 @@ RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 1 RenderCASSharpness 1 1 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 1 // // Low Graphics Settings @@ -116,7 +120,11 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 4 RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium Low Graphics Settings @@ -153,7 +161,11 @@ RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium Graphics Settings (standard) @@ -190,7 +202,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Medium High Graphics Settings @@ -227,7 +243,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // High Graphics Settings (SSAO + sun shadows) @@ -264,7 +284,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCAS 1 0 RenderCASSharpness 1 0 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // High Ultra Graphics Settings (SSAO + all shadows) @@ -301,7 +325,11 @@ RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Ultra graphics (REALLY PURTY!) @@ -338,7 +366,11 @@ RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCAS 1 1 RenderCASSharpness 1 0.4 +RenderExposure 1 1 +RenderTonemapType 1 1 +RenderTonemapMix 1 0.7 // // Class Unknown Hardware (unknown) diff --git a/indra/newview/gltf/common.h b/indra/newview/gltf/common.h index 742daff715..8cf3f1dff7 100644 --- a/indra/newview/gltf/common.h +++ b/indra/newview/gltf/common.h @@ -26,8 +26,6 @@ * $/LicenseInfo$ */ -#define GLM_ENABLE_EXPERIMENTAL 1 - #include "glm/vec2.hpp" #include "glm/vec3.hpp" #include "glm/vec4.hpp" diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index 2810cd6706..3d07ead95d 100644 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -729,15 +729,11 @@ void LLAgentListener::getID(LLSD const& event_data) Response response(llsd::map("id", gAgentID), event_data); } -struct AvResultSet : public LL::ResultSet +struct AvResultSet : public LL::VectorResultSet<LLVOAvatar*> { - AvResultSet() : LL::ResultSet("nearby_avatars") {} - std::vector<LLVOAvatar*> mAvatars; - - int getLength() const override { return narrow(mAvatars.size()); } - LLSD getSingle(int index) const override + AvResultSet() : super("nearby_avatars") {} + LLSD getSingleFrom(LLVOAvatar* const& av) const override { - auto av = mAvatars[index]; LLAvatarName av_name; LLAvatarNameCache::get(av->getID(), &av_name); LLVector3 region_pos = av->getCharacterPosition(); @@ -749,15 +745,11 @@ struct AvResultSet : public LL::ResultSet } }; -struct ObjResultSet : public LL::ResultSet +struct ObjResultSet : public LL::VectorResultSet<LLViewerObject*> { - ObjResultSet() : LL::ResultSet("nearby_objects") {} - std::vector<LLViewerObject*> mObjects; - - int getLength() const override { return narrow(mObjects.size()); } - LLSD getSingle(int index) const override + ObjResultSet() : super("nearby_objects") {} + LLSD getSingleFrom(LLViewerObject* const& obj) const override { - auto obj = mObjects[index]; return llsd::map("id", obj->getID(), "global_pos", ll_sd_from_vector3d(obj->getPositionGlobal()), "region_pos", ll_sd_from_vector3(obj->getPositionRegion()), @@ -791,7 +783,7 @@ void LLAgentListener::getNearbyAvatarsList(LLSD const& event_data) { if ((dist_vec_squared(avatar->getPositionGlobal(), agent_pos) <= radius)) { - avresult->mAvatars.push_back(avatar); + avresult->mVector.push_back(avatar); } } } @@ -813,7 +805,7 @@ void LLAgentListener::getNearbyObjectsList(LLSD const& event_data) { if ((dist_vec_squared(object->getPositionGlobal(), agent_pos) <= radius)) { - objresult->mObjects.push_back(object); + objresult->mVector.push_back(object); } } } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 23da0faa47..8452b3e974 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -273,10 +273,6 @@ using namespace LL; // define a self-registering event API object #include "llappviewerlistener.h" -#if LL_LINUX && LL_GTK -#include "glib.h" -#endif // (LL_LINUX) && LL_GTK - static LLAppViewerListener sAppViewerListener(LLAppViewer::instance); ////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor @@ -1486,6 +1482,7 @@ void sendGameControlInput() bool LLAppViewer::doFrame() { LL_RECORD_BLOCK_TIME(FTM_FRAME); + LL_PROFILE_GPU_ZONE("Frame"); { // and now adjust the visuals from previous frame. if(LLPerfStats::tunables.userAutoTuneEnabled && LLPerfStats::tunables.tuningFlag != LLPerfStats::Tunables::Nothing) @@ -1575,24 +1572,26 @@ bool LLAppViewer::doFrame() if (!LLApp::isExiting()) { - LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df JoystickKeyboard"); - pingMainloopTimeout("Main:JoystickKeyboard"); - - // Scan keyboard for movement keys. Command keys and typing - // are handled by windows callbacks. Don't do this until we're - // done initializing. JC - if (gViewerWindow - && (gHeadlessClient || gViewerWindow->getWindow()->getVisible()) - && gViewerWindow->getActive() - && !gViewerWindow->getWindow()->getMinimized() - && LLStartUp::getStartupState() == STATE_STARTED - && (gHeadlessClient || !gViewerWindow->getShowProgress()) - && !gFocusMgr.focusLocked()) { - LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); - joystick->scanJoystick(); - gKeyboard->scanKeyboard(); - gViewerInput.scanMouse(); + LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df JoystickKeyboard"); + pingMainloopTimeout("Main:JoystickKeyboard"); + + // Scan keyboard for movement keys. Command keys and typing + // are handled by windows callbacks. Don't do this until we're + // done initializing. JC + if (gViewerWindow + && (gHeadlessClient || gViewerWindow->getWindow()->getVisible()) + && gViewerWindow->getActive() + && !gViewerWindow->getWindow()->getMinimized() + && LLStartUp::getStartupState() == STATE_STARTED + && (gHeadlessClient || !gViewerWindow->getShowProgress()) + && !gFocusMgr.focusLocked()) + { + LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE); + joystick->scanJoystick(); + gKeyboard->scanKeyboard(); + gViewerInput.scanMouse(); + } } // Update state based on messages, user input, object idle. diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 7ce74649e2..febe2d1e41 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -39,8 +39,9 @@ #include "llfindlocale.h" #include <exception> - +#ifdef LL_GLIB #include <gio/gio.h> +#endif #include <resolv.h> #if (__GLIBC__*1000 + __GLIBC_MINOR__) >= 2034 @@ -112,6 +113,11 @@ static void exceptionTerminateHandler() int main( int argc, char **argv ) { + // Call Tracy first thing to have it allocate memory + // https://github.com/wolfpld/tracy/issues/196 + LL_PROFILER_FRAME_END; + LL_PROFILER_SET_THREAD_NAME("App"); + gArgC = argc; gArgV = argv; diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 4162c0479a..f497a3cdf3 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -231,6 +231,11 @@ void infos(const std::string& message) int main( int argc, char **argv ) { + // Call Tracy first thing to have it allocate memory + // https://github.com/wolfpld/tracy/issues/196 + LL_PROFILER_FRAME_END; + LL_PROFILER_SET_THREAD_NAME("App"); + // Store off the command line args for use later. gArgC = argc; gArgV = argv; diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index 299cc5ed64..a108f5872c 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -31,6 +31,7 @@ // Viewer includes #include "llagent.h" #include "llagentpicksinfo.h" +#include "llappviewer.h" #include "lldateutil.h" #include "llviewergenericmessage.h" #include "llstartup.h" @@ -367,7 +368,11 @@ void LLAvatarPropertiesProcessor::requestAvatarPropertiesCoro(std::string cap_ur avatar_data.picks_list.emplace_back(pick_data["id"].asUUID(), pick_data["name"].asString()); } - inst.notifyObservers(avatar_id, &avatar_data, type); + LLAppViewer::instance()->postToMainCoro([=]() + { + LLAvatarData av_data = avatar_data; + instance().notifyObservers(avatar_id, &av_data, type); + }); } void LLAvatarPropertiesProcessor::processAvatarLegacyPropertiesReply(LLMessageSystem* msg, void**) diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index 17edca7ccb..032433434d 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -45,6 +45,13 @@ #include <shlobj.h> #endif +#if LL_NFD +#include "nfd.hpp" +#if LL_USE_SDL_WINDOW +#include "nfd_sdl2.h" +#endif +#endif + // // Implementation // @@ -65,7 +72,95 @@ bool LLDirPicker::check_local_file_access_enabled() return true; } -#if LL_WINDOWS +#if LL_NFD + +LLDirPicker::LLDirPicker() : + mFileName(nullptr), + mLocked(false) +{ + reset(); +} + +LLDirPicker::~LLDirPicker() +{ +} + + +void LLDirPicker::reset() +{ + mDir.clear(); +} + +bool LLDirPicker::getDir(std::string* filename, bool blocking) +{ + if( mLocked ) + { + return false; + } + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } + + bool success = false; + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + + // initialize NFD + NFD::Guard nfdGuard; + + // auto-freeing memory + NFD::UniquePath outPath; + + nfdwindowhandle_t windowHandle = nfdwindowhandle_t(); +#if LL_USE_SDL_WINDOW + if(!NFD_GetNativeWindowFromSDLWindow((SDL_Window*)gViewerWindow->getPlatformWindow(), &windowHandle)) + { + windowHandle = nfdwindowhandle_t(); + } +#elif LL_WINDOWS + windowHandle = { NFD_WINDOW_HANDLE_TYPE_WINDOWS, gViewerWindow->getWindow()->getPlatformWindow() }; +#endif + + // show the dialog + nfdresult_t result = NFD::PickFolder(outPath, nullptr, windowHandle); + if (result == NFD_OKAY) + { + mDir = std::string(outPath.get()); + success = true; + } + else if (result == NFD_CANCEL) + { + LL_INFOS() << "User pressed cancel." << LL_ENDL; + } + else + { + LL_INFOS() << "DirPicker Error: " << NFD::GetError() << LL_ENDL; + } + + if (blocking) + { + send_agent_resume(); + + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + } + + return success; +} + +std::string LLDirPicker::getDirName() +{ + return mDir; +} + +#elif LL_WINDOWS LLDirPicker::LLDirPicker() : mFileName(NULL), @@ -286,7 +381,7 @@ std::queue<LLDirPickerThread*> LLDirPickerThread::sDeadQ; void LLDirPickerThread::getFile() { -#if LL_WINDOWS +#if LL_WINDOWS || (LL_NFD && !LL_DARWIN) start(); #else run(); @@ -296,7 +391,7 @@ void LLDirPickerThread::getFile() //virtual void LLDirPickerThread::run() { -#if LL_WINDOWS +#if LL_WINDOWS || (LL_NFD && !LL_DARWIN) bool blocking = false; #else bool blocking = true; // modal diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index bc412214c7..34257f98f8 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -339,7 +339,7 @@ public: } } #else - static inline const char* lookupPass(U32 pass) { return ""; } + static inline const char* lookupPassName(U32 pass) { return ""; } #endif LLRenderPass(const U32 type); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index f3cb07739d..b726e21380 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1557,7 +1557,7 @@ bool LLFace::getGeometryVolume(const LLVolume& volume, } U8 texgen = getTextureEntry()->getTexGen(); - if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT) + if (texgen != LLTextureEntry::TEX_GEN_DEFAULT) { //planar texgen needs binormals mVObjp->getVolume()->genTangents(face_index); } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 634a4853b0..4a33b9f05f 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -31,10 +31,14 @@ #include "llviewertexture.h" class LLGLSLShader; +class LLGLTFMaterialList; +class LLTerrainMaterials; class LLFetchedGLTFMaterial: public LLGLTFMaterial { - friend class LLGLTFMaterialList; // for lifetime management + // for lifetime management + friend class LLGLTFMaterialList; + friend class LLTerrainMaterials; public: LLFetchedGLTFMaterial(); virtual ~LLFetchedGLTFMaterial(); diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 3639064cc4..ca0b58b611 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -36,9 +36,11 @@ #include "llviewercontrol.h" #include "llwindow.h" // beforeDialog() -#if LL_LINUX -#include "llwindowsdl.h" // for some X/GTK utils to help with filepickers -#include "llhttpconstants.h" // file picker uses some of thes constants on Linux +#if LL_NFD +#include "nfd.hpp" +#if LL_USE_SDL_WINDOW +#include "nfd_sdl2.h" +#endif #endif // @@ -80,7 +82,7 @@ LLFilePicker::LLFilePicker() { reset(); -#if LL_WINDOWS +#if LL_WINDOWS && !LL_NFD mOFN.lStructSize = sizeof(OPENFILENAMEW); mOFN.hwndOwner = NULL; // Set later mOFN.hInstance = NULL; @@ -165,7 +167,431 @@ void LLFilePicker::reset() mCurrentFile = 0; } +#if LL_NFD +std::vector<nfdfilteritem_t> LLFilePicker::setupFilter(ELoadFilter filter) +{ + std::vector<nfdfilteritem_t> filter_vec; + switch (filter) + { + case FFLOAD_EXE: #if LL_WINDOWS + filter_vec.emplace_back(nfdfilteritem_t{"Executables", "exe"}); +#endif + break; + case FFLOAD_ALL: + // Empty to allow picking all files by default + break; + case FFLOAD_WAV: + filter_vec.emplace_back(nfdfilteritem_t{"Sounds", "wav"}); + break; + case FFLOAD_IMAGE: + filter_vec.emplace_back(nfdfilteritem_t{"Images", "tga,bmp,jpg,jpeg,png"}); + break; + case FFLOAD_ANIM: + filter_vec.emplace_back(nfdfilteritem_t{"Animations", "bvh,anim"}); + break; + case FFLOAD_GLTF: + case FFLOAD_MATERIAL: + filter_vec.emplace_back(nfdfilteritem_t{"GLTF Files", "gltf,glb"}); + break; + case FFLOAD_COLLADA: + filter_vec.emplace_back(nfdfilteritem_t{"Scene", "dae"}); + break; + case FFLOAD_XML: + filter_vec.emplace_back(nfdfilteritem_t{"XML files", "xml"}); + break; + case FFLOAD_SLOBJECT: + filter_vec.emplace_back(nfdfilteritem_t{"Objects", "slobject"}); + break; + case FFLOAD_RAW: + filter_vec.emplace_back(nfdfilteritem_t{"RAW files", "raw"}); + break; + case FFLOAD_MODEL: + filter_vec.emplace_back(nfdfilteritem_t{"Model files", "dae"}); + break; + case FFLOAD_HDRI: + filter_vec.emplace_back(nfdfilteritem_t{"EXR files", "exr"}); + break; + case FFLOAD_MATERIAL_TEXTURE: + filter_vec.emplace_back(nfdfilteritem_t{"GLTF Import", "gltf,glb,tga,bmp,jpg,jpeg,png"}); + filter_vec.emplace_back(nfdfilteritem_t{"GLTF Files", "gltf,glb"}); + filter_vec.emplace_back(nfdfilteritem_t{"Images", "tga,bmp,jpg,jpeg,png"}); + break; + case FFLOAD_SCRIPT: + filter_vec.emplace_back(nfdfilteritem_t{"Script files (*.lsl)", "lsl"}); + break; + case FFLOAD_DICTIONARY: + filter_vec.emplace_back(nfdfilteritem_t{"Dictionary files", "dic,xcu"}); + break; + case FFLOAD_LUA: + filter_vec.emplace_back(nfdfilteritem_t{"Script files (*.lua)", "lua"}); + break; + default: + break; + } + return filter_vec; +} + +bool LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) +{ + if( mLocked ) + { + return false; + } + bool success = false; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } + + // initialize NFD + NFD::Guard nfdGuard; + + // auto-freeing memory + NFD::UniquePath outPath; + + // prepare filters for the dialog + auto filterItem = setupFilter(filter); + + nfdwindowhandle_t windowHandle = nfdwindowhandle_t(); +#if LL_USE_SDL_WINDOW + if(!NFD_GetNativeWindowFromSDLWindow((SDL_Window*)gViewerWindow->getPlatformWindow(), &windowHandle)) + { + windowHandle = nfdwindowhandle_t(); + } +#elif LL_WINDOWS + windowHandle = { NFD_WINDOW_HANDLE_TYPE_WINDOWS, gViewerWindow->getWindow()->getPlatformWindow() }; +#endif + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + + reset(); + + // show the dialog + nfdresult_t result = NFD::OpenDialog(outPath, filterItem.data(), narrow(filterItem.size()), nullptr, windowHandle); + if (result == NFD_OKAY) + { + mFiles.push_back(outPath.get()); + success = true; + } + + if (blocking) + { + send_agent_resume(); + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + } + + return success; +} + +bool LLFilePicker::getOpenFileModeless(ELoadFilter filter, + void (*callback)(bool, std::vector<std::string> &, void*), + void *userdata) +{ + if( mLocked ) + return false; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } + + reset(); + LL_WARNS() << "NOT IMPLEMENTED" << LL_ENDL; + return false; +} + +bool LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking) +{ + if( mLocked ) + { + return false; + } + bool success = false; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } + + // initialize NFD + NFD::Guard nfdGuard; + + auto filterItem = setupFilter(filter); + + reset(); + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + + nfdwindowhandle_t windowHandle = nfdwindowhandle_t(); +#if LL_USE_SDL_WINDOW + if(!NFD_GetNativeWindowFromSDLWindow((SDL_Window*)gViewerWindow->getPlatformWindow(), &windowHandle)) + { + windowHandle = nfdwindowhandle_t(); + } +#elif LL_WINDOWS + windowHandle = { NFD_WINDOW_HANDLE_TYPE_WINDOWS, gViewerWindow->getWindow()->getPlatformWindow() }; +#endif + + // auto-freeing memory + NFD::UniquePathSet outPaths; + + // show the dialog + nfdresult_t result = NFD::OpenDialogMultiple(outPaths, filterItem.data(), narrow(filterItem.size()), nullptr, windowHandle); + if (result == NFD_OKAY) + { + LL_INFOS() << "Success!" << LL_ENDL; + + nfdpathsetsize_t numPaths; + NFD::PathSet::Count(outPaths, numPaths); + + nfdpathsetsize_t i; + for (i = 0; i < numPaths; ++i) + { + NFD::UniquePathSetPath path; + NFD::PathSet::GetPath(outPaths, i, path); + mFiles.push_back(path.get()); + LL_INFOS() << "Path " << i << ": " << path.get() << LL_ENDL; + } + success = true; + } + else if (result == NFD_CANCEL) + { + LL_INFOS() << "User pressed cancel." << LL_ENDL; + } + else + { + LL_INFOS() << "Error: " << NFD::GetError() << LL_ENDL; + } + + if (blocking) + { + send_agent_resume(); + + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + } + + return success; +} + +bool LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, + void (*callback)(bool, std::vector<std::string> &, void*), + void *userdata ) +{ + if( mLocked ) + return false; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } + + reset(); + + LL_WARNS() << "NOT IMPLEMENTED" << LL_ENDL; + return false; +} + +bool LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking) +{ + if( mLocked ) + { + return false; + } + bool success = false; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } + + // initialize NFD + NFD::Guard nfdGuard; + + std::vector<nfdfilteritem_t> filter_vec; + std::string saved_filename = filename; + switch( filter ) + { + case FFSAVE_ALL: + filter_vec.emplace_back(nfdfilteritem_t{"WAV Sounds", "wav"}); + filter_vec.emplace_back(nfdfilteritem_t{"Targa, Bitmap Images", "tga,bmp"}); + break; + case FFSAVE_WAV: + if (filename.empty()) + { + saved_filename = "untitled.wav"; + } + filter_vec.emplace_back(nfdfilteritem_t{"WAV Sounds", "wav"}); + break; + case FFSAVE_TGA: + if (filename.empty()) + { + saved_filename = "untitled.tga"; + } + filter_vec.emplace_back(nfdfilteritem_t{"Targa Images", "tga"}); + break; + case FFSAVE_BMP: + if (filename.empty()) + { + saved_filename = "untitled.bmp"; + } + filter_vec.emplace_back(nfdfilteritem_t{"Bitmap Images", "bmp"}); + break; + case FFSAVE_PNG: + if (filename.empty()) + { + saved_filename = "untitled.png"; + } + filter_vec.emplace_back(nfdfilteritem_t{"PNG Images", "png"}); + break; + case FFSAVE_TGAPNG: + if (filename.empty()) + { + saved_filename = "untitled.png"; + } + + filter_vec.emplace_back(nfdfilteritem_t{"PNG Images", "png"}); + filter_vec.emplace_back(nfdfilteritem_t{"Targa Images", "tga"}); + filter_vec.emplace_back(nfdfilteritem_t{"JPEG Images", "jpg,jpeg"}); + filter_vec.emplace_back(nfdfilteritem_t{"Jpeg2000 Images", "j2c"}); + filter_vec.emplace_back(nfdfilteritem_t{"Bitmap Images", "bmp"}); + break; + case FFSAVE_JPEG: + if (filename.empty()) + { + saved_filename = "untitled.jpeg"; + } + filter_vec.emplace_back(nfdfilteritem_t{"JPEG Images", "jpg,jpeg"}); + break; + case FFSAVE_AVI: + if (filename.empty()) + { + saved_filename = "untitled.avi"; + } + filter_vec.emplace_back(nfdfilteritem_t{"AVI Movie File", "avi"}); + break; + case FFSAVE_ANIM: + if (filename.empty()) + { + saved_filename = "untitled.xaf"; + } + filter_vec.emplace_back(nfdfilteritem_t{"XAF Anim File", "xaf"}); + break; + case FFSAVE_XML: + if (filename.empty()) + { + saved_filename = "untitled.xml"; + } + filter_vec.emplace_back(nfdfilteritem_t{"XML File", "xml"}); + break; + case FFSAVE_COLLADA: + if (filename.empty()) + { + saved_filename = "untitled.collada"; + } + filter_vec.emplace_back(nfdfilteritem_t{"COLLADA File", "collada"}); + break; + case FFSAVE_RAW: + if (filename.empty()) + { + saved_filename = "untitled.raw"; + } + filter_vec.emplace_back(nfdfilteritem_t{"RAW files", "raw"}); + break; + case FFSAVE_J2C: + if (filename.empty()) + { + saved_filename = "untitled.j2c"; + } + filter_vec.emplace_back(nfdfilteritem_t{"Compressed Images", "j2c"}); + break; + case FFSAVE_SCRIPT: + if (filename.empty()) + { + saved_filename = "untitled.lsl"; + } + filter_vec.emplace_back(nfdfilteritem_t{"LSL Files", "lsl"}); + break; + default: + return false; + } + + nfdwindowhandle_t windowHandle = nfdwindowhandle_t(); +#if LL_USE_SDL_WINDOW + if(!NFD_GetNativeWindowFromSDLWindow((SDL_Window*)gViewerWindow->getPlatformWindow(), &windowHandle)) + { + windowHandle = nfdwindowhandle_t(); + } +#elif LL_WINDOWS + windowHandle = { NFD_WINDOW_HANDLE_TYPE_WINDOWS, gViewerWindow->getWindow()->getPlatformWindow() }; +#endif + + reset(); + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } + + { + NFD::UniquePath savePath; + + // show the dialog + nfdresult_t result = NFD::SaveDialog(savePath, filter_vec.data(), narrow(filter_vec.size()), nullptr, saved_filename.c_str(), windowHandle); + if (result == NFD_OKAY) { + mFiles.push_back(savePath.get()); + success = true; + } + gKeyboard->resetKeys(); + } + + if (blocking) + { + send_agent_resume(); + + // Account for the fact that the app has been stalled. + LLFrameTimer::updateFrameTime(); + } + + return success; +} + +bool LLFilePicker::getSaveFileModeless(ESaveFilter filter, + const std::string& filename, + void (*callback)(bool, std::string&, void*), + void *userdata) +{ + if( mLocked ) + return false; + + // if local file browsing is turned off, return without opening dialog + if ( check_local_file_access_enabled() == false ) + { + return false; + } + + reset(); + LL_WARNS() << "NOT IMPLEMENTED" << LL_ENDL; + return false; +} +#elif LL_WINDOWS bool LLFilePicker::setupFilter(ELoadFilter filter) { @@ -1104,488 +1530,6 @@ bool LLFilePicker::getSaveFileModeless(ESaveFilter filter, #elif LL_LINUX -# if LL_GTK - -// static -void LLFilePicker::add_to_selectedfiles(gpointer data, gpointer user_data) -{ - // We need to run g_filename_to_utf8 in the user's locale - std::string saved_locale(setlocale(LC_ALL, NULL)); - setlocale(LC_ALL, ""); - - LLFilePicker* picker = (LLFilePicker*) user_data; - GError *error = NULL; - gchar* filename_utf8 = g_filename_to_utf8((gchar*)data, - -1, NULL, NULL, &error); - if (error) - { - // *FIXME. - // This condition should really be notified to the user, e.g. - // through a message box. Just logging it is inappropriate. - - // g_filename_display_name is ideal, but >= glib 2.6, so: - // a hand-rolled hacky makeASCII which disallows control chars - std::string display_name; - for (const gchar *str = (const gchar *)data; *str; str++) - { - display_name += (char)((*str >= 0x20 && *str <= 0x7E) ? *str : '?'); - } - LL_WARNS() << "g_filename_to_utf8 failed on \"" << display_name << "\": " << error->message << LL_ENDL; - } - - if (filename_utf8) - { - picker->mFiles.push_back(std::string(filename_utf8)); - LL_DEBUGS() << "ADDED FILE " << filename_utf8 << LL_ENDL; - g_free(filename_utf8); - } - - setlocale(LC_ALL, saved_locale.c_str()); -} - -// static -void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer user_data) -{ - LLFilePicker* picker = (LLFilePicker*)user_data; - - LL_DEBUGS() << "GTK DIALOG RESPONSE " << response << LL_ENDL; - - if (response == GTK_RESPONSE_ACCEPT) - { - GSList *file_list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(widget)); - g_slist_foreach(file_list, (GFunc)add_to_selectedfiles, user_data); - g_slist_foreach(file_list, (GFunc)g_free, NULL); - g_slist_free (file_list); - } - - // let's save the extension of the last added file(considering current filter) - GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget)); - if(gfilter) - { - std::string filter = gtk_file_filter_get_name(gfilter); - - if(filter == LLTrans::getString("png_image_files")) - { - picker->mCurrentExtension = ".png"; - } - else if(filter == LLTrans::getString("targa_image_files")) - { - picker->mCurrentExtension = ".tga"; - } - } - - // set the default path for this usage context. - const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget)); - if (cur_folder != NULL) - { - picker->mContextToPathMap[picker->mCurContextName] = cur_folder; - } - - gtk_widget_destroy(widget); - gtk_main_quit(); -} - - -GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context) -{ -#ifndef LL_MESA_HEADLESS - if (LLWindowSDL::ll_try_gtk_init()) - { - GtkWidget *win = NULL; - GtkFileChooserAction pickertype = - is_save? - (is_folder? - GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER : - GTK_FILE_CHOOSER_ACTION_SAVE) : - (is_folder? - GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER : - GTK_FILE_CHOOSER_ACTION_OPEN); - - win = gtk_file_chooser_dialog_new(NULL, NULL, - pickertype, - GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - is_folder ? - GTK_STOCK_APPLY : - (is_save ? - GTK_STOCK_SAVE : - GTK_STOCK_OPEN), - GTK_RESPONSE_ACCEPT, - (gchar *)NULL); - mCurContextName = context; - - // get the default path for this usage context if it's been - // seen before. - std::map<std::string,std::string>::iterator - this_path = mContextToPathMap.find(context); - if (this_path != mContextToPathMap.end()) - { - gtk_file_chooser_set_current_folder - (GTK_FILE_CHOOSER(win), - this_path->second.c_str()); - } - -# if LL_X11 - // Make GTK tell the window manager to associate this - // dialog with our non-GTK raw X11 window, which should try - // to keep it on top etc. - Window XWindowID = LLWindowSDL::get_SDL_XWindowID(); - if (None != XWindowID) - { - gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin - GdkWindow *gdkwin = gdk_window_foreign_new(XWindowID); - gdk_window_set_transient_for(GTK_WIDGET(win)->window, - gdkwin); - } - else - { - LL_WARNS() << "Hmm, couldn't get xwid to use for transient." << LL_ENDL; - } -# endif //LL_X11 - - g_signal_connect (GTK_FILE_CHOOSER(win), - "response", - G_CALLBACK(LLFilePicker::chooser_responder), - this); - - gtk_window_set_modal(GTK_WINDOW(win), TRUE); - - /* GTK 2.6: if (is_folder) - gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(win), - TRUE); */ - - return GTK_WINDOW(win); - } - else - { - return NULL; - } -#else - return NULL; -#endif //LL_MESA_HEADLESS -} - -static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter, - GtkWindow *picker, - std::string filtername) -{ - gtk_file_filter_set_name(gfilter, filtername.c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter); - GtkFileFilter *allfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(allfilter, "*"); - gtk_file_filter_set_name(allfilter, LLTrans::getString("all_files").c_str()); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), allfilter); - gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(picker), gfilter); -} - -static std::string add_simple_pattern_filter_to_gtkchooser(GtkWindow *picker, - std::string pattern, - std::string filtername) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, pattern.c_str()); - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - -static std::string add_simple_mime_filter_to_gtkchooser(GtkWindow *picker, - std::string mime, - std::string filtername) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_mime_type(gfilter, mime.c_str()); - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - -static std::string add_wav_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_mime_filter_to_gtkchooser(picker, "audio/x-wav", - LLTrans::getString("sound_files") + " (*.wav)"); -} - -static std::string add_anim_filter_to_gtkchooser(GtkWindow *picker) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, "*.bvh"); - gtk_file_filter_add_pattern(gfilter, "*.anim"); - std::string filtername = LLTrans::getString("animation_files") + " (*.bvh; *.anim)"; - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - -static std::string add_xml_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_pattern_filter_to_gtkchooser(picker, "*.xml", - LLTrans::getString("xml_files") + " (*.xml)"); -} - -static std::string add_collada_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_pattern_filter_to_gtkchooser(picker, "*.dae", - LLTrans::getString("scene_files") + " (*.dae)"); -} - -static std::string add_imageload_filter_to_gtkchooser(GtkWindow *picker) -{ - GtkFileFilter *gfilter = gtk_file_filter_new(); - gtk_file_filter_add_pattern(gfilter, "*.tga"); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_JPEG.c_str()); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_PNG.c_str()); - gtk_file_filter_add_mime_type(gfilter, HTTP_CONTENT_IMAGE_BMP.c_str()); - std::string filtername = LLTrans::getString("image_files") + " (*.tga; *.bmp; *.jpg; *.png)"; - add_common_filters_to_gtkchooser(gfilter, picker, filtername); - return filtername; -} - -static std::string add_script_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, - LLTrans::getString("script_files") + " (*.lsl)"); -} - -static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker) -{ - return add_simple_mime_filter_to_gtkchooser(picker, HTTP_CONTENT_TEXT_PLAIN, - LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)"); -} - -static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker) -{ - GtkFileFilter *gfilter_tga = gtk_file_filter_new(); - GtkFileFilter *gfilter_png = gtk_file_filter_new(); - - gtk_file_filter_add_pattern(gfilter_tga, "*.tga"); - gtk_file_filter_add_mime_type(gfilter_png, "image/png"); - std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)"; - gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str()); - gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str()); - - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter_png); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), - gfilter_tga); - return caption; -} - -bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) -{ - bool rtn = false; - - // if local file browsing is turned off, return without opening dialog - if (!check_local_file_access_enabled()) - { - return false; - } - - gViewerWindow->getWindow()->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(true, false, "savefile"); - - if (picker) - { - std::string suggest_name = "untitled"; - std::string suggest_ext = ""; - std::string caption = LLTrans::getString("save_file_verb") + " "; - switch (filter) - { - case FFSAVE_WAV: - caption += add_wav_filter_to_gtkchooser(picker); - suggest_ext = ".wav"; - break; - case FFSAVE_TGA: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.tga", LLTrans::getString("targa_image_files") + " (*.tga)"); - suggest_ext = ".tga"; - break; - case FFSAVE_BMP: - caption += add_simple_mime_filter_to_gtkchooser - (picker, HTTP_CONTENT_IMAGE_BMP, LLTrans::getString("bitmap_image_files") + " (*.bmp)"); - suggest_ext = ".bmp"; - break; - case FFSAVE_PNG: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)"); - suggest_ext = ".png"; - break; - case FFSAVE_TGAPNG: - caption += add_save_texture_filter_to_gtkchooser(picker); - suggest_ext = ".png"; - break; - case FFSAVE_AVI: - caption += add_simple_mime_filter_to_gtkchooser - (picker, "video/x-msvideo", - LLTrans::getString("avi_movie_file") + " (*.avi)"); - suggest_ext = ".avi"; - break; - case FFSAVE_ANIM: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.xaf", LLTrans::getString("xaf_animation_file") + " (*.xaf)"); - suggest_ext = ".xaf"; - break; - case FFSAVE_XML: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.xml", LLTrans::getString("xml_file") + " (*.xml)"); - suggest_ext = ".xml"; - break; - case FFSAVE_RAW: - caption += add_simple_pattern_filter_to_gtkchooser - (picker, "*.raw", LLTrans::getString("raw_file") + " (*.raw)"); - suggest_ext = ".raw"; - break; - case FFSAVE_J2C: - // *TODO: Should this be 'image/j2c' ? - caption += add_simple_mime_filter_to_gtkchooser - (picker, "images/jp2", - LLTrans::getString("compressed_image_files") + " (*.j2c)"); - suggest_ext = ".j2c"; - break; - case FFSAVE_SCRIPT: - caption += add_script_filter_to_gtkchooser(picker); - suggest_ext = ".lsl"; - break; - default:; - break; - } - - gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - - if (filename.empty()) - { - suggest_name += suggest_ext; - - gtk_file_chooser_set_current_name - (GTK_FILE_CHOOSER(picker), - suggest_name.c_str()); - } - else - { - gtk_file_chooser_set_current_name - (GTK_FILE_CHOOSER(picker), filename.c_str()); - } - - gtk_widget_show_all(GTK_WIDGET(picker)); - - gtk_main(); - - rtn = (getFileCount() == 1); - - if(rtn && filter == FFSAVE_TGAPNG) - { - std::string selected_file = mFiles.back(); - mFiles.pop_back(); - mFiles.push_back(selected_file + mCurrentExtension); - } - } - - gViewerWindow->getWindow()->afterDialog(); - - return rtn; -} - -bool LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) -{ - bool rtn = false; - - // if local file browsing is turned off, return without opening dialog - if (!check_local_file_access_enabled()) - { - return false; - } - - gViewerWindow->getWindow()->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(false, false, "openfile"); - - if (picker) - { - std::string caption = LLTrans::getString("load_file_verb") + " "; - std::string filtername = ""; - switch (filter) - { - case FFLOAD_WAV: - filtername = add_wav_filter_to_gtkchooser(picker); - break; - case FFLOAD_ANIM: - filtername = add_anim_filter_to_gtkchooser(picker); - break; - case FFLOAD_XML: - filtername = add_xml_filter_to_gtkchooser(picker); - break; - case FFLOAD_GLTF: - filtername = dead_code_should_blow_up_here(picker); - break; - case FFLOAD_COLLADA: - filtername = add_collada_filter_to_gtkchooser(picker); - break; - case FFLOAD_IMAGE: - filtername = add_imageload_filter_to_gtkchooser(picker); - break; - case FFLOAD_SCRIPT: - filtername = add_script_filter_to_gtkchooser(picker); - break; - case FFLOAD_DICTIONARY: - filtername = add_dictionary_filter_to_gtkchooser(picker); - break; - default:; - break; - } - - caption += filtername; - - gtk_window_set_title(GTK_WINDOW(picker), caption.c_str()); - - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - - rtn = (getFileCount() == 1); - } - - gViewerWindow->getWindow()->afterDialog(); - - return rtn; -} - -bool LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) -{ - bool rtn = false; - - // if local file browsing is turned off, return without opening dialog - if (!check_local_file_access_enabled()) - { - return false; - } - - gViewerWindow->getWindow()->beforeDialog(); - - reset(); - - GtkWindow* picker = buildFilePicker(false, false, "openfile"); - - if (picker) - { - gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER(picker), - TRUE); - - gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("load_files").c_str()); - - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - rtn = !mFiles.empty(); - } - - gViewerWindow->getWindow()->afterDialog(); - - return rtn; -} - -# else // LL_GTK - // Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with // static results, when we don't have a real filepicker. @@ -1673,8 +1617,6 @@ bool LLFilePicker::getMultipleOpenFilesModeless(ELoadFilter filter, return false; } -#endif // LL_GTK - #else // not implemented bool LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename ) diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 4d71a3b392..8c89570174 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -54,6 +54,10 @@ #include <commdlg.h> #endif +#if LL_NFD +#include "nfd.hpp" +#endif + class LLFilePicker { public: @@ -151,14 +155,18 @@ private: // is enabled and if not, tidy up and indicate we're not allowed to do this. bool check_local_file_access_enabled(); -#if LL_WINDOWS +#if LL_NFD + std::vector<nfdfilteritem_t> setupFilter(ELoadFilter filter); +#endif + +#if LL_WINDOWS && !LL_NFD OPENFILENAMEW mOFN; // for open and save dialogs WCHAR mFilesW[FILENAME_BUFFER_SIZE]; bool setupFilter(ELoadFilter filter); #endif -#if LL_DARWIN +#if LL_DARWIN && !LL_NFD S32 mPickOptions; std::vector<std::string> mFileVector; diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 7d098b2676..8897ad55e0 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -151,7 +151,6 @@ void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection *source, S32 so { S32 num_output_sections = 1<<dest_sections; LLVector3 scale = mVO->mDrawable->getScale(); - F32 source_section_length = scale.mV[VZ] / (F32)(1<<source_sections); F32 section_length = scale.mV[VZ] / (F32)num_output_sections; if (source_sections == -1) { @@ -183,6 +182,7 @@ void LLVolumeImplFlexible::remapSections(LLFlexibleObjectSection *source, S32 so // Iterate from right to left since it may be an in-place computation S32 step_shift = dest_sections-source_sections; S32 num_steps = 1<<step_shift; + F32 source_section_length = scale.mV[VZ] / (F32)(1<<source_sections); for (S32 section=num_output_sections-num_steps; section>=0; section -= num_steps) { LLFlexibleObjectSection *last_source_section = &source[section>>step_shift]; diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 6c3e8391cd..f108b5198e 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -37,6 +37,7 @@ #include "llfloatersidepanelcontainer.h" #include "llfocusmgr.h" #include "lllogchat.h" +#include "llregex.h" #include "llresizebar.h" #include "llresizehandle.h" #include "lldraghandle.h" @@ -55,6 +56,7 @@ #include "llfloaterimnearbychatlistener.h" #include "llagent.h" // gAgent #include "llgesturemgr.h" +#include "llluamanager.h" #include "llmultigesture.h" #include "llkeyboard.h" #include "llanimationstates.h" @@ -606,6 +608,13 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type ) if(!LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text)) { utf8_revised_text = utf8text; + // check if the message is /filename.lua and execute the Lua script + static const boost::regex is_lua_script("^/.*\\.luau?(?:\\s+\\S+)*$"); + if (ll_regex_match(utf8text, is_lua_script)) + { + LLLUAmanager::runScriptFile(utf8text.substr(1)); + utf8_revised_text.clear(); + } } } else diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index e85aac3810..84e51fe6c5 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -142,7 +142,7 @@ void LLFloaterIMSession::onClickCloseBtn(bool app_qutting) { if (app_qutting) { - LLFloaterIMSessionTab::onClickCloseBtn(); + LLFloaterIMSessionTab::onClickCloseBtn(app_qutting); return; } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 0855a628fb..4b1d3da630 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -47,6 +47,7 @@ #include "llfloaterimnearbychat.h" #include "llgroupiconctrl.h" #include "lllayoutstack.h" +#include "llnotificationsutil.h" #include "llpanelemojicomplete.h" #include "lltoolbarview.h" @@ -1440,3 +1441,20 @@ bool LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask ) } return handled; } + +void LLFloaterIMSessionTab::onClickCloseBtn(bool app_quitting) +{ + bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false); + if (is_ad_hoc && !app_quitting) + { + LLNotificationsUtil::add("ConfirmLeaveAdhoc", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response) + { + if (0 == LLNotificationsUtil::getSelectedOption(notification, response)) + closeFloater(); + }); + } + else + { + closeFloater(); + } +} diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 890c920bbe..4087ced73d 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -76,13 +76,15 @@ public: bool isNearbyChat() {return mIsNearbyChat;} // LLFloater overrides - /*virtual*/ void onOpen(const LLSD& key); - /*virtual*/ bool postBuild(); - /*virtual*/ void draw(); - /*virtual*/ void setVisible(bool visible); - /*virtual*/ void setFocus(bool focus); - /*virtual*/ void closeFloater(bool app_quitting = false); - /*virtual*/ void deleteAllChildren(); + /*virtual*/ void onOpen(const LLSD& key) override; + /*virtual*/ bool postBuild() override; + /*virtual*/ void draw() override; + /*virtual*/ void setVisible(bool visible) override; + /*virtual*/ void setFocus(bool focus) override; + /*virtual*/ void closeFloater(bool app_quitting = false) override; + /*virtual*/ void deleteAllChildren() override; + + virtual void onClickCloseBtn(bool app_quitting = false) override; // Handle the left hand participant list widgets void addConversationViewParticipant(LLConversationItem* item, bool update_view = true); @@ -98,7 +100,7 @@ public: virtual void updateMessages() {} LLConversationItem* getCurSelectedViewModelItem(); void forceReshape(); - virtual bool handleKeyHere( KEY key, MASK mask ); + virtual bool handleKeyHere( KEY key, MASK mask ) override; bool isMessagePaneExpanded(){return mMessagePaneExpanded;} void setMessagePaneExpanded(bool expanded){mMessagePaneExpanded = expanded;} void restoreFloater(); @@ -139,8 +141,8 @@ protected: virtual void enableDisableCallBtn(); // process focus events to set a currently active session - /* virtual */ void onFocusReceived(); - /* virtual */ void onFocusLost(); + /* virtual */ void onFocusReceived() override; + /* virtual */ void onFocusLost() override; // prepare chat's params and out one message to chatHistory void appendMessage(const LLChat& chat, const LLSD& args = LLSD()); @@ -212,7 +214,7 @@ private: void getSelectedUUIDs(uuid_vec_t& selected_uuids); /// Refreshes the floater at a constant rate. - virtual void refresh() = 0; + virtual void refresh() override = 0; /** * Adjusts chat history height to fit vertically with input chat field diff --git a/indra/newview/llfloaternotificationstabbed.cpp b/indra/newview/llfloaternotificationstabbed.cpp index e571011acf..8eeba095b2 100644 --- a/indra/newview/llfloaternotificationstabbed.cpp +++ b/indra/newview/llfloaternotificationstabbed.cpp @@ -45,7 +45,6 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL mGroupNoticeMessageList(NULL), mTransactionMessageList(NULL), mSystemMessageList(NULL), - mNotificationsSeparator(NULL), mNotificationsTabContainer(NULL), NOTIFICATION_TABBED_ANCHOR_NAME("notification_well_panel"), IM_WELL_ANCHOR_NAME("im_well_panel"), @@ -54,7 +53,7 @@ LLFloaterNotificationsTabbed::LLFloaterNotificationsTabbed(const LLSD& key) : LL { setOverlapsScreenChannel(true); mNotificationUpdates.reset(new NotificationTabbedChannel(this)); - mNotificationsSeparator = new LLNotificationSeparator(); + mNotificationsSeparator = std::make_unique<LLNotificationSeparator>(); } //--------------------------------------------------------------------------------- @@ -117,6 +116,7 @@ void LLFloaterNotificationsTabbed::setSysWellChiclet(LLSysWellChiclet* chiclet) //--------------------------------------------------------------------------------- LLFloaterNotificationsTabbed::~LLFloaterNotificationsTabbed() { + mNotificationsSeparator.reset(); } //--------------------------------------------------------------------------------- diff --git a/indra/newview/llfloaternotificationstabbed.h b/indra/newview/llfloaternotificationstabbed.h index 87e880c8d2..49dfe6033f 100644 --- a/indra/newview/llfloaternotificationstabbed.h +++ b/indra/newview/llfloaternotificationstabbed.h @@ -162,7 +162,7 @@ private: LLNotificationListView* mGroupNoticeMessageList; LLNotificationListView* mTransactionMessageList; LLNotificationListView* mSystemMessageList; - LLNotificationSeparator* mNotificationsSeparator; + std::unique_ptr<LLNotificationSeparator> mNotificationsSeparator; LLTabContainer* mNotificationsTabContainer; LLButton* mDeleteAllBtn; LLButton* mCollapseAllBtn; diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 12576c042b..797d146d97 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -701,13 +701,9 @@ void LLFloaterUIPreview::refreshList() // Note: no deduplification (shouldn't be necessary) void LLFloaterUIPreview::addFloaterEntry(const std::string& path) { - LLUUID* entry_id = new LLUUID(); // create a new UUID - entry_id->generate(path); - const LLUUID& entry_id_ref = *entry_id; // get a reference to the UUID for the LLSD block - // fill LLSD column entry: initialize row/col structure LLSD row; - row["id"] = entry_id_ref; + row["id"] = LLUUID::generateNewID(path); // create a new UUID; LLSD& columns = row["columns"]; // Get name of floater: diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index cf6b08797d..5ca841f9f1 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -523,31 +523,19 @@ bool LLGLTFPreviewTexture::render() gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap); gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap); gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap, /*use_history = */ false); - gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap); - LLVertexBuffer::unbind(); - gPipeline.generateGlow(&gPipeline.mPostMap); - gPipeline.combineGlow(&gPipeline.mPostMap, &screen); - gPipeline.renderDoF(&screen, &gPipeline.mPostMap); - gPipeline.applyFXAA(&gPipeline.mPostMap, &screen); - // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame) - gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); + LLRenderTarget* src = &gPipeline.mPostPingMap; + LLRenderTarget* dst = &gPipeline.mPostPongMap; + gPipeline.tonemap(&screen, dst); + std::swap(src, dst); // Final render + LLVertexBuffer::unbind(); + gPipeline.generateGlow(src); + gPipeline.combineGlow(src, nullptr); - gDeferredPostNoDoFProgram.bind(); - - // From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems." - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &screen); - gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true); - - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - gPipeline.mScreenTriangleVB->setBuffer(); - gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - gDeferredPostNoDoFProgram.unbind(); + // *HACK: Restore mExposureMap (it will be consumed by generateExposure next frame) + gPipeline.mExposureMap.swapFBORefs(gPipeline.mLastExposure); // Clean up gPipeline.setupHWLights(); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index ce419498cf..8e3cd0626f 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -81,6 +81,7 @@ void LLHeroProbeManager::update() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("hero manager update"); llassert(!gCubeSnapshot); // assert a snapshot is not in progress if (LLAppViewer::instance()->logoutRequestSent()) { @@ -279,6 +280,9 @@ void LLHeroProbeManager::renderProbes() // In effect this simulates single-bounce lighting. void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool is_dynamic, F32 near_clip) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("hero probe update"); + // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mHeroProbeRT; @@ -349,7 +353,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool for (int i = 0; i < mMipChain.size(); ++i) { - LL_PROFILE_GPU_ZONE("probe mip"); + LL_PROFILE_GPU_ZONE("hero probe mip"); mMipChain[i].bindTarget(); if (i == 0) { @@ -376,7 +380,7 @@ void LLHeroProbeManager::updateProbeFace(LLReflectionMap* probe, U32 face, bool if (mip >= 0) { - LL_PROFILE_GPU_ZONE("probe mip copy"); + LL_PROFILE_GPU_ZONE("hero probe mip copy"); mTexture->bind(0); glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res); @@ -424,7 +428,7 @@ void LLHeroProbeManager::generateRadiance(LLReflectionMap* probe) for (int i = 0; i < mMipChain.size() / 4; ++i) { - LL_PROFILE_GPU_ZONE("probe radiance gen"); + LL_PROFILE_GPU_ZONE("hero probe radiance gen"); static LLStaticHashedString sMipLevel("mipLevel"); static LLStaticHashedString sRoughness("roughness"); static LLStaticHashedString sWidth("u_width"); @@ -471,6 +475,7 @@ void LLHeroProbeManager::updateUniforms() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("hpmu - uniforms") LLMatrix4a modelview; modelview.loadu(gGLModelView); diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 66130a2744..d56d3a66c5 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -291,15 +291,6 @@ void LLHUDNameTag::renderText() LLVector3 render_position = mPositionAgent + (x_pixel_vec * screen_offset.mV[VX]) + (y_pixel_vec * screen_offset.mV[VY]); - bool reset_buffers = false; - const F32 treshold = 0.000001f; - if (abs(mLastRenderPosition.mV[VX] - render_position.mV[VX]) > treshold - || abs(mLastRenderPosition.mV[VY] - render_position.mV[VY]) > treshold - || abs(mLastRenderPosition.mV[VZ] - render_position.mV[VZ]) > treshold) - { - reset_buffers = true; - mLastRenderPosition = render_position; - } LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); LLRect screen_rect; @@ -323,11 +314,6 @@ void LLHUDNameTag::renderText() for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin(); segment_iter != mLabelSegments.end(); ++segment_iter ) { - if (reset_buffers) - { - segment_iter->mFontBufferLabel.reset(); - } - // Label segments use default font const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp; y_offset -= fontp->getLineHeight(); @@ -365,11 +351,6 @@ void LLHUDNameTag::renderText() for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment; segment_iter != mTextSegments.end(); ++segment_iter ) { - if (reset_buffers) - { - segment_iter->mFontBufferText.reset(); - } - const LLFontGL* fontp = segment_iter->mFont; y_offset -= fontp->getLineHeight(); y_offset -= LINE_PADDING; diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 818474a0cb..593eaa76ca 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -185,15 +185,6 @@ void LLHUDText::renderText() LLVector3 render_position = mPositionAgent + (x_pixel_vec * screen_offset.mV[VX]) + (y_pixel_vec * screen_offset.mV[VY]); - bool reset_buffers = false; - const F32 treshold = 0.000001f; - if (abs(mLastRenderPosition.mV[VX] - render_position.mV[VX]) > treshold - || abs(mLastRenderPosition.mV[VY] - render_position.mV[VY]) > treshold - || abs(mLastRenderPosition.mV[VZ] - render_position.mV[VZ]) > treshold) - { - reset_buffers = true; - mLastRenderPosition = render_position; - } F32 y_offset = (F32)mOffsetY; @@ -217,11 +208,6 @@ void LLHUDText::renderText() for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment; segment_iter != mTextSegments.end(); ++segment_iter ) { - if (reset_buffers) - { - segment_iter->mFontBufferText.reset(); - } - const LLFontGL* fontp = segment_iter->mFont; y_offset -= fontp->getLineHeight() - 1; // correction factor to match legacy font metrics diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index 4c850e2d91..390b7dd16e 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -67,7 +67,6 @@ protected: LLColor4 mColor; LLFontGL::StyleFlags mStyle; const LLFontGL* mFont; - LLFontVertexBuffer mFontBuffer; LLFontVertexBuffer mFontBufferText; private: LLWString mText; diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index e050fb77e0..4c02511268 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -684,14 +684,6 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, asset_type = (LLAssetType::EType)(atoi((*(iter++)).c_str())); iter++; // wearable type if applicable, otherwise asset type item_name = std::string((*(iter++)).c_str()); - // Note There is more elements in 'tokens' ... - - - for (int i = 0; i < 6; i++) - { - LL_WARNS() << *(iter++) << LL_ENDL; - iter++; - } } } else diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index 93f5425fd7..7550b465e9 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -2790,6 +2790,7 @@ static LLDefaultChildRegistry::Register<LLInventoryGalleryItem> r("inventory_gal LLInventoryGalleryItem::LLInventoryGalleryItem(const Params& p) : LLPanel(p), mSelected(false), + mWorn(false), mDefaultImage(true), mItemName(""), mWornSuffix(""), diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 63d3117e77..cfa37cc3ee 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -99,7 +99,7 @@ void LLInventoryItemsList::updateSelection() for(std::vector<LLSD>::const_iterator cur_id_it = cur.begin(); cur_id_it != cur.end() && !mSelectTheseIDs.empty(); ++cur_id_it) { - uuid_vec_t::iterator select_ids_it = std::find(mSelectTheseIDs.begin(), mSelectTheseIDs.end(), *cur_id_it); + uuid_vec_t::iterator select_ids_it = std::find(mSelectTheseIDs.begin(), mSelectTheseIDs.end(), cur_id_it->asUUID()); if(select_ids_it != mSelectTheseIDs.end()) { selectItemByUUID(*select_ids_it); diff --git a/indra/newview/llinventorylistener.cpp b/indra/newview/llinventorylistener.cpp index 88b07c0b0b..13ca12a69a 100644 --- a/indra/newview/llinventorylistener.cpp +++ b/indra/newview/llinventorylistener.cpp @@ -107,15 +107,11 @@ LLInventoryListener::LLInventoryListener() // This struct captures (possibly large) category results from // getDirectDescendants() and collectDescendantsIf(). -struct CatResultSet: public LL::ResultSet +struct CatResultSet: public LL::VectorResultSet<LLInventoryModel::cat_array_t::value_type> { - CatResultSet(): LL::ResultSet("categories") {} - LLInventoryModel::cat_array_t mCategories; - - int getLength() const override { return narrow(mCategories.size()); } - LLSD getSingle(int index) const override + CatResultSet(): super("categories") {} + LLSD getSingleFrom(const LLPointer<LLViewerInventoryCategory>& cat) const override { - auto cat = mCategories[index]; return llsd::map("id", cat->getUUID(), "name", cat->getName(), "parent_id", cat->getParentUUID(), @@ -125,15 +121,11 @@ struct CatResultSet: public LL::ResultSet // This struct captures (possibly large) item results from // getDirectDescendants() and collectDescendantsIf(). -struct ItemResultSet: public LL::ResultSet +struct ItemResultSet: public LL::VectorResultSet<LLInventoryModel::item_array_t::value_type> { - ItemResultSet(): LL::ResultSet("items") {} - LLInventoryModel::item_array_t mItems; - - int getLength() const override { return narrow(mItems.size()); } - LLSD getSingle(int index) const override + ItemResultSet(): super("items") {} + LLSD getSingleFrom(const LLPointer<LLViewerInventoryItem>& item) const override { - auto item = mItems[index]; return llsd::map("id", item->getUUID(), "name", item->getName(), "parent_id", item->getParentUUID(), @@ -160,14 +152,14 @@ void LLInventoryListener::getItemsInfo(LLSD const &data) LLViewerInventoryItem* item = gInventory.getItem(it); if (item) { - itemresult->mItems.push_back(item); + itemresult->mVector.push_back(item); } else { LLViewerInventoryCategory *cat = gInventory.getCategory(it); if (cat) { - catresult->mCategories.push_back(cat); + catresult->mVector.push_back(cat); } } } @@ -202,8 +194,8 @@ void LLInventoryListener::getDirectDescendants(LLSD const &data) auto catresult = new CatResultSet; auto itemresult = new ItemResultSet; - catresult->mCategories = *cats; - itemresult->mItems = *items; + catresult->mVector = *cats; + itemresult->mVector = *items; response["categories"] = catresult->getKeyLength(); response["items"] = itemresult->getKeyLength(); @@ -260,8 +252,8 @@ void LLInventoryListener::collectDescendantsIf(LLSD const &data) // collectDescendentsIf() method so it doesn't steal too many cycles. gInventory.collectDescendentsIf( folder_id, - catresult->mCategories, - itemresult->mItems, + catresult->mVector, + itemresult->mVector, LLInventoryModel::EXCLUDE_TRASH, collector); @@ -269,14 +261,6 @@ void LLInventoryListener::collectDescendantsIf(LLSD const &data) response["items"] = itemresult->getKeyLength(); } -/*==========================================================================*| -void LLInventoryListener::getSingle(LLSD const& data) -{ - auto result = LL::ResultSet::getInstance(data["result"]); - sendReply(llsd::map("single", result->getSingle(data["index"])), data); -} -|*==========================================================================*/ - void LLInventoryListener::getSlice(LLSD const& data) { auto result = LL::ResultSet::getInstance(data["result"]); diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index 56e5555ba5..c048b028f5 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -206,7 +206,7 @@ private: std::string mEditLandmarkTooltip; // this field holds a human-readable form of the location string, it is needed to be able to compare copy-pated value and real location std::string mHumanReadableLocation; - bool isHumanReadableLocationVisible; + bool isHumanReadableLocationVisible = true; std::string mMaturityHelpTopic; }; diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 7b8211ded8..53ea345858 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -450,17 +450,14 @@ LLMarketplaceInventoryImporter::LLMarketplaceInventoryImporter() , mImportInProgress(false) , mInitialized(false) , mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED) - , mErrorInitSignal(NULL) - , mStatusChangedSignal(NULL) - , mStatusReportSignal(NULL) { } boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErrorCallback(const status_report_signal_t::slot_type& cb) { - if (mErrorInitSignal == NULL) + if (mErrorInitSignal == nullptr) { - mErrorInitSignal = new status_report_signal_t(); + mErrorInitSignal = std::make_unique<status_report_signal_t>(); } return mErrorInitSignal->connect(cb); @@ -468,9 +465,9 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setInitializationErr boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCallback(const status_changed_signal_t::slot_type& cb) { - if (mStatusChangedSignal == NULL) + if (mStatusChangedSignal == nullptr) { - mStatusChangedSignal = new status_changed_signal_t(); + mStatusChangedSignal = std::make_unique<status_changed_signal_t>(); } return mStatusChangedSignal->connect(cb); @@ -478,9 +475,9 @@ boost::signals2::connection LLMarketplaceInventoryImporter::setStatusChangedCall boost::signals2::connection LLMarketplaceInventoryImporter::setStatusReportCallback(const status_report_signal_t::slot_type& cb) { - if (mStatusReportSignal == NULL) + if (mStatusReportSignal == nullptr) { - mStatusReportSignal = new status_report_signal_t(); + mStatusReportSignal = std::make_unique<status_report_signal_t>(); } return mStatusReportSignal->connect(cb); @@ -717,8 +714,6 @@ LLMarketplaceTuple::LLMarketplaceTuple(const LLUUID& folder_id, S32 listing_id, LLMarketplaceData::LLMarketplaceData() : mMarketPlaceStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED), mMarketPlaceDataFetched(MarketplaceFetchCodes::MARKET_FETCH_NOT_DONE), - mStatusUpdatedSignal(NULL), - mDataFetchedSignal(NULL), mDirtyCount(false) { mInventoryObserver = new LLMarketplaceInventoryObserver; @@ -752,9 +747,9 @@ LLSD LLMarketplaceData::getMarketplaceStringSubstitutions() void LLMarketplaceData::initializeSLM(const status_updated_signal_t::slot_type& cb) { - if (mStatusUpdatedSignal == NULL) + if (mStatusUpdatedSignal == nullptr) { - mStatusUpdatedSignal = new status_updated_signal_t(); + mStatusUpdatedSignal = std::make_unique<status_updated_signal_t>(); } mStatusUpdatedSignal->connect(cb); @@ -842,7 +837,7 @@ void LLMarketplaceData::setDataFetchedSignal(const status_updated_signal_t::slot { if (mDataFetchedSignal == NULL) { - mDataFetchedSignal = new status_updated_signal_t(); + mDataFetchedSignal = std::make_unique<status_updated_signal_t>(); } mDataFetchedSignal->connect(cb); } diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 281743c1d6..4e61b0c7f3 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -113,9 +113,9 @@ private: bool mInitialized; U32 mMarketPlaceStatus; - status_report_signal_t * mErrorInitSignal; - status_changed_signal_t * mStatusChangedSignal; - status_report_signal_t * mStatusReportSignal; + std::unique_ptr<status_report_signal_t> mErrorInitSignal; + std::unique_ptr<status_changed_signal_t> mStatusChangedSignal; + std::unique_ptr<status_report_signal_t> mStatusReportSignal; }; @@ -276,13 +276,13 @@ private: // Handling Marketplace connection and inventory connection U32 mMarketPlaceStatus; std::string mMarketPlaceFailureReason; - status_updated_signal_t* mStatusUpdatedSignal; + std::unique_ptr<status_updated_signal_t> mStatusUpdatedSignal; LLInventoryObserver* mInventoryObserver; bool mDirtyCount; // If true, stock count value need to be updated at the next check // Update data U32 mMarketPlaceDataFetched; - status_updated_signal_t* mDataFetchedSignal; + std::unique_ptr<status_updated_signal_t> mDataFetchedSignal; std::set<LLUUID> mPendingUpdateSet; // Listing folders waiting for validation diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 355fb78ad2..d2b73fb565 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -3184,14 +3184,7 @@ void LLMaterialEditor::applyToSelection() { LL_WARNS("MaterialEditor") << "Not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL; - // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere. - LLPointer<LLFetchedGLTFMaterial> mat = new LLFetchedGLTFMaterial(); - getGLTFMaterial(mat); - static const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98"); - gGLTFMaterialList.addMaterial(placeholder, mat); - LLRenderMaterialFunctor mat_func(placeholder); - LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - selected_objects->applyToTEs(&mat_func); + LLNotificationsUtil::add("MissingMaterialCaps"); } } diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index ee5e5b438e..dbc44ad649 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -234,7 +234,7 @@ boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LL get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id); if (itCallback == mGetCallbacks.end()) { - std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.insert(std::pair<LLMaterialID, get_callback_t*>(material_id, new get_callback_t())); + std::pair<get_callback_map_t::iterator, bool> ret = mGetCallbacks.emplace(material_id, std::make_unique<get_callback_t>()); itCallback = ret.first; } connection = itCallback->second->connect(cb);; @@ -279,7 +279,7 @@ boost::signals2::connection LLMaterialMgr::getTE(const LLUUID& region_id, const get_callback_te_map_t::iterator itCallback = mGetTECallbacks.find(te_mat_pair); if (itCallback == mGetTECallbacks.end()) { - std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.insert(std::pair<TEMaterialPair, get_callback_te_t*>(te_mat_pair, new get_callback_te_t())); + std::pair<get_callback_te_map_t::iterator, bool> ret = mGetTECallbacks.emplace(te_mat_pair, std::make_unique<get_callback_te_t>()); itCallback = ret.first; } connection = itCallback->second->connect(cb); @@ -317,7 +317,7 @@ boost::signals2::connection LLMaterialMgr::getAll(const LLUUID& region_id, LLMat getall_callback_map_t::iterator itCallback = mGetAllCallbacks.find(region_id); if (mGetAllCallbacks.end() == itCallback) { - std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.insert(std::pair<LLUUID, getall_callback_t*>(region_id, new getall_callback_t())); + std::pair<getall_callback_map_t::iterator, bool> ret = mGetAllCallbacks.emplace(region_id, std::make_unique<getall_callback_t>()); itCallback = ret.first; } return itCallback->second->connect(cb);; @@ -329,8 +329,8 @@ void LLMaterialMgr::put(const LLUUID& object_id, const U8 te, const LLMaterial& if (mPutQueue.end() == itQueue) { LL_DEBUGS("Materials") << "mPutQueue insert object " << object_id << LL_ENDL; - mPutQueue.insert(std::pair<LLUUID, facematerial_map_t>(object_id, facematerial_map_t())); - itQueue = mPutQueue.find(object_id); + auto ret = mPutQueue.emplace(object_id, facematerial_map_t()); + itQueue = ret.first; } facematerial_map_t::iterator itFace = itQueue->second.find(te); @@ -361,7 +361,7 @@ void LLMaterialMgr::setLocalMaterial(const LLUUID& region_id, LLMaterialPtr mate } LL_DEBUGS("Materials") << "region " << region_id << "new local material id " << material_id << LL_ENDL; - mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, material_ptr)); + mMaterials.emplace(material_id, material_ptr); setMaterialCallbacks(material_id, material_ptr); @@ -376,7 +376,7 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL { LL_DEBUGS("Materials") << "new material" << LL_ENDL; LLMaterialPtr newMaterial(new LLMaterial(material_data)); - std::pair<material_map_t::const_iterator, bool> ret = mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, newMaterial)); + std::pair<material_map_t::const_iterator, bool> ret = mMaterials.emplace(material_id, newMaterial); itMaterial = ret.first; } @@ -400,7 +400,6 @@ void LLMaterialMgr::setMaterialCallbacks(const LLMaterialID& material_id, const if (itCallbackTE != mGetTECallbacks.end()) { (*itCallbackTE->second)(material_id, material_ptr, te_mat_pair.te); - delete itCallbackTE->second; mGetTECallbacks.erase(itCallbackTE); } } @@ -410,7 +409,6 @@ void LLMaterialMgr::setMaterialCallbacks(const LLMaterialID& material_id, const { (*itCallback->second)(material_id, material_ptr); - delete itCallback->second; mGetCallbacks.erase(itCallback); } } @@ -509,7 +507,6 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL { (*itCallback->second)(region_id, materials); - delete itCallback->second; mGetAllCallbacks.erase(itCallback); } @@ -549,11 +546,11 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) { llassert(response_data.isArray()); LL_DEBUGS("Materials") << "response has "<< response_data.size() << " materials" << LL_ENDL; +#ifdef SHOW_ASSERT // same condition that controls llassert() for (LLSD::array_const_iterator faceIter = response_data.beginArray(); faceIter != response_data.endArray(); ++faceIter) { -# ifdef SHOW_ASSERT // same condition that controls llassert() const LLSD& face_data = *faceIter; // conditional to avoid unused variable warning -# endif + llassert(face_data.isMap()); llassert(face_data.has(MATERIALS_CAP_OBJECT_ID_FIELD)); @@ -570,6 +567,7 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) // *TODO: do we really still need to process this? } +#endif } } diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h index 1279b77ad4..ac4c18d60c 100644 --- a/indra/newview/llmaterialmgr.h +++ b/indra/newview/llmaterialmgr.h @@ -110,13 +110,13 @@ private: typedef std::map<LLUUID, material_queue_t> get_queue_t; typedef std::pair<const LLUUID, LLMaterialID> pending_material_t; typedef std::map<const pending_material_t, F64> get_pending_map_t; - typedef std::map<LLMaterialID, get_callback_t*> get_callback_map_t; + typedef std::map<LLMaterialID, std::unique_ptr<get_callback_t>> get_callback_map_t; - typedef boost::unordered_map<TEMaterialPair, get_callback_te_t*> get_callback_te_map_t; + typedef boost::unordered_map<TEMaterialPair, std::unique_ptr<get_callback_te_t>> get_callback_te_map_t; typedef std::set<LLUUID> getall_queue_t; typedef std::map<LLUUID, F64> getall_pending_map_t; - typedef std::map<LLUUID, getall_callback_t*> getall_callback_map_t; + typedef std::map<LLUUID, std::unique_ptr<getall_callback_t>> getall_callback_map_t; typedef std::map<U8, LLMaterial> facematerial_map_t; typedef std::map<LLUUID, facematerial_map_t> put_queue_t; diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 49260d5c50..ef9e8d7dac 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -1022,10 +1022,6 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) case MEDIA_EVENT_NAVIGATE_COMPLETE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL; - if(mHidingInitialLoad) - { - mHidingInitialLoad = false; - } }; break; diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 9f9564af46..5d3d8f3ba2 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -201,7 +201,6 @@ public: mStretchToFill, mMaintainAspectRatio, mHideLoading, - mHidingInitialLoad, mClearCache, mHoverTextChanged, mDecoupleTextureSize, diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 6ef7712000..4ebd35171e 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -3564,7 +3564,7 @@ bool LLModelPreview::render() LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; if (decomp) { - LLMutexLock(decomp->mMutex); + LLMutexLock lock(decomp->mMutex); LLModel::Decomposition& physics = model->mPhysics; @@ -3685,7 +3685,7 @@ bool LLModelPreview::render() LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread; if (decomp) { - LLMutexLock(decomp->mMutex); + LLMutexLock lock(decomp->mMutex); LLModel::Decomposition& physics = model->mPhysics; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 483ddcdd63..bf9aa66094 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -96,6 +96,7 @@ LLNetMap::LLNetMap (const Params & p) mPopupWorldPos(0.f, 0.f, 0.f), mMouseDown(0, 0), mPanning(false), + mCentering(false), mUpdateNow(false), mObjectImageCenterGlobal( gAgentCamera.getCameraPositionGlobal() ), mObjectRawImagep(), diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 7cbbb89313..ee5188b2bb 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -517,6 +517,7 @@ void LLPreviewGesture::addKeys() void LLPreviewGesture::addAnimations() { LLComboBox* combo = mAnimationCombo; + LLUUID old_value = combo->getCurrentID(); combo->removeall(); @@ -565,6 +566,8 @@ void LLPreviewGesture::addAnimations() combo->add(item->getName(), item->getAssetUUID(), ADD_BOTTOM); } + + combo->setCurrentByID(old_value); } @@ -1093,6 +1096,9 @@ void LLPreviewGesture::saveIfNeeded() if (!region) { LL_WARNS() << "Not connected to a region, cannot save gesture." << LL_ENDL; + // we're done with this gesture + delete gesture; + gesture = NULL; return; } std::string agent_url = region->getCapability("UpdateGestureAgentInventory"); @@ -1410,7 +1416,7 @@ void LLPreviewGesture::onCommitAnimation(LLUICtrl* ctrl, void* data) { // Assign the animation name LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step; - if (self->mAnimationCombo->getCurrentIndex() == 0) + if (self->mAnimationCombo->getCurrentIndex() <= 0) { anim_step->mAnimName.clear(); anim_step->mAnimAssetID.setNull(); diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 1b657d9ea1..800fc7ec0c 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -441,6 +441,16 @@ void LLPreviewTexture::onFileLoadedForSave(bool success, self->getWindow()->decBusyCount(); self->mLoadingFullImage = false; } + if (!success) + { + LL_WARNS("FileSaveAs") << "Failed to download file " << *item_uuid << " for saving." + << " Is missing: " << (src_vi->isMissingAsset() ? "true" : "false") + << " Discard: " << src_vi->getDiscardLevel() + << " Raw discard: " << discard_level + << " Size: " << src_vi->getWidth() << "x" << src_vi->getHeight() + << " Has GL texture: " << (src_vi->hasGLTexture() ? "true" : "false") + << " Has saved raw image: " << (src_vi->hasSavedRawImage() ? "true" : "false") << LL_ENDL; + } } if( self && final && success ) diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index f083747bfe..4b79ce03eb 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -210,6 +210,7 @@ void LLReflectionMapManager::update() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("reflection manager update"); llassert(!gCubeSnapshot); // assert a snapshot is not in progress if (LLAppViewer::instance()->logoutRequestSent()) { @@ -677,6 +678,8 @@ void LLReflectionMapManager::doProbeUpdate() // In effect this simulates single-bounce lighting. void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("probe update"); // hacky hot-swap of camera specific render targets gPipeline.mRT = &gPipeline.mAuxillaryRT; @@ -991,6 +994,7 @@ void LLReflectionMapManager::updateUniforms() } LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + LL_PROFILE_GPU_ZONE("rmmu - uniforms") // structure for packing uniform buffer object // see class3/deferred/reflectionProbeF.glsl diff --git a/indra/newview/llscrollingpanelparam.h b/indra/newview/llscrollingpanelparam.h index 3aba4e4e40..93daf22e76 100644 --- a/indra/newview/llscrollingpanelparam.h +++ b/indra/newview/llscrollingpanelparam.h @@ -81,7 +81,6 @@ public: protected: LLTimer mMouseDownTimer; // timer for how long mouse has been held down on a hint. F32 mLastHeldTime; - bool mAllowModify; LLButton* mLessBtn; LLButton* mMoreBtn; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 9cce47107a..2c1d798d4c 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -3151,6 +3151,8 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch) F32 scale_x = 1; F32 scale_y = 1; + F32 offset_x = 0; + F32 offset_y = 0; for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) { @@ -3167,6 +3169,21 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch) scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis]; } material->mTextureTransform[i].mScale.set(scale_x, scale_y); + + LLVector2 scales = selectNode->mGLTFScales[te_num][i]; + LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; + F64 int_part = 0; + offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); + if (offset_x < 0) + { + offset_x++; + } + offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); + if (offset_y < 0) + { + offset_y++; + } + material->mTextureTransform[i].mOffset.set(offset_x, offset_y); } LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)tep->getGLTFRenderMaterial(); @@ -6906,6 +6923,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) { mTextureScaleRatios.clear(); mGLTFScaleRatios.clear(); + mGLTFScales.clear(); + mGLTFOffsets.clear(); if (mObject.notNull()) { @@ -6946,6 +6965,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) F32 scale_x = 1; F32 scale_y = 1; std::vector<LLVector3> material_v_vec; + std::vector<LLVector2> material_scales_vec; + std::vector<LLVector2> material_offset_vec; for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) { if (material) @@ -6953,12 +6974,16 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) LLGLTFMaterial::TextureTransform& transform = material->mTextureTransform[i]; scale_x = transform.mScale[VX]; scale_y = transform.mScale[VY]; + material_scales_vec.push_back(transform.mScale); + material_offset_vec.push_back(transform.mOffset); } else { // Not having an override doesn't mean that there is no material scale_x = 1; scale_y = 1; + material_scales_vec.emplace_back(scale_x, scale_y); + material_offset_vec.emplace_back(0.f, 0.f); } if (tep->getTexGen() == LLTextureEntry::TEX_GEN_PLANAR) @@ -6974,6 +6999,8 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) material_v_vec.push_back(material_v); } mGLTFScaleRatios.push_back(material_v_vec); + mGLTFScales.push_back(material_scales_vec); + mGLTFOffsets.push_back(material_offset_vec); } } } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 40e4891bd9..d39c12e2c6 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -240,6 +240,8 @@ public: gltf_materials_vec_t mSavedGLTFOverrideMaterials; std::vector<LLVector3> mTextureScaleRatios; std::vector< std::vector<LLVector3> > mGLTFScaleRatios; + std::vector< std::vector<LLVector2> > mGLTFScales; + std::vector< std::vector<LLVector2> > mGLTFOffsets; std::vector<LLVector3> mSilhouetteVertices; // array of vertices to render silhouette of object std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object bool mSilhouetteExists; // need to generate silhouette? diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 3aaa3d60e8..016ebff827 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -123,7 +123,7 @@ public: std::vector<LLPointer<LLViewerTexture> > mTextureList; - LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info + LLUUID mMaterialHash; // hash of LLGLTFMaterial or LLMaterial applied to this draw info U32 mShaderMask = 0; F32 mEnvIntensity = 0.f; @@ -272,8 +272,7 @@ public: IN_IMAGE_QUEUE = (ALPHA_DIRTY << 1), IMAGE_DIRTY = (IN_IMAGE_QUEUE << 1), MESH_DIRTY = (IMAGE_DIRTY << 1), - NEW_DRAWINFO = (MESH_DIRTY << 1), - IN_BUILD_Q1 = (NEW_DRAWINFO << 1), + IN_BUILD_Q1 = (MESH_DIRTY << 1), IN_BUILD_Q2 = (IN_BUILD_Q1 << 1), STATE_MASK = 0x0000FFFF, } eSpatialState; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 58c01269f7..c5fcb97d12 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -574,12 +574,13 @@ bool LLToolDragAndDrop::handleKey(KEY key, MASK mask) bool LLToolDragAndDrop::handleToolTip(S32 x, S32 y, MASK mask) { + const F32 DRAG_N_DROP_TOOLTIP_DELAY = 0.1f; if (!mToolTipMsg.empty()) { LLToolTipMgr::instance().unblockToolTips(); LLToolTipMgr::instance().show(LLToolTip::Params() .message(mToolTipMsg) - .delay_time(gSavedSettings.getF32( "DragAndDropToolTipDelay" ))); + .delay_time(DRAG_N_DROP_TOOLTIP_DELAY)); return true; } return false; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 184c0e7d8b..e9e231db59 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -770,6 +770,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition); setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); + setting_setup_signal_listener(gSavedSettings, "RenderCAS", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderFSAAType", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index cb741e4af9..94ebca77e2 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -406,6 +406,7 @@ static void update_tp_display(bool minimized) void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Render"); + LL_PROFILE_GPU_ZONE("Render"); LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_DISPLAY); // render time capture - This is the main stat for overall rendering. @@ -473,6 +474,35 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) // true = minimized, do not show/update the TP screen. HB update_tp_display(true); } + + // Run texture subsystem to discard memory while backgrounded + if (!gNonInteractive) + { + LL_PROFILE_ZONE_NAMED("Update Images"); + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Class"); + LLViewerTexture::updateClass(); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Image Update Bump"); + gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first. + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("List"); + F32 max_image_decode_time = 0.050f * gFrameIntervalSeconds.value(); // 50 ms/second decode time + max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f); // min 2ms/frame, max 5ms/frame) + gTextureList.updateImages(max_image_decode_time); + } + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("GLTF Materials Cleanup"); + // remove dead gltf materials + gGLTFMaterialList.flushMaterials(); + } + } return; } @@ -681,6 +711,7 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) if (gPipeline.RenderMirrors && !gSnapshot) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update hero probes"); + LL_PROFILE_GPU_ZONE("hero manager") gPipeline.mHeroProbeManager.update(); gPipeline.mHeroProbeManager.renderProbes(); } diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 66042128f2..12c0335c4f 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -158,6 +158,9 @@ static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode m static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode ) { + agent_handle_doubletap_run(s, mode); + if (KEYSTATE_UP == s) return; + F32 time = gKeyboard->getCurKeyElapsedTime(); S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9ad4926634..9b1709cef0 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -6764,11 +6764,8 @@ class LLAvatarEnableResetSkeleton : public view_listener_t { bool handleEvent(const LLSD& userdata) { - if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())) - { - return true; - } - return false; + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); + return obj && obj->getAvatar(); } }; @@ -9994,7 +9991,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedClickGLTFEdit(), "Advanced.ClickGLTFEdit", cb_info::UNTRUSTED_BLOCK); view_listener_t::addMenu(new LLAdvancedClickResizeWindow(), "Advanced.ClickResizeWindow", cb_info::UNTRUSTED_BLOCK); view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache", cb_info::UNTRUSTED_BLOCK); - view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain", cb_info::UNTRUSTED_BLOCK); #ifdef TOGGLE_HACKED_GODLIKE_VIEWER view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode"); @@ -10012,10 +10008,10 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedResetInterestLists(), "Advanced.ResetInterestLists"); // Develop > Terrain - view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain"); - view_listener_t::addMenu(new LLAdvancedTerrainCreateLocalPaintMap(), "Advanced.TerrainCreateLocalPaintMap"); - view_listener_t::addMenu(new LLAdvancedTerrainEditLocalPaintMap(), "Advanced.TerrainEditLocalPaintMap"); - view_listener_t::addMenu(new LLAdvancedTerrainDeleteLocalPaintMap(), "Advanced.TerrainDeleteLocalPaintMap"); + view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain", cb_info::UNTRUSTED_BLOCK); + view_listener_t::addMenu(new LLAdvancedTerrainCreateLocalPaintMap(), "Advanced.TerrainCreateLocalPaintMap", cb_info::UNTRUSTED_BLOCK); + view_listener_t::addMenu(new LLAdvancedTerrainEditLocalPaintMap(), "Advanced.TerrainEditLocalPaintMap", cb_info::UNTRUSTED_BLOCK); + view_listener_t::addMenu(new LLAdvancedTerrainDeleteLocalPaintMap(), "Advanced.TerrainDeleteLocalPaintMap", cb_info::UNTRUSTED_BLOCK); // Advanced > UI registrar.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 02667a3ff6..51f555b778 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -137,10 +137,10 @@ std::queue<LLFilePickerThread*> LLFilePickerThread::sDeadQ; void LLFilePickerThread::getFile() { -#if LL_WINDOWS +#if LL_WINDOWS || (LL_NFD && !LL_DARWIN) // Todo: get rid of LLFilePickerThread and make this modeless start(); -#elif LL_DARWIN +#elif LL_DARWIN && !LL_NFD runModeless(); #else run(); @@ -150,7 +150,7 @@ void LLFilePickerThread::getFile() //virtual void LLFilePickerThread::run() { -#if LL_WINDOWS +#if LL_WINDOWS || (LL_NFD && !LL_DARWIN) bool blocking = false; #else bool blocking = true; // modal diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 8c24b2438b..d92341eb96 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1750,6 +1750,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use { instance->mTeleportFinishedSignal(instance->mTeleportInProgressPosition, false); } + instance->postTeleportFinished(instance->mTeleportWithinRegion); + instance->mTeleportWithinRegion = false; } parcel->setParcelEnvironmentVersion(parcel_environment_version); LL_DEBUGS("ENVIRONMENT") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL; @@ -2709,6 +2711,8 @@ void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos // Local teleport. We already have the agent parcel data. // Emit the signal immediately. getInstance()->mTeleportFinishedSignal(new_pos, local); + + postTeleportFinished(true); } else { @@ -2717,12 +2721,14 @@ void LLViewerParcelMgr::onTeleportFinished(bool local, const LLVector3d& new_pos // Let's wait for the update and then emit the signal. mTeleportInProgressPosition = new_pos; mTeleportInProgress = true; + mTeleportWithinRegion = local; } } void LLViewerParcelMgr::onTeleportFailed() { mTeleportFailedSignal(); + LLEventPumps::instance().obtain("LLTeleport").post(llsd::map("success", false)); } bool LLViewerParcelMgr::getTeleportInProgress() @@ -2730,3 +2736,17 @@ bool LLViewerParcelMgr::getTeleportInProgress() return mTeleportInProgress // case where parcel data arrives after teleport || gAgent.getTeleportState() > LLAgent::TELEPORT_NONE; // For LOCAL, no mTeleportInProgress } + +void LLViewerParcelMgr::postTeleportFinished(bool local) +{ + auto post = []() { LLEventPumps::instance().obtain("LLTeleport").post(llsd::map("success", true)); }; + if (local) + { + static LLCachedControl<F32> teleport_local_delay(gSavedSettings, "TeleportLocalDelay"); + LL::Timers::instance().scheduleAfter(post, teleport_local_delay + 0.5f); + } + else + { + post(); + } +} diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 974ea39359..4d54593c1e 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -295,6 +295,8 @@ public: void onTeleportFailed(); bool getTeleportInProgress(); + void postTeleportFinished(bool local); + static bool isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power); static bool isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power); @@ -344,8 +346,11 @@ private: std::vector<LLParcelObserver*> mObservers; + // Used to communicate between onTeleportFinished() and processParcelProperties() bool mTeleportInProgress; + bool mTeleportWithinRegion{ false }; LLVector3d mTeleportInProgressPosition; + teleport_finished_signal_t mTeleportFinishedSignal; teleport_failed_signal_t mTeleportFailedSignal; diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index a643aa91bb..35ed040e08 100755 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -559,8 +559,7 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3 { F32 new_x = start[VX] + (x - start[VX]) * part; F32 new_y = start[VY] + (y - start[VY]) * part; - F32 new_z = start[VZ] + (z - start[VZ]) * part; - edge.pushVertex(lod, new_x, new_y, new_z, water_z); + edge.pushVertex(lod, new_x, new_y, water_z, 0); }; auto checkForSplit = [&](U32 lod) @@ -624,7 +623,6 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3 // Point G simplified (last two vertices) move(LINE_WIDTH); - checkForSplit(1); pushTwoVertices(1); // Point G detailized (only one vertex) diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index a857887247..5700d8b278 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -29,22 +29,28 @@ #ifndef LL_LLVIEWERPRECOMPILEDHEADERS_H #define LL_LLVIEWERPRECOMPILEDHEADERS_H -#include "llwin32headers.h" - // This file MUST be the first one included by each .cpp file // in viewer. // It is used to precompile headers for improved build speed. #include "linden_common.h" +#include "llwin32headers.h" + #include <algorithm> #include <deque> #include <functional> +#include <list> #include <map> #include <set> #include <vector> +#include <string_view> +#include <unordered_map> +#include <unordered_set> // Library headers from llcommon project: +#include "apply.h" +#include "function_types.h" #include "indra_constants.h" #include "llinitparam.h" #include "llapp.h" @@ -54,8 +60,10 @@ #include "llerror.h" #include "llfasttimer.h" #include "llframetimer.h" +#include "llinstancetracker.h" #include "llpointer.h" #include "llprocessor.h" +#include "llrand.h" #include "llrefcount.h" #include "llsafehandle.h" #include "llsd.h" @@ -65,11 +73,13 @@ #include "llstring.h" #include "llsys.h" #include "lltimer.h" +#include "lluuid.h" #include "stdtypes.h" #include "u64.h" // Library includes from llmath project #include "llmath.h" +#include "llbbox.h" #include "llbboxlocal.h" #include "llcamera.h" #include "llcoord.h" @@ -77,9 +87,7 @@ #include "llcrc.h" #include "llplane.h" #include "llquantize.h" -#include "llrand.h" #include "llrect.h" -#include "lluuid.h" #include "m3math.h" #include "m4math.h" #include "llquaternion.h" @@ -91,11 +99,42 @@ #include "v4coloru.h" #include "v4math.h" #include "xform.h" +#include "llvector4a.h" +#include "llmatrix4a.h" +#include "lloctree.h" +#include "llvolume.h" +// Library includes from llfilesystem project #include "lldir.h" // Library includes from llmessage project +#include "llassetstorage.h" +#include "llavatarnamecache.h" #include "llcachename.h" +#include "llcorehttputil.h" + +// Library includes from llrender project +#include "llgl.h" +#include "llrender.h" + +// Library includes from llrender project +#include "llcharacter.h" + +// Library includes from llui project +#include "llnotifications.h" +#include "llpanel.h" +#include "llfloater.h" + +#include <boost/function.hpp> +#include <boost/signals2.hpp> +#include <boost/unordered_set.hpp> +#include <boost/unordered_map.hpp> +#include <boost/json.hpp> +#include "glm/glm.hpp" +#include "glm/gtc/type_ptr.hpp" +#include "glm/ext/quaternion_float.hpp" +#include "glm/gtx/quaternion.hpp" +#include "glm/gtx/matrix_decompose.hpp" #endif diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index a6d397c039..4d248af5d5 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -87,6 +87,7 @@ LLGLSLShader gRadianceGenProgram; LLGLSLShader gHeroRadianceGenProgram; LLGLSLShader gIrradianceGenProgram; LLGLSLShader gGlowCombineFXAAProgram; +LLGLSLShader gFXAALumaGenProgram; LLGLSLShader gTwoTextureCompareProgram; LLGLSLShader gOneTextureFilterProgram; LLGLSLShader gDebugProgram; @@ -198,6 +199,7 @@ LLGLSLShader gDeferredPostTonemapProgram; LLGLSLShader gNoPostTonemapProgram; LLGLSLShader gDeferredPostGammaCorrectProgram; LLGLSLShader gLegacyPostGammaCorrectProgram; +LLGLSLShader gNoPostGammaCorrectProgram; LLGLSLShader gExposureProgram; LLGLSLShader gExposureProgramNoFade; LLGLSLShader gLuminanceProgram; @@ -205,7 +207,9 @@ LLGLSLShader gFXAAProgram[4]; LLGLSLShader gSMAAEdgeDetectProgram[4]; LLGLSLShader gSMAABlendWeightsProgram[4]; LLGLSLShader gSMAANeighborhoodBlendProgram[4]; +LLGLSLShader gSMAANeighborhoodBlendGlowCombineProgram[4]; LLGLSLShader gCASProgram; +LLGLSLShader gCASLegacyGammaProgram; LLGLSLShader gDeferredPostNoDoFProgram; LLGLSLShader gDeferredPostNoDoFNoiseProgram; LLGLSLShader gDeferredWLSkyProgram; @@ -434,8 +438,8 @@ void LLViewerShaderMgr::finalizeShaderList() mShaderList.push_back(&gHUDPBRAlphaProgram); mShaderList.push_back(&gDeferredPostTonemapProgram); mShaderList.push_back(&gNoPostTonemapProgram); - mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma - mShaderList.push_back(&gLegacyPostGammaCorrectProgram); + mShaderList.push_back(&gLegacyPostGammaCorrectProgram); // for gamma + mShaderList.push_back(&gCASLegacyGammaProgram); // for gamma mShaderList.push_back(&gDeferredDiffuseProgram); mShaderList.push_back(&gDeferredBumpProgram); mShaderList.push_back(&gDeferredPBROpaqueProgram); @@ -985,7 +989,10 @@ bool LLViewerShaderMgr::loadShadersWater() return loadShadersWater(); } - LLWorld::getInstance()->updateWaterObjects(); + if (LLWorld::instanceExists()) + { + LLWorld::getInstance()->updateWaterObjects(); + } return true; } @@ -2323,8 +2330,10 @@ bool LLViewerShaderMgr::loadShadersDeferred() gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true; gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); gDeferredPostGammaCorrectProgram.clearPermutations(); + gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP", "1"); + gDeferredPostGammaCorrectProgram.addPermutation("GAMMA_CORRECT", "1"); gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER)); + gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredPostGammaCorrectProgram.createShader(); llassert(success); @@ -2337,9 +2346,10 @@ bool LLViewerShaderMgr::loadShadersDeferred() gLegacyPostGammaCorrectProgram.mFeatures.isDeferred = true; gLegacyPostGammaCorrectProgram.mShaderFiles.clear(); gLegacyPostGammaCorrectProgram.clearPermutations(); + gLegacyPostGammaCorrectProgram.addPermutation("GAMMA_CORRECT", "1"); gLegacyPostGammaCorrectProgram.addPermutation("LEGACY_GAMMA", "1"); gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER)); + gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); gLegacyPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gLegacyPostGammaCorrectProgram.createShader(); llassert(success); @@ -2347,11 +2357,27 @@ bool LLViewerShaderMgr::loadShadersDeferred() if (success) { + gNoPostGammaCorrectProgram.mName = "No Post Gamma Correction Post Process"; + gNoPostGammaCorrectProgram.mFeatures.hasSrgb = true; + gNoPostGammaCorrectProgram.mFeatures.isDeferred = true; + gNoPostGammaCorrectProgram.mShaderFiles.clear(); + gNoPostGammaCorrectProgram.clearPermutations(); + gNoPostGammaCorrectProgram.addPermutation("GAMMA_CORRECT", "1"); + gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); + gNoPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gNoPostGammaCorrectProgram.createShader(); + llassert(success); + } + + if (success) + { gDeferredPostTonemapProgram.mName = "Deferred Tonemap Post Process"; gDeferredPostTonemapProgram.mFeatures.hasSrgb = true; gDeferredPostTonemapProgram.mFeatures.isDeferred = true; gDeferredPostTonemapProgram.mShaderFiles.clear(); gDeferredPostTonemapProgram.clearPermutations(); + gDeferredPostTonemapProgram.addPermutation("TONEMAP", "1"); gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); gDeferredPostTonemapProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; @@ -2366,6 +2392,7 @@ bool LLViewerShaderMgr::loadShadersDeferred() gNoPostTonemapProgram.mFeatures.isDeferred = true; gNoPostTonemapProgram.mShaderFiles.clear(); gNoPostTonemapProgram.clearPermutations(); + gNoPostTonemapProgram.addPermutation("TONEMAP", "1"); gNoPostTonemapProgram.addPermutation("NO_POST", "1"); gNoPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); gNoPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredTonemap.glsl", GL_FRAGMENT_SHADER)); @@ -2471,6 +2498,7 @@ bool LLViewerShaderMgr::loadShadersDeferred() gSMAANeighborhoodBlendProgram[i].clearPermutations(); gSMAANeighborhoodBlendProgram[i].addPermutations(defines); + gSMAANeighborhoodBlendProgram[i].addPermutation("NO_GLOW", "1"); gSMAANeighborhoodBlendProgram[i].mShaderFiles.clear(); gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendF.glsl", GL_FRAGMENT_SHADER_ARB)); @@ -2478,8 +2506,27 @@ bool LLViewerShaderMgr::loadShadersDeferred() gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB)); gSMAANeighborhoodBlendProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB)); gSMAANeighborhoodBlendProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + success = gSMAANeighborhoodBlendProgram[i].createShader(); } + + if (success) + { + gSMAANeighborhoodBlendGlowCombineProgram[i].mName = llformat("SMAA Neighborhood Blending Glow Combine (%s)", smaa_pair.second.c_str()); + gSMAANeighborhoodBlendGlowCombineProgram[i].mFeatures.isDeferred = true; + + gSMAANeighborhoodBlendGlowCombineProgram[i].clearPermutations(); + gSMAANeighborhoodBlendGlowCombineProgram[i].addPermutations(defines); + + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.clear(); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendF.glsl", GL_FRAGMENT_SHADER_ARB)); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAANeighborhoodBlendV.glsl", GL_VERTEX_SHADER_ARB)); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_FRAGMENT_SHADER_ARB)); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderFiles.push_back(make_pair("deferred/SMAA.glsl", GL_VERTEX_SHADER_ARB)); + gSMAANeighborhoodBlendGlowCombineProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + + success = gSMAANeighborhoodBlendGlowCombineProgram[i].createShader(); + } ++i; } } @@ -2497,6 +2544,19 @@ bool LLViewerShaderMgr::loadShadersDeferred() if (success) { + gCASLegacyGammaProgram.mName = "Contrast Adaptive Sharpening Legacy Gamma Shader"; + gCASLegacyGammaProgram.mFeatures.hasSrgb = true; + gCASLegacyGammaProgram.clearPermutations(); + gCASLegacyGammaProgram.addPermutation("LEGACY_GAMMA", "1"); + gCASLegacyGammaProgram.mShaderFiles.clear(); + gCASLegacyGammaProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gCASLegacyGammaProgram.mShaderFiles.push_back(make_pair("deferred/CASF.glsl", GL_FRAGMENT_SHADER)); + gCASLegacyGammaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gCASLegacyGammaProgram.createShader(); + } + + if (success) + { gDeferredPostProgram.mName = "Deferred Post Shader"; gDeferredPostProgram.mFeatures.isDeferred = true; gDeferredPostProgram.mShaderFiles.clear(); @@ -2545,22 +2605,6 @@ bool LLViewerShaderMgr::loadShadersDeferred() if (success) { - gDeferredPostNoDoFNoiseProgram.mName = "Deferred Post NoDoF Noise Shader"; - gDeferredPostNoDoFNoiseProgram.mFeatures.isDeferred = true; - gDeferredPostNoDoFNoiseProgram.mShaderFiles.clear(); - gDeferredPostNoDoFNoiseProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); - gDeferredPostNoDoFNoiseProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER)); - - gDeferredPostNoDoFNoiseProgram.clearPermutations(); - gDeferredPostNoDoFNoiseProgram.addPermutation("HAS_NOISE", "1"); - - gDeferredPostNoDoFNoiseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredPostNoDoFNoiseProgram.createShader(); - llassert(success); - } - - if (success) - { gEnvironmentMapProgram.mName = "Environment Map Program"; gEnvironmentMapProgram.mShaderFiles.clear(); gEnvironmentMapProgram.mFeatures.calculatesAtmospherics = true; @@ -2948,7 +2992,7 @@ bool LLViewerShaderMgr::loadShadersInterface() if (success) { - gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader"; + gGlowCombineFXAAProgram.mName = "Glow Combine FXAA Luma Gen Shader"; gGlowCombineFXAAProgram.mShaderFiles.clear(); gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER)); gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER)); @@ -2963,6 +3007,25 @@ bool LLViewerShaderMgr::loadShadersInterface() } } + if (success) + { + gFXAALumaGenProgram.mName = "FXAA Luma Gen Shader"; + gFXAALumaGenProgram.mShaderFiles.clear(); + gFXAALumaGenProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER)); + gFXAALumaGenProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER)); + gFXAALumaGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE]; + gFXAALumaGenProgram.clearPermutations(); + gFXAALumaGenProgram.addPermutation("NO_GLOW", "1"); + success = gFXAALumaGenProgram.createShader(); + if (success) + { + gFXAALumaGenProgram.bind(); + gFXAALumaGenProgram.uniform1i(sGlowMap, 0); + gFXAALumaGenProgram.uniform1i(sScreenMap, 1); + gFXAALumaGenProgram.unbind(); + } + } + #ifdef LL_WINDOWS if (success) { diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index e654967c46..60b880c161 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -160,6 +160,7 @@ extern LLGLSLShader gRadianceGenProgram; extern LLGLSLShader gHeroRadianceGenProgram; extern LLGLSLShader gIrradianceGenProgram; extern LLGLSLShader gGlowCombineFXAAProgram; +extern LLGLSLShader gFXAALumaGenProgram; extern LLGLSLShader gDebugProgram; enum NormalDebugShaderVariant : S32 { @@ -250,11 +251,13 @@ extern LLGLSLShader gFXAAProgram[4]; extern LLGLSLShader gSMAAEdgeDetectProgram[4]; extern LLGLSLShader gSMAABlendWeightsProgram[4]; extern LLGLSLShader gSMAANeighborhoodBlendProgram[4]; +extern LLGLSLShader gSMAANeighborhoodBlendGlowCombineProgram[4]; extern LLGLSLShader gCASProgram; +extern LLGLSLShader gCASLegacyGammaProgram; extern LLGLSLShader gDeferredPostNoDoFProgram; -extern LLGLSLShader gDeferredPostNoDoFNoiseProgram; extern LLGLSLShader gDeferredPostGammaCorrectProgram; extern LLGLSLShader gLegacyPostGammaCorrectProgram; +extern LLGLSLShader gNoPostGammaCorrectProgram; extern LLGLSLShader gDeferredPostTonemapProgram; extern LLGLSLShader gNoPostTonemapProgram; extern LLGLSLShader gExposureProgram; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 6953407f75..546fc354b0 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -43,6 +43,7 @@ #include "message.h" #include "lltimer.h" #include "v4coloru.h" +#include "llnotificationsutil.h" // viewer includes #include "llimagegl.h" @@ -505,8 +506,12 @@ void LLViewerTexture::updateClass() F32 budget = max_vram_budget == 0 ? (F32)gGLManager.mVRAM : (F32)max_vram_budget; - // try to leave half a GB for everyone else, but keep at least 768MB for ourselves - F32 target = llmax(budget - 512.f, MIN_VRAM_BUDGET); + // Try to leave at least half a GB for everyone else and for bias, + // but keep at least 768MB for ourselves + // Viewer can 'overshoot' target when scene changes, if viewer goes over budget it + // can negatively impact performance, so leave 20% of a breathing room for + // 'bias' calculation to kick in. + F32 target = llmax(llmin(budget - 512.f, budget * 0.8f), MIN_VRAM_BUDGET); sFreeVRAMMegabytes = target - used; F32 over_pct = (used - target) / target; @@ -522,7 +527,7 @@ void LLViewerTexture::updateClass() // slam to 1.5 bias the moment we hit low memory (discards off screen textures immediately) sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f); - if (is_sys_low) + if (is_sys_low || over_pct > 2.f) { // if we're low on system memory, emergency purge off screen textures to avoid a death spiral LL_WARNS() << "Low system memory detected, emergency downrezzing off screen textures" << LL_ENDL; for (auto& image : gTextureList) @@ -542,7 +547,6 @@ void LLViewerTexture::updateClass() { static LLCachedControl<F32> low_mem_min_discard_increment(gSavedSettings, "RenderLowMemMinDiscardIncrement", .1f); sDesiredDiscardBias += (F32) low_mem_min_discard_increment * (F32) gFrameIntervalSeconds; - sEvaluationTimer.reset(); } } else @@ -558,20 +562,49 @@ void LLViewerTexture::updateClass() } // set to max discard bias if the window has been backgrounded for a while + static F32 last_desired_discard_bias = 1.f; static bool was_backgrounded = false; static LLFrameTimer backgrounded_timer; + static LLCachedControl<F32> minimized_discard_time(gSavedSettings, "TextureDiscardMinimizedTime", 1.f); + static LLCachedControl<F32> backgrounded_discard_time(gSavedSettings, "TextureDiscardBackgroundedTime", 60.f); bool in_background = (gViewerWindow && !gViewerWindow->getWindow()->getVisible()) || !gFocusMgr.getAppHasFocus(); - + bool is_minimized = gViewerWindow && gViewerWindow->getWindow()->getMinimized() && in_background; if (in_background) { - if (backgrounded_timer.getElapsedTimeF32() > 10.f) + F32 discard_time = is_minimized ? minimized_discard_time : backgrounded_discard_time; + if (discard_time > 0.f && backgrounded_timer.getElapsedTimeF32() > discard_time) { if (!was_backgrounded) { - LL_INFOS() << "Viewer is backgrounded, freeing up video memory." << LL_ENDL; + std::string notification_name; + std::string setting; + if (is_minimized) + { + notification_name = "TextureDiscardMinimized"; + setting = "TextureDiscardMinimizedTime"; + } + else + { + notification_name = "TextureDiscardBackgrounded"; + setting = "TextureDiscardBackgroundedTime"; + } + + LL_INFOS() << "Viewer was " << (is_minimized ? "minimized" : "backgrounded") << " for " << discard_time + << "s, freeing up video memory." << LL_ENDL; + + LLNotificationsUtil::add(notification_name, llsd::map("DELAY", discard_time), LLSD(), + [=](const LLSD& notification, const LLSD& response) + { + if (response["Cancel_okcancelignore"].asBoolean()) + { + LL_INFOS() << "User chose to disable texture discard on " << (is_minimized ? "minimizing." : "backgrounding.") << LL_ENDL; + gSavedSettings.setF32(setting, -1.f); + } + }); + last_desired_discard_bias = sDesiredDiscardBias; + was_backgrounded = true; } - was_backgrounded = true; sDesiredDiscardBias = 4.f; } } @@ -580,9 +613,9 @@ void LLViewerTexture::updateClass() backgrounded_timer.reset(); if (was_backgrounded) { // if the viewer was backgrounded - LL_INFOS() << "Viewer is no longer backgrounded, resuming normal texture usage." << LL_ENDL; + LL_INFOS() << "Viewer is no longer backgrounded or minimized, resuming normal texture usage." << LL_ENDL; was_backgrounded = false; - sDesiredDiscardBias = 1.f; + sDesiredDiscardBias = last_desired_discard_bias; } } @@ -1522,8 +1555,8 @@ void LLViewerFetchedTexture::postCreateTexture() if (!needsToSaveRawImage()) { mNeedsAux = false; - destroyRawImage(); } + destroyRawImage(); // will save raw image if needed mNeedsCreateTexture = false; } @@ -1658,6 +1691,7 @@ void LLViewerFetchedTexture::processTextureStats() if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more { mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel); + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S32)mLoadedCallbackDesiredDiscardLevel); mFullyLoaded = false; } //setDebugText("fully loaded"); @@ -1707,6 +1741,7 @@ void LLViewerFetchedTexture::processTextureStats() log((F32)mFullHeight / mKnownDrawHeight) / log_2); mDesiredDiscardLevel = llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()); mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel); + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S32)mLoadedCallbackDesiredDiscardLevel); } mKnownDrawSizeChanged = false; @@ -2436,6 +2471,7 @@ bool LLViewerFetchedTexture::doLoadedCallbacks() if (mIsRawImageValid) { // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels. + current_raw_discard = mRawDiscardLevel; best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel); best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw current_aux_discard = llmin(current_aux_discard, best_aux_discard); @@ -2892,10 +2928,12 @@ void LLViewerLODTexture::processTextureStats() { // If the image has not been significantly visible in a while, we don't want it mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1)); + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S32)mLoadedCallbackDesiredDiscardLevel); } else if (!mFullWidth || !mFullHeight) { mDesiredDiscardLevel = getMaxDiscardLevel(); + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S32)mLoadedCallbackDesiredDiscardLevel); } else { @@ -2965,6 +3003,7 @@ void LLViewerLODTexture::processTextureStats() // stop requesting more mDesiredDiscardLevel = current_discard; } + mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S32)mLoadedCallbackDesiredDiscardLevel); } if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) @@ -3471,7 +3510,7 @@ void LLViewerMediaTexture::setPlaying(bool playing) { LLFace* facep = *iter; const LLTextureEntry* te = facep->getTextureEntry(); - if (te->getGLTFMaterial()) + if (te && te->getGLTFMaterial()) { // PBR material, switch emissive and basecolor switchTexture(LLRender::EMISSIVE_MAP, *iter); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 752cfb3884..489e5980d6 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1269,6 +1269,11 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) //update MIN_UPDATE_COUNT or 5% of other textures, whichever is greater update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/20); + if (LLViewerTexture::sDesiredDiscardBias > 1.f) + { + // we are over memory target, update more agresively + update_count = (S32)(update_count * LLViewerTexture::sDesiredDiscardBias); + } update_count = llmin(update_count, (U32) mUUIDMap.size()); { // copy entries out of UUID map to avoid iterator invalidation from deletion inside updateImageDecodeProiroty or updateFetch below @@ -1422,6 +1427,11 @@ bool LLViewerTextureList::createUploadFile(LLPointer<LLImageRaw> raw_image, raw_image->getComponents()); LLPointer<LLImageJ2C> compressedImage = LLViewerTextureList::convertToUploadFile(scale_image, max_image_dimentions); + if (compressedImage.isNull()) + { + LL_INFOS() << "Couldn't convert to j2c, file : " << out_filename << LL_ENDL; + return false; + } if (compressedImage->getWidth() < min_image_dimentions || compressedImage->getHeight() < min_image_dimentions) { std::string reason = llformat("Images below %d x %d pixels are not allowed. Actual size: %d x %dpx", @@ -1432,12 +1442,6 @@ bool LLViewerTextureList::createUploadFile(LLPointer<LLImageRaw> raw_image, compressedImage->setLastError(reason); return false; } - if (compressedImage.isNull()) - { - compressedImage->setLastError("Couldn't convert the image to jpeg2000."); - LL_INFOS() << "Couldn't convert to j2c, file : " << out_filename << LL_ENDL; - return false; - } if (!compressedImage->save(out_filename)) { compressedImage->setLastError("Couldn't create the jpeg2000 image for upload."); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 440eb427cc..8356affc63 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -269,9 +269,6 @@ static const F32 MIN_DISPLAY_SCALE = 0.75f; static const char KEY_MOUSELOOK = 'M'; -static LLCachedControl<std::string> sSnapshotBaseName(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot")); -static LLCachedControl<std::string> sSnapshotDir(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseDir", "")); - LLTrace::SampleStatHandle<> LLViewerWindow::sMouseVelocityStat("Mouse Velocity"); @@ -2023,6 +2020,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) std::string LLViewerWindow::getLastSnapshotDir() { + static LLCachedControl<std::string> sSnapshotDir(gSavedPerAccountSettings, "SnapshotBaseDir", ""); return sSnapshotDir; } @@ -3793,7 +3791,7 @@ void LLViewerWindow::updateLayout() { LLToolMgr* tool_mgr = LLToolMgr::getInstance(); LLTool* tool = tool_mgr->getCurrentTool(); - LLCachedControl<bool> freeze_time(gSavedSettings, "FreezeTime"); + static LLCachedControl<bool> freeze_time(gSavedSettings, "FreezeTime"); if (gFloaterTools != NULL && tool != NULL && tool != gToolNull @@ -4722,6 +4720,7 @@ void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picke // Get a base file location if needed. if (force_picker || !isSnapshotLocSet()) { + static LLCachedControl<std::string> sSnapshotBaseName(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot"); std::string proposed_name(sSnapshotBaseName); // getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in. @@ -4767,6 +4766,9 @@ void LLViewerWindow::onSelectionFailure(const snapshot_saved_signal_t::slot_type void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb) { + static LLCachedControl<std::string> sSnapshotBaseName(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot"); + static LLCachedControl<std::string> sSnapshotDir(gSavedPerAccountSettings, "SnapshotBaseDir", ""); + std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir(); if (lastSnapshotDir.empty()) { @@ -4915,8 +4917,8 @@ void LLViewerWindow::playSnapshotAnimAndSound() bool LLViewerWindow::isSnapshotLocSet() const { - std::string snapshot_dir = sSnapshotDir; - return !snapshot_dir.empty(); + static LLCachedControl<std::string> sSnapshotDir(gSavedPerAccountSettings, "SnapshotBaseDir", ""); + return !sSnapshotDir().empty(); } void LLViewerWindow::resetSnapshotLoc() const diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index ca76d93cd7..4a5f269c9f 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -102,14 +102,6 @@ namespace } }; -LLTerrainMaterials::LLTerrainMaterials() -{ - for (S32 i = 0; i < ASSET_COUNT; ++i) - { - mMaterialTexturesSet[i] = false; - } -} - LLTerrainMaterials::~LLTerrainMaterials() { unboost(); @@ -199,7 +191,6 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) LLPointer<LLFetchedGLTFMaterial>& mat = mDetailMaterials[asset]; mat = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id); mDetailRenderMaterials[asset] = nullptr; - mMaterialTexturesSet[asset] = false; } const LLGLTFMaterial* LLTerrainMaterials::getMaterialOverride(S32 asset) const @@ -262,11 +253,17 @@ bool LLTerrainMaterials::makeMaterialsReady(bool boost, bool strict) if (!material_asset_ready(mat)) { continue; } LLPointer<LLFetchedGLTFMaterial>& render_mat = mDetailRenderMaterials[i]; + // This will be mutated by materialTexturesReady, due to the way that + // function is implemented. + bool render_material_textures_set = bool(render_mat); if (!render_mat) { render_mat = new LLFetchedGLTFMaterial(); *render_mat = *mat; // This render_mat is effectively already loaded, because it gets its data from mat. + // However, its textures may not be loaded yet. + render_mat->materialBegin(); + render_mat->materialComplete(true); LLPointer<LLGLTFMaterial>& override_mat = mDetailMaterialOverrides[i]; if (override_mat) @@ -275,7 +272,8 @@ bool LLTerrainMaterials::makeMaterialsReady(bool boost, bool strict) } } - ready[i] = materialTexturesReady(render_mat, mMaterialTexturesSet[i], boost, strict); + ready[i] = materialTexturesReady(render_mat, render_material_textures_set, boost, strict); + llassert(render_material_textures_set); } #if 1 @@ -418,16 +416,6 @@ bool LLTerrainMaterials::materialTexturesReady(LLPointer<LLFetchedGLTFMaterial>& return true; } -// Boost the loading priority of every known texture in the material -// Return true when ready to use -// static -bool LLTerrainMaterials::makeMaterialReady(LLPointer<LLFetchedGLTFMaterial> &mat, bool &textures_set, bool boost, bool strict) -{ - if (!material_asset_ready(mat)) { return false; } - - return materialTexturesReady(mat, textures_set, boost, strict); -} - // static const LLUUID (&LLVLComposition::getDefaultTextures())[ASSET_COUNT] { diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h index 21fd484375..9574080b38 100644 --- a/indra/newview/llvlcomposition.h +++ b/indra/newview/llvlcomposition.h @@ -27,19 +27,17 @@ #ifndef LL_LLVLCOMPOSITION_H #define LL_LLVLCOMPOSITION_H +#include "llfetchedgltfmaterial.h" +#include "llimage.h" +#include "llpointer.h" +#include "llterrainpaintmap.h" #include "llviewerlayer.h" #include "llviewershadermgr.h" #include "llviewertexture.h" -#include "llpointer.h" -#include "llterrainpaintmap.h" - -#include "llimage.h" class LLSurface; class LLViewerFetchedTexture; -class LLGLTFMaterial; -class LLFetchedGLTFMaterial; class LLModifyRegion { @@ -53,7 +51,7 @@ class LLTerrainMaterials : public LLModifyRegion public: friend class LLDrawPoolTerrain; - LLTerrainMaterials(); + LLTerrainMaterials() {} virtual ~LLTerrainMaterials(); void apply(const LLModifyRegion& other); @@ -106,15 +104,15 @@ protected: static bool makeTextureReady(LLPointer<LLViewerFetchedTexture>& tex, bool boost); // strict = true -> all materials must be sufficiently loaded // strict = false -> at least one material must be loaded - static bool makeMaterialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost, bool strict); - // *NOTE: Prefer calling makeMaterialReady if mat is known to be LLFetchedGLTFMaterial static bool materialTexturesReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, bool boost, bool strict); LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT]; + // *NOTE: Unlike mDetailRenderMaterials, the textures in this are not + // guaranteed to be set or loaded after a true return from + // makeMaterialsReady. LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT]; LLPointer<LLGLTFMaterial> mDetailMaterialOverrides[ASSET_COUNT]; LLPointer<LLFetchedGLTFMaterial> mDetailRenderMaterials[ASSET_COUNT]; - bool mMaterialTexturesSet[ASSET_COUNT]; U32 mPaintType = TERRAIN_PAINT_TYPE_HEIGHTMAP_WITH_NOISE; LLPointer<LLViewerTexture> mPaintMap; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 8b7d284259..5f792a351c 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -683,12 +683,11 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mFullyLoaded(false), mPreviousFullyLoaded(false), mFullyLoadedInitialized(false), - mLastCloudAttachmentCount(0), + mLastCloudAttachmentCount(-1), mFullyLoadedFrameCounter(0), mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), mLoadedCallbacksPaused(false), mLoadedCallbackTextures(0), - mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar", false)), mLastRezzedStatus(-1), mIsEditingAppearance(false), mUseLocalAppearance(false), @@ -7740,6 +7739,64 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) } } +bool check_object_for_mesh_loading(LLViewerObject* objectp) +{ + if (!objectp || !objectp->getVolume()) + { + return false; + } + LLVolume* volp = objectp->getVolume(); + const LLUUID& mesh_id = volp->getParams().getSculptID(); + if (mesh_id.isNull()) + { + // No mesh nor skin info needed + return false; + } + + if (volp->isMeshAssetUnavaliable()) + { + // Mesh failed to load, do not expect it + return false; + } + + if (!objectp->mDrawable) + { + return false; + } + + LLVOVolume* pvobj = objectp->mDrawable->getVOVolume(); + if (pvobj) + { + if (!pvobj->isMesh()) + { + // Not a mesh + return false; + } + + if (!volp->isMeshAssetLoaded()) + { + // Waiting for mesh + return true; + } + + const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo(); + if (skin_data) + { + // Skin info present, done + return false; + } + + if (pvobj->isSkinInfoUnavaliable()) + { + // Load failed or info not present, don't expect it + return false; + } + } + + // object is not ready + return true; +} + bool LLVOAvatar::hasPendingAttachedMeshes() { for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); @@ -7754,62 +7811,20 @@ bool LLVOAvatar::hasPendingAttachedMeshes() ++attachment_iter) { LLViewerObject* objectp = attachment_iter->get(); - if (objectp) + if (objectp && !objectp->isDead()) { + if (check_object_for_mesh_loading(objectp)) + { + return true; + } LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); iter1 != child_list.end(); ++iter1) { LLViewerObject* objectchild = *iter1; - if (objectchild && objectchild->getVolume()) + if (check_object_for_mesh_loading(objectchild)) { - const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID(); - if (mesh_id.isNull()) - { - // No mesh nor skin info needed - continue; - } - - if (objectchild->getVolume()->isMeshAssetUnavaliable()) - { - // Mesh failed to load, do not expect it - continue; - } - - if (objectchild->mDrawable) - { - LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume(); - if (pvobj) - { - if (!pvobj->isMesh()) - { - // Not a mesh - continue; - } - - if (!objectchild->getVolume()->isMeshAssetLoaded()) - { - // Waiting for mesh - return true; - } - - const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo(); - if (skin_data) - { - // Skin info present, done - continue; - } - - if (pvobj->isSkinInfoUnavaliable()) - { - // Load failed or info not present, don't expect it - continue; - } - } - - // objectchild is not ready - return true; - } + return true; } } } @@ -8540,7 +8555,8 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading) bool LLVOAvatar::isFullyLoaded() const { - return (mRenderUnloadedAvatar || mFullyLoaded); + static LLCachedControl<bool> render_unloaded_avatars(gSavedSettings, "RenderUnloadedAvatar", false); + return (render_unloaded_avatars || mFullyLoaded); } bool LLVOAvatar::isTooComplex() const diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index d377ebad41..1e678c1a84 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -669,8 +669,6 @@ private: LLVector3 mLastAnimExtents[2]; LLVector3 mLastAnimBasePos; - LLCachedControl<bool> mRenderUnloadedAvatar; - //-------------------------------------------------------------------- // Wind rippling in clothes //-------------------------------------------------------------------- @@ -1015,7 +1013,7 @@ public: void startTyping() { mTyping = true; mTypingTimer.reset(); } void stopTyping() { mTyping = false; } private: - bool mVisibleChat; + bool mVisibleChat = false; //-------------------------------------------------------------------- // Lip synch morphs @@ -1197,7 +1195,7 @@ public: static F32 sGreyUpdateTime; // Last time stats were updated (to prevent multiple updates per frame) protected: S32 getUnbakedPixelAreaRank(); - bool mHasGrey; + bool mHasGrey = false; private: F32 mMinPixelArea; F32 mMaxPixelArea; diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 6d4f3fe356..c7e246b3bf 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -258,6 +258,7 @@ void LLWebRTCVoiceClient::cleanupSingleton() mNextSession->shutdownAllConnections(); } cleanUp(); + stopTimer(); sessionState::clearSessions(); } @@ -296,14 +297,13 @@ void LLWebRTCVoiceClient::cleanUp() mNeighboringRegions.clear(); sessionState::for_each(boost::bind(predShutdownSession, _1)); LL_DEBUGS("Voice") << "Exiting" << LL_ENDL; - stopTimer(); } void LLWebRTCVoiceClient::stopTimer() { if (mIsTimerActive) { - LLMuteList::instanceExists(); + if (LLMuteList::instanceExists()) { LLMuteList::getInstance()->removeObserver(this); } @@ -2507,7 +2507,9 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio if (!regionp || !regionp->capabilitiesReceived()) { LL_DEBUGS("Voice") << "no capabilities for voice provisioning; waiting " << LL_ENDL; - connection->setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + // fine, don't be polite and ask the janus server to break the connection. + // just fall through and drop the connection. + connection->setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); connection->mOutstandingRequests--; return; } @@ -2515,7 +2517,8 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio std::string url = regionp->getCapability("ProvisionVoiceAccountRequest"); if (url.empty()) { - connection->setVoiceConnectionState(VOICE_STATE_SESSION_RETRY); + // and go on to drop the connection here, too. + connection->setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); connection->mOutstandingRequests--; return; } @@ -2529,7 +2532,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio body["voice_server_type"] = WEBRTC_VOICE_SERVER_TYPE; LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter( - new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::breakVoiceConnection", + new LLCoreHttpUtil::HttpCoroutineAdapter("LLVoiceWebRTCAdHocConnection::breakVoiceConnectionCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID)); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); @@ -2543,8 +2546,11 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio connection->mOutstandingRequests--; - if (connection->getVoiceConnectionState() == VOICE_STATE_WAIT_FOR_EXIT) + if (connection->getVoiceConnectionState() == VOICE_STATE_WAIT_FOR_EXIT || + !(connection->getVoiceConnectionState() & VOICE_STATE_SESSION_STOPPING)) { + // drop the connection if we either somehow got set back to a running/starting state + // or we completed the call in the wait-for-exit state connection->setVoiceConnectionState(VOICE_STATE_SESSION_EXIT); } } @@ -2829,8 +2835,8 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() { mOutstandingRequests++; setVoiceConnectionState(VOICE_STATE_WAIT_FOR_EXIT); - LLCoros::instance().launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro", - boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this->shared_from_this())); + LLCoros::getInstance()->launch("LLVoiceWebRTCConnection::breakVoiceConnectionCoro", + boost::bind(&LLVoiceWebRTCConnection::breakVoiceConnectionCoro, this->shared_from_this())); } else { @@ -2843,17 +2849,18 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() break; case VOICE_STATE_SESSION_EXIT: + setVoiceConnectionState(VOICE_STATE_WAIT_FOR_CLOSE); + mOutstandingRequests++; + if (!LLWebRTCVoiceClient::isShuttingDown()) { - setVoiceConnectionState(VOICE_STATE_WAIT_FOR_CLOSE); - mOutstandingRequests++; - if (!LLWebRTCVoiceClient::isShuttingDown()) - { - mWebRTCPeerConnectionInterface->shutdownConnection(); - } - // else was already posted by llwebrtc::terminate(). - break; + mWebRTCPeerConnectionInterface->shutdownConnection(); + } + // else was already posted by llwebrtc::terminate(). + break; + case VOICE_STATE_WAIT_FOR_CLOSE: break; + case VOICE_STATE_CLOSED: if (!mShutDown) { @@ -2870,7 +2877,6 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() } } break; - } default: { @@ -3059,7 +3065,9 @@ void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface return; } - if (data_interface) + // OnDataChannelReady may be called multiple times in a single connection attempt + // so don't double-set the observer. + if (!mWebRTCDataInterface && data_interface) { mWebRTCDataInterface = data_interface; mWebRTCDataInterface->setDataObserver(this); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 43bb1c177c..e4dd5fead6 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -641,6 +641,15 @@ void LLVOVolume::animateTextures() if (!facep->mTextureMatrix) { facep->mTextureMatrix = new LLMatrix4(); + if (facep->getVirtualSize() > MIN_TEX_ANIM_SIZE) + { + // Fix the one edge case missed in + // LLVOVolume::updateTextureVirtualSize when the + // mTextureMatrix is not yet present + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + mDrawable->getSpatialGroup()->dirtyGeom(); + gPipeline.markRebuild(mDrawable->getSpatialGroup()); + } } LLMatrix4& tex_mat = *facep->mTextureMatrix; @@ -784,11 +793,29 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) for (S32 i = 0; i < num_faces; i++) { LLFace* face = mDrawable->getFace(i); - if (!face) continue; + if (!face || face->mExtents[0].equals3(face->mExtents[1])) continue; const LLTextureEntry *te = face->getTextureEntry(); - LLViewerTexture *imagep = face->getTexture(); - if (!imagep || !te || - face->mExtents[0].equals3(face->mExtents[1])) + if (!te) continue; + + LLViewerTexture *imagep = nullptr; + U32 ch_min; + U32 ch_max; + if (!te->getGLTFRenderMaterial()) + { + ch_min = LLRender::DIFFUSE_MAP; + ch_max = LLRender::SPECULAR_MAP; + } + else + { + ch_min = LLRender::BASECOLOR_MAP; + ch_max = LLRender::EMISSIVE_MAP; + } + for (U32 ch = ch_min; (!imagep && ch <= ch_max); ++ch) + { + // Get _a_ non-null texture if possible (usually diffuse/basecolor, but could be something else) + imagep = face->getTexture(ch); + } + if (!imagep) { continue; } @@ -814,12 +841,25 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) // if the face has gotten small enough to turn off texture animation and texture // animation is running, rebuild the render batch for this face to turn off // texture animation + // Do the opposite when the face gets big enough. + // If a face is animatable, it will always have non-null mTextureMatrix + // pointer defined after the first call to LLVOVolume::animateTextures, + // although the animation is not always turned on. if (face->mTextureMatrix != NULL) { - if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || - (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)) + if ((vsize > MIN_TEX_ANIM_SIZE) != (old_size > MIN_TEX_ANIM_SIZE)) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + // dirtyGeom+markRebuild tells the engine to call + // LLVolumeGeometryManager::rebuildGeom, which rebuilds the + // LLDrawInfo for the spatial group containing this LLFace, + // safely copying the mTextureMatrix from the LLFace the the + // LLDrawInfo. While it's not ideal to call it here, prims with + // animated faces get moved to a smaller partition to reduce + // side-effects of their updates (see shrinkWrap in + // LLVOVolume::animateTextures). + mDrawable->getSpatialGroup()->dirtyGeom(); + gPipeline.markRebuild(mDrawable->getSpatialGroup()); } } @@ -5396,7 +5436,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif - info->mMaterialID == mat_id && + info->mMaterialHash == mat_id && info->mFullbright == fullbright && info->mBump == bump && (!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different @@ -5455,11 +5495,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (gltf_mat) { // just remember the material ID, render pools will reference the GLTF material - draw_info->mMaterialID = mat_id; + draw_info->mMaterialHash = mat_id; } else if (mat) { - draw_info->mMaterialID = mat_id; + draw_info->mMaterialHash = mat_id; // We have a material. Update our draw info accordingly. @@ -5491,10 +5531,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } - // if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr - { //for alpha sorting - facep->setDrawInfo(draw_info); - } + // This backpointer is used by alpha sorting and avatar attachment + // accounting. + // To be safe, always populate the draw_info ptr. + facep->setDrawInfo(draw_info); if (index < FACE_DO_NOT_BATCH_TEXTURES) { //initialize texture list for texture batching @@ -6116,7 +6156,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLVertexBuffer::flushBuffers(); } - group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); + group->clearState(LLSpatialGroup::MESH_DIRTY); } } } diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 0f956d8350..5b24d46bb0 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -313,6 +313,8 @@ bool LLXMLRPCTransaction::Impl::process() if (mHasResponse && !mResponseParsed) { LLXMLNodePtr root; + bool strip_escaped_strings = LLXMLNode::sStripEscapedStrings; + LLXMLNode::sStripEscapedStrings = false; if (!LLXMLNode::parseBuffer(mResponseText.data(), mResponseText.size(), root, nullptr)) { @@ -329,6 +331,7 @@ bool LLXMLRPCTransaction::Impl::process() LL_WARNS() << "XMLRPC response parsing failed; request URI: " << mURI << LL_ENDL; } + LLXMLNode::sStripEscapedStrings = strip_escaped_strings; mResponseParsed = true; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0b4b98d674..1edbf584d6 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -828,8 +828,9 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY) mRT->deferredScreen.shareDepthBuffer(mRT->screen); - if (shadow_detail > 0 || ssao || RenderDepthOfField) - { //only need mRT->deferredLight for shadows OR ssao OR dof + static LLCachedControl<bool> render_cas(gSavedSettings, "RenderCAS", true); + if (shadow_detail > 0 || ssao || render_cas) + { //only need mRT->deferredLight for shadows OR ssao if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false; } else @@ -849,13 +850,18 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY) } } - if (RenderFSAAType > 0) + if (RenderFSAAType > 0 || RenderDepthOfField) { if (!mFXAAMap.allocate(resX, resY, GL_RGBA)) return false; if (RenderFSAAType == 2) { if (!mSMAABlendBuffer.allocate(resX, resY, GL_RGBA, false)) return false; } + else + { + mSMAABlendBuffer.release(); + } + } else { @@ -875,7 +881,8 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY) mSceneMap.release(); } - mPostMap.allocate(resX, resY, GL_RGBA16F); + mPostPingMap.allocate(resX, resY, GL_RGBA); + mPostPongMap.allocate(resX, resY, GL_RGBA); // used to scale down textures // See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown @@ -1133,7 +1140,8 @@ void LLPipeline::releaseGLBuffers() mSceneMap.release(); - mPostMap.release(); + mPostPingMap.release(); + mPostPongMap.release(); mFXAAMap.release(); @@ -3512,11 +3520,6 @@ void LLPipeline::postSort(LLCamera &camera) continue; } - if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY) && !gCubeSnapshot) - { // no way this group is going to be drawable without a rebuild - group->rebuildGeom(); - } - for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) { LLSpatialGroup::drawmap_elem_t &src_vec = j->second; @@ -6895,7 +6898,10 @@ static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex) { - dst->bindTarget(); + if (dst) + { + dst->bindTarget(); + } gDeferredBufferVisualProgram.bind(); gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex); @@ -6908,7 +6914,10 @@ void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); gDeferredBufferVisualProgram.unbind(); - dst->flush(); + if (dst) + { + dst->flush(); + } } void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst) @@ -7047,13 +7056,14 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool extern LLPointer<LLImageGL> gEXRImage; -void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) +void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst, bool gamma_correct/* = true*/) { - dst->bindTarget(); // gamma correct lighting { LL_PROFILE_GPU_ZONE("tonemap"); + dst->bindTarget(); + static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false); LLGLDepthTest depth(GL_FALSE, GL_FALSE); @@ -7064,18 +7074,26 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools->isAvailable()); - LLGLSLShader& shader = no_post ? gNoPostTonemapProgram : gDeferredPostTonemapProgram; + bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable()); + LLGLSLShader* shader = nullptr; + if (gamma_correct) + { + shader = no_post ? &gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping) + psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? &gLegacyPostGammaCorrectProgram : + &gDeferredPostGammaCorrectProgram; + } + else + { + shader = (psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || no_post) ? &gNoPostTonemapProgram : &gDeferredPostTonemapProgram; + } - shader.bind(); + shader->bind(); S32 channel = 0; - shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT); - - shader.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap); - - shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); + shader->bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT); + shader->bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f); @@ -7085,54 +7103,26 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) static LLStaticHashedString tonemap_mix("tonemap_mix"); static LLStaticHashedString tonemap_type("tonemap_type"); - shader.uniform1f(s_exposure, e); + shader->uniform1f(s_exposure, e); static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U); - shader.uniform1i(tonemap_type, tonemap_type_setting); + shader->uniform1i(tonemap_type, tonemap_type_setting); static LLCachedControl<F32> tonemap_mix_setting(gSavedSettings, "RenderTonemapMix", 1.f); - shader.uniform1f(tonemap_mix, tonemap_mix_setting); + shader->uniform1f(tonemap_mix, tonemap_mix_setting); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); gGL.getTexUnit(channel)->unbind(src->getUsage()); - shader.unbind(); - } - dst->flush(); -} - -void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) -{ - dst->bindTarget(); - // gamma correct lighting - { - LL_PROFILE_GPU_ZONE("gamma correct"); - - LLGLDepthTest depth(GL_FALSE, GL_FALSE); - - static LLCachedControl<bool> buildNoPost(gSavedSettings, "RenderDisablePostProcessing", false); - static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); - - LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLGLSLShader& shader = psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram : - gDeferredPostGammaCorrectProgram; - - shader.bind(); - shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT); - shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); - - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + shader->unbind(); - shader.unbind(); + dst->flush(); } - dst->flush(); } void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst) { - if (RenderScreenSpaceReflections && !gCubeSnapshot) { LL_PROFILE_GPU_ZONE("ssr copy"); @@ -7159,9 +7149,9 @@ void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* void LLPipeline::generateGlow(LLRenderTarget* src) { + LL_PROFILE_GPU_ZONE("glow generate"); if (sRenderGlow) { - LL_PROFILE_GPU_ZONE("glow"); mGlow[2].bindTarget(); mGlow[2].clear(); @@ -7270,13 +7260,12 @@ void LLPipeline::generateGlow(LLRenderTarget* src) void LLPipeline::applyCAS(LLRenderTarget* src, LLRenderTarget* dst) { static LLCachedControl<F32> cas_sharpness(gSavedSettings, "RenderCASSharpness", 0.4f); - if (cas_sharpness == 0.0f || !gCASProgram.isComplete()) - { - gPipeline.copyRenderTarget(src, dst); - return; - } + static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true); - LLGLSLShader* sharpen_shader = &gCASProgram; + LL_PROFILE_GPU_ZONE("cas"); + + LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); + LLGLSLShader* sharpen_shader = psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? &gCASLegacyGammaProgram : &gCASProgram; // Bind setup: dst->bindTarget(); @@ -7312,89 +7301,85 @@ void LLPipeline::applyCAS(LLRenderTarget* src, LLRenderTarget* dst) dst->flush(); } -void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst) +void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst, bool combine_glow) { - { - llassert(!gCubeSnapshot); - bool multisample = RenderFSAAType == 1 && mFXAAMap.isComplete(); - LLGLSLShader* shader = &gGlowCombineProgram; + llassert(!gCubeSnapshot); + LLGLSLShader* shader = &gGlowCombineProgram; - // Present everything. - if (multisample) - { - LL_PROFILE_GPU_ZONE("aa"); - S32 width = dst->getWidth(); - S32 height = dst->getHeight(); + LL_PROFILE_GPU_ZONE("FXAA"); + S32 width = src->getWidth(); + S32 height = src->getHeight(); - // bake out texture2D with RGBL for FXAA shader - mFXAAMap.bindTarget(); - mFXAAMap.invalidate(GL_COLOR_BUFFER_BIT); + // bake out texture2D with RGBL for FXAA shader + mFXAAMap.bindTarget(); + mFXAAMap.invalidate(GL_COLOR_BUFFER_BIT); - shader = &gGlowCombineFXAAProgram; - shader->bind(); + shader = combine_glow ? &gGlowCombineFXAAProgram : &gFXAALumaGenProgram; + shader->bind(); - S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); - if (channel > -1) - { - src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); + if (channel > -1) + { + src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } + shader->bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); - shader->unbind(); + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); + shader->unbind(); - mFXAAMap.flush(); + mFXAAMap.flush(); - dst->bindTarget(); + if (dst) + { + dst->bindTarget(); + } - static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); - U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); + static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); + U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); - shader = &gFXAAProgram[fsaa_quality]; - shader->bind(); + shader = &gFXAAProgram[fsaa_quality]; + shader->bind(); - channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAAMap.getUsage()); - if (channel > -1) - { - mFXAAMap.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); - } + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAAMap.getUsage()); + if (channel > -1) + { + mFXAAMap.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); + } - gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; - gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; - gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); - gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); - glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - F32 scale_x = (F32)width / mFXAAMap.getWidth(); - F32 scale_y = (F32)height / mFXAAMap.getHeight(); - shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); - shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, - 0.5f / width * scale_x, 0.5f / height * scale_y); - shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, - 2.f / width * scale_x, 2.f / height * scale_y); + F32 scale_x = (F32)width / mFXAAMap.getWidth(); + F32 scale_y = (F32)height / mFXAAMap.getHeight(); + shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); + shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, + 0.5f / width * scale_x, 0.5f / height * scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, + 2.f / width * scale_x, 2.f / height * scale_y); - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH); - gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true); + { + LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); + shader->bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + } - shader->unbind(); - dst->flush(); - } - else { - copyRenderTarget(src, dst); - } + shader->unbind(); + if (dst) + { + dst->flush(); } } @@ -7406,7 +7391,7 @@ void LLPipeline::generateSMAABuffers(LLRenderTarget* src) // Present everything. if (multisample) { - LL_PROFILE_GPU_ZONE("aa"); + LL_PROFILE_GPU_ZONE("SMAA Edge"); static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); @@ -7517,72 +7502,73 @@ void LLPipeline::generateSMAABuffers(LLRenderTarget* src) } } -void LLPipeline::applySMAA(LLRenderTarget* src, LLRenderTarget* dst) +void LLPipeline::applySMAA(LLRenderTarget* src, LLRenderTarget* dst, bool combine_glow) { llassert(!gCubeSnapshot); - bool multisample = RenderFSAAType == 2 && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); - // Present everything. - if (multisample) - { - LL_PROFILE_GPU_ZONE("aa"); - static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); - U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); + LL_PROFILE_GPU_ZONE("SMAA"); + static LLCachedControl<U32> aa_quality(gSavedSettings, "RenderFSAASamples", 0U); + U32 fsaa_quality = std::clamp(aa_quality(), 0U, 3U); - S32 width = src->getWidth(); - S32 height = src->getHeight(); + S32 width = src->getWidth(); + S32 height = src->getHeight(); - float rt_metrics[] = { 1.f / width, 1.f / height, (float)width, (float)height }; + float rt_metrics[] = { 1.f / width, 1.f / height, (float)width, (float)height }; - LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDepthTest depth(GL_FALSE, GL_FALSE); - static LLCachedControl<bool> use_sample(gSavedSettings, "RenderSMAAUseSample", false); - //static LLCachedControl<bool> use_stencil(gSavedSettings, "RenderSMAAUseStencil", true); + static LLCachedControl<bool> use_sample(gSavedSettings, "RenderSMAAUseSample", false); + //static LLCachedControl<bool> use_stencil(gSavedSettings, "RenderSMAAUseStencil", true); + { + //LLGLDisable stencil(GL_STENCIL_TEST); + + // Bind setup: + LLGLSLShader& blend_shader = combine_glow ? gSMAANeighborhoodBlendGlowCombineProgram[fsaa_quality] + : gSMAANeighborhoodBlendProgram[fsaa_quality]; + + if(dst) { - //LLGLDisable stencil(GL_STENCIL_TEST); + dst->bindTarget(); + dst->invalidate(GL_COLOR_BUFFER_BIT); + } - // Bind setup: - LLRenderTarget* bound_target = dst; - LLGLSLShader& blend_shader = gSMAANeighborhoodBlendProgram[fsaa_quality]; + blend_shader.bind(); + blend_shader.uniform4fv(sSmaaRTMetrics, 1, rt_metrics); - bound_target->bindTarget(); - bound_target->invalidate(GL_COLOR_BUFFER_BIT); + S32 diffuse_channel = blend_shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); + if(diffuse_channel > -1) + { + src->bindTexture(0, diffuse_channel, LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + } - blend_shader.bind(); - blend_shader.uniform4fv(sSmaaRTMetrics, 1, rt_metrics); + S32 blend_channel = blend_shader.enableTexture(LLShaderMgr::SMAA_BLEND_TEX); + if (blend_channel > -1) + { + mSMAABlendBuffer.bindTexture(0, blend_channel, LLTexUnit::TFO_BILINEAR); + } - S32 diffuse_channel = blend_shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE); - if(diffuse_channel > -1) - { - src->bindTexture(0, diffuse_channel, LLTexUnit::TFO_BILINEAR); - gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); - } + blend_shader.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); - S32 blend_channel = blend_shader.enableTexture(LLShaderMgr::SMAA_BLEND_TEX); - if (blend_channel > -1) - { - mSMAABlendBuffer.bindTexture(0, blend_channel, LLTexUnit::TFO_BILINEAR); - } + blend_shader.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + blend_shader.unbind(); + gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(blend_channel)->unbindFast(LLTexUnit::TT_TEXTURE); - bound_target->flush(); - blend_shader.unbind(); - gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(blend_channel)->unbindFast(LLTexUnit::TT_TEXTURE); + if (dst) + { + dst->flush(); } } - else - { - copyRenderTarget(src, dst); - } } void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) { - LL_PROFILE_GPU_ZONE("copyRenderTarget"); dst->bindTarget(); @@ -7603,218 +7589,221 @@ void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst) void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst) { - // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer. - - dst->bindTarget(); + LL_PROFILE_GPU_ZONE("glow combine"); + // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer. + if (dst) { + dst->bindTarget(); + } + { gGlowCombineProgram.bind(); gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src); gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); + gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } - dst->flush(); + if (dst) + { + dst->flush(); + } } void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) { - { - bool dof_enabled = - (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && - RenderDepthOfField && - !gCubeSnapshot; - - gViewerWindow->setup3DViewport(); + LL_PROFILE_GPU_ZONE("dof"); + gViewerWindow->setup3DViewport(); - if (dof_enabled) - { - LL_PROFILE_GPU_ZONE("dof"); - LLGLDisable blend(GL_BLEND); - - // depth of field focal plane calculations - static F32 current_distance = 16.f; - static F32 start_distance = 16.f; - static F32 transition_time = 1.f; + LLGLDisable blend(GL_BLEND); - LLVector3 focus_point; + // depth of field focal plane calculations + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; - LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); - if (obj && obj->mDrawable && obj->isSelected()) - { // focus on selected media object - S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); - if (obj && obj->mDrawable) - { - LLFace* face = obj->mDrawable->getFace(face_idx); - if (face) - { - focus_point = face->getPositionAgent(); - } - } - } + LLVector3 focus_point; - if (focus_point.isExactlyZero()) + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { // focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) { - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { // focus on point under cursor - focus_point.set(gDebugRaycastIntersection.getF32ptr()); - } - else if (gAgentCamera.cameraMouselook()) - { // focus on point under mouselook crosshairs - LLVector4a result; - result.clear(); + focus_point = face->getPositionAgent(); + } + } + } - gViewerWindow->cursorIntersect(-1, -1, 512.f, nullptr, -1, false, false, true, true, nullptr, nullptr, nullptr, &result); + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { // focus on point under cursor + focus_point.set(gDebugRaycastIntersection.getF32ptr()); + } + else if (gAgentCamera.cameraMouselook()) + { // focus on point under mouselook crosshairs + LLVector4a result; + result.clear(); - focus_point.set(result.getF32ptr()); - } - else - { - // focus on alt-zoom target - LLViewerRegion* region = gAgent.getRegion(); - if (region) - { - focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); - } - } - } + gViewerWindow->cursorIntersect(-1, -1, 512.f, nullptr, -1, false, false, true, true, nullptr, nullptr, nullptr, &result); - LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); - F32 target_distance = 16.f; - if (!focus_point.isExactlyZero()) + focus_point.set(result.getF32ptr()); + } + else + { + // focus on alt-zoom target + LLViewerRegion* region = gAgent.getRegion(); + if (region) { - target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); + focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); } + } + } - if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) - { // large shift happened, interpolate smoothly to new target distance - transition_time = 0.f; - start_distance = current_distance; - } - else if (transition_time < 1.f) - { // currently in a transition, continue interpolating - transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); - transition_time = llmin(transition_time, 1.f); + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); + } - F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; - current_distance = start_distance + (target_distance - start_distance) * t; - } - else - { // small or no change, just snap to target distance - current_distance = target_distance; - } + if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) + { // large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { // currently in a transition, continue interpolating + transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); + transition_time = llmin(transition_time, 1.f); - // convert to mm - F32 subject_distance = current_distance * 1000.f; - F32 fnumber = CameraFNumber; - F32 default_focal_length = CameraFocalLength; + F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; + current_distance = start_distance + (target_distance - start_distance) * t; + } + else + { // small or no change, just snap to target distance + current_distance = target_distance; + } - F32 fov = LLViewerCamera::getInstance()->getView(); + // convert to mm + F32 subject_distance = current_distance * 1000.f; + F32 fnumber = CameraFNumber; + F32 default_focal_length = CameraFocalLength; - const F32 default_fov = CameraFieldOfView * F_PI / 180.f; + F32 fov = LLViewerCamera::getInstance()->getView(); - // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); + const F32 default_fov = CameraFieldOfView * F_PI / 180.f; - F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); + // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); - F32 focal_length = dv / (2 * tanf(fov / 2.f)); + F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); - // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); + F32 focal_length = dv / (2 * tanf(fov / 2.f)); - // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) - // where N = fnumber - // s2 = dot distance - // s1 = subject distance - // f = focal length - // + // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); - F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); - blur_constant /= 1000.f; // convert to meters for shader - F32 magnification = focal_length / (subject_distance - focal_length); + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // - { // build diffuse+bloom+CoF - mRT->deferredLight.bindTarget(); + F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); + blur_constant /= 1000.f; // convert to meters for shader + F32 magnification = focal_length / (subject_distance - focal_length); - gDeferredCoFProgram.bind(); + { // build diffuse+bloom+CoF + mFXAAMap.bindTarget(); - gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); - gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); + gDeferredCoFProgram.bind(); - gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)dst->getWidth(), (GLfloat)dst->getHeight()); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); + gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - gDeferredCoFProgram.unbind(); - mRT->deferredLight.flush(); - } + gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)mFXAAMap.getWidth(), (GLfloat)mFXAAMap.getHeight()); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]); - U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); - U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gDeferredCoFProgram.unbind(); + mFXAAMap.flush(); + } - { // perform DoF sampling at half-res (preserve alpha channel) - src->bindTarget(); - glViewport(0, 0, dof_width, dof_height); + U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); + U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); - gGL.setColorMask(true, false); + { // perform DoF sampling at half-res (preserve alpha channel) + src->bindTarget(); + glViewport(0, 0, dof_width, dof_height); - gDeferredPostProgram.bind(); - gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT); + gGL.setColorMask(true, false); - gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)dst->getWidth(), (GLfloat)dst->getHeight()); - gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredPostProgram.bind(); + gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mFXAAMap, LLTexUnit::TFO_POINT); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); + gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - gDeferredPostProgram.unbind(); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - src->flush(); - gGL.setColorMask(true, true); - } + gDeferredPostProgram.unbind(); - { // combine result based on alpha + src->flush(); + gGL.setColorMask(true, true); + } - dst->bindTarget(); - glViewport(0, 0, dst->getWidth(), dst->getHeight()); + { // combine result based on alpha - gDeferredDoFCombineProgram.bind(); - gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); - gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT); + if(dst) + { + dst->bindTarget(); + } + glViewport(0, 0, mFXAAMap.getWidth(), mFXAAMap.getHeight()); - gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)dst->getWidth(), (GLfloat)dst->getHeight()); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth()); - gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight()); + gDeferredDoFCombineProgram.bind(); + gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT); + gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mFXAAMap, LLTexUnit::TFO_POINT); + gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); + gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)src->getWidth(), (GLfloat)src->getHeight()); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth()); + gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight()); - gDeferredDoFCombineProgram.unbind(); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - dst->flush(); - } - } - else + gDeferredDoFCombineProgram.unbind(); + + if (dst) { - copyRenderTarget(src, dst); + dst->flush(); } } } void LLPipeline::renderFinalize() { + // Ensure changes here are propogated to relevant portions of LLGLTFPreviewTexture::render() + llassert(!gCubeSnapshot); LLVertexBuffer::unbind(); LLGLState::checkStates(); @@ -7840,21 +7829,26 @@ void LLPipeline::renderFinalize() generateExposure(&mLuminanceMap, &mExposureMap); - tonemap(&mRT->screen, &mPostMap); - - applyCAS(&mPostMap, &mRT->screen); + LLRenderTarget* src = &mPostPingMap; + LLRenderTarget* dest = &mPostPongMap; - generateSMAABuffers(&mRT->screen); + static LLCachedControl<bool> render_cas(gSavedSettings, "RenderCAS", true); + if (render_cas && gCASProgram.isComplete()) + { + tonemap(&mRT->screen, &mRT->deferredLight, false); // Must output to 16F buffer when passing to CAS or banding occurs - gammaCorrect(&mRT->screen, &mPostMap); + applyCAS(&mRT->deferredLight, dest); // Gamma corrects after sharpening + std::swap(src, dest); + } + else + { + tonemap(&mRT->screen, dest); + std::swap(src, dest); + } LLVertexBuffer::unbind(); - applySMAA(&mPostMap, &mRT->screen); - - generateGlow(&mRT->screen); - - combineGlow(&mRT->screen, &mPostMap); + generateGlow(src); gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; @@ -7862,13 +7856,30 @@ void LLPipeline::renderFinalize() gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - renderDoF(&mPostMap, &mRT->screen); + bool smaa_enabled = RenderFSAAType == 2 && mFXAAMap.isComplete() && mSMAABlendBuffer.isComplete(); + bool fxaa_enabled = RenderFSAAType == 1 && mFXAAMap.isComplete(); + bool dof_enabled = RenderDepthOfField && + (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()); + if(dof_enabled) // DoF Combines Glow + { + LLRenderTarget* dof_dest = (smaa_enabled || fxaa_enabled) ? dest : nullptr; // render to screen if no AA enabled + renderDoF(src, dof_dest); + std::swap(src, dof_dest); + } - LLRenderTarget* finalBuffer = &mRT->screen; - if (RenderFSAAType == 1) + // Render to screen + if (smaa_enabled) { - applyFXAA(&mRT->screen, &mPostMap); - finalBuffer = &mPostMap; + generateSMAABuffers(src); + applySMAA(src, nullptr, !dof_enabled); + } + else if (fxaa_enabled) + { + applyFXAA(src, nullptr, !dof_enabled); + } + else if (!dof_enabled) + { + combineGlow(src, nullptr); } if (RenderBufferVisualization > -1) @@ -7879,16 +7890,16 @@ void LLPipeline::renderFinalize() case 1: case 2: case 3: - visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization); + visualizeBuffers(&mRT->deferredScreen, nullptr, RenderBufferVisualization); break; case 4: - visualizeBuffers(&mLuminanceMap, finalBuffer, 0); + visualizeBuffers(&mLuminanceMap, nullptr, 0); break; case 5: { if (RenderFSAAType > 0) { - visualizeBuffers(&mFXAAMap, finalBuffer, 0); + visualizeBuffers(&mFXAAMap, nullptr, 0); } break; } @@ -7896,7 +7907,7 @@ void LLPipeline::renderFinalize() { if (RenderFSAAType == 2) { - visualizeBuffers(&mSMAABlendBuffer, finalBuffer, 0); + visualizeBuffers(&mSMAABlendBuffer, nullptr, 0); } break; } @@ -7905,24 +7916,6 @@ void LLPipeline::renderFinalize() } } - // Present the screen target. - - gDeferredPostNoDoFNoiseProgram.bind(); // Add noise as part of final render to screen pass to avoid damaging other post effects - - // Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems. - gDeferredPostNoDoFNoiseProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer); - gDeferredPostNoDoFNoiseProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); - - gDeferredPostNoDoFNoiseProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)finalBuffer->getWidth(), (GLfloat)finalBuffer->getHeight()); - - { - LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); - mScreenTriangleVB->setBuffer(); - mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - gDeferredPostNoDoFNoiseProgram.unbind(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c69ca863e7..309665f80a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -155,13 +155,12 @@ public: void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst); void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst); void generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool use_history = true); - void tonemap(LLRenderTarget* src, LLRenderTarget* dst); - void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst); + void tonemap(LLRenderTarget* src, LLRenderTarget* dst, bool gamma_correct = true); void generateGlow(LLRenderTarget* src); void applyCAS(LLRenderTarget* src, LLRenderTarget* dst); - void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst); + void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst, bool combine_glow); void generateSMAABuffers(LLRenderTarget* src); - void applySMAA(LLRenderTarget* src, LLRenderTarget* dst); + void applySMAA(LLRenderTarget* src, LLRenderTarget* dst, bool combine_glow); void renderDoF(LLRenderTarget* src, LLRenderTarget* dst); void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst); void combineGlow(LLRenderTarget* src, LLRenderTarget* dst); @@ -337,8 +336,6 @@ public: // should be called just before rendering pre-water alpha objects void doWaterHaze(); - void postDeferredGammaCorrect(LLRenderTarget* screen_target); - void generateSunShadow(LLCamera& camera); LLRenderTarget* getSunShadowTarget(U32 i); LLRenderTarget* getSpotShadowTarget(U32 i); @@ -725,7 +722,8 @@ public: LLRenderTarget mLastExposure; // tonemapped and gamma corrected render ready for post - LLRenderTarget mPostMap; + LLRenderTarget mPostPingMap; + LLRenderTarget mPostPongMap; // FXAA helper target LLRenderTarget mFXAAMap; diff --git a/indra/newview/scripts/lua/frame_profile.lua b/indra/newview/scripts/lua/frame_profile.lua index 3c6353ff68..4d0874f55e 100644 --- a/indra/newview/scripts/lua/frame_profile.lua +++ b/indra/newview/scripts/lua/frame_profile.lua @@ -4,11 +4,13 @@ LLAgent = require 'LLAgent' startup = require 'startup' Timer = (require 'timers').Timer UI = require 'UI' +teleport_util = require('teleport_util') startup.wait('STATE_STARTED') -- teleport to http://maps.secondlife.com/secondlife/Bug%20Island/220/224/27 print(LLAgent.teleport{regionname='Bug Island', x=220, y=224, z=27}) +--teleport_util.wait() Timer(10, 'wait') LLAgent.setCamera{camera_pos={220, 224, 26}, camera_locked=true, focus_pos ={228, 232, 26}, focus_locked=true} diff --git a/indra/newview/scripts/lua/require/teleport_util.lua b/indra/newview/scripts/lua/require/teleport_util.lua new file mode 100644 index 0000000000..8a46768e54 --- /dev/null +++ b/indra/newview/scripts/lua/require/teleport_util.lua @@ -0,0 +1,28 @@ +local leap = require 'leap' + +local teleport_util = {} + +local teleport_pump = 'LLTeleport' +local waitfor = leap.WaitFor(0, teleport_pump) +function waitfor:filter(pump, data) + if pump == self.name then + return data + end +end + +function waitfor:process(data) + teleport_util._success = data.success + leap.WaitFor.process(self, data) +end + +leap.request(leap.cmdpump(), + {op='listen', source=teleport_pump, listener='teleport.lua', tweak=true}) + +function teleport_util.wait() + while teleport_util._success == nil do + local item = waitfor:wait() + end + return teleport_util._success +end + +return teleport_util diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 73ea0f548e..610cffb84a 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -821,7 +821,7 @@ layout="topleft" left="420" min_val="0.5" - max_val="1.5" + max_val="4.0" name="RenderExposure" show_text="true" top_delta="24" @@ -924,6 +924,19 @@ </combo_box> <!-- End of mirror settings --> <!-- Sharpening Settings --> + <check_box + control_name="RenderCAS" + height="16" + initial_value="false" + label="Sharpening" + layout="topleft" + left="420" + name="Sharpening" + top_delta="24" + width="240"> + <check_box.commit_callback + function="Pref.RenderOptionUpdate" /> + </check_box> <slider control_name="RenderCASSharpness" decimal_digits="1" @@ -931,7 +944,7 @@ height="16" increment="0.1" initial_value="160" - label="Sharpening:" + label="Sharpening Strength:" label_width="145" layout="topleft" left="420" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 053eed6c00..1d468f58b3 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9623,6 +9623,22 @@ Are you sure you want to leave this call? <notification icon="alertmodal.tga" + name="ConfirmLeaveAdhoc" + type="alertmodal"> +Are you sure you want to leave this conference chat? + <tag>confirm</tag> + <tag>voice</tag> + <usetemplate + ignoretext="Confirm before I leave conference chat" + name="okcancelignore" + notext="No" + yestext="Yes"> + <unique/> + </usetemplate> + </notification> + + <notification + icon="alertmodal.tga" name="ConfirmMuteAll" type="alert"> You have selected to mute all participants in a group call. @@ -10374,6 +10390,14 @@ You are now the owner of object [OBJECT_NAME] <notification icon="alertmodal.tga" + name="NowOwnObjectInv" + type="notify"> + <tag>fail</tag> +You are now the owner of object [OBJECT_NAME] and it has been placed in your inventory. + </notification> + + <notification + icon="alertmodal.tga" name="CantRezOnLand" type="notify"> <tag>fail</tag> @@ -12629,4 +12653,34 @@ are wearing now. yestext="OK"/> </notification> + <notification + icon="notify.tga" + name="TextureDiscardBackgrounded" + type="notify"> + <unique> + <context>DELAY</context> + </unique> + To improve system performance, [SECOND_LIFE] has reduced texture memory usage after being in the background for [DELAY] seconds. It may take some time for texture image quality to return to normal. + <usetemplate + ignoretext="Ask me about background texture memory usage and recovery" + name="okcancelignore" + yestext="OK" + notext="Disable"/> + </notification> + + <notification + icon="notify.tga" + name="TextureDiscardMinimized" + type="notify"> + <unique> + <context>DELAY</context> + </unique> + To improve system performance, [SECOND_LIFE] has reduced texture memory usage after being minimized for [DELAY] seconds. It may take some time for texture image quality to return to normal. + <usetemplate + ignoretext="Ask me about minimized texture memory usage and recovery" + name="okcancelignore" + yestext="OK" + notext="Disable"/> + </notification> + </notifications> diff --git a/indra/test/lltut.h b/indra/test/lltut.h index 986bdd0619..1e380a3f5e 100644 --- a/indra/test/lltut.h +++ b/indra/test/lltut.h @@ -128,7 +128,7 @@ namespace tut inline void ensure_memory_matches(const void* actual, U32 actual_len, const void* expected,U32 expected_len) { - ensure_memory_matches(NULL, actual, actual_len, expected, expected_len); + ensure_memory_matches("", actual, actual_len, expected, expected_len); } template <class T,class Q> |