From c950cb3b49e1810adec0b7f7a9afadce71ce49a7 Mon Sep 17 00:00:00 2001 From: Rye Date: Tue, 14 Oct 2025 05:21:10 -0400 Subject: Remove dead LLPostProcess code with deprecated opengl usages Signed-off-by: Rye --- indra/newview/llappviewer.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index bfd8b1dcc7..b63e7c66b5 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -180,7 +180,6 @@ #include "lltracker.h" #include "llviewerparcelmgr.h" #include "llworldmapview.h" -#include "llpostprocess.h" #include "lldebugview.h" #include "llconsole.h" @@ -1879,8 +1878,6 @@ bool LLAppViewer::cleanup() SUBSYSTEM_CLEANUP(LLAvatarAppearance); - SUBSYSTEM_CLEANUP(LLPostProcess); - LLTracker::cleanupInstance(); // *FIX: This is handled in LLAppViewerWin32::cleanup(). -- cgit v1.3 From 579d8fbf82b622b6e071cf8fbc5770238644eb85 Mon Sep 17 00:00:00 2001 From: Rye Date: Thu, 23 Oct 2025 02:16:20 -0400 Subject: CMake changes for linux64 support including code from archive/develop Restore changes for GLIB based dbus support from archive/develop Signed-off-by: Rye --- .gitignore | 4 +- autobuild.xml | 358 +++++++-------------- indra/cmake/00-COMPILE-LINK-RUN.txt | 4 +- indra/cmake/00-Common.cmake | 60 ++-- indra/cmake/Boost.cmake | 165 ++++------ indra/cmake/CEFPlugin.cmake | 11 +- indra/cmake/CMakeLists.txt | 8 +- indra/cmake/ConfigurePkgConfig.cmake | 74 ----- indra/cmake/Copy3rdPartyLibs.cmake | 15 +- indra/cmake/DBusGlib.cmake | 14 - indra/cmake/Discord.cmake | 23 +- indra/cmake/FreeType.cmake | 4 +- indra/cmake/Havok.cmake | 37 ++- indra/cmake/JPEG.cmake | 3 + indra/cmake/LLKDU.cmake | 18 +- indra/cmake/LLWindow.cmake | 16 +- indra/cmake/NDOF.cmake | 7 +- indra/cmake/OPENAL.cmake | 2 + indra/cmake/PNG.cmake | 4 +- indra/cmake/Prebuilt.cmake | 5 +- indra/cmake/Python.cmake | 2 +- indra/cmake/SDL3.cmake | 19 ++ indra/cmake/UI.cmake | 36 +-- indra/cmake/Variables.cmake | 64 ++-- indra/cmake/ViewerMiscLibs.cmake | 7 +- indra/cmake/ZLIBNG.cmake | 1 + indra/cmake/bugsplat.cmake | 14 +- indra/llappearance/CMakeLists.txt | 3 +- indra/llrender/CMakeLists.txt | 10 +- indra/media_plugins/CMakeLists.txt | 16 +- indra/newview/CMakeLists.txt | 36 ++- indra/newview/llappviewer.cpp | 4 - indra/newview/llappviewerlinux.cpp | 267 +++++++-------- indra/newview/llappviewerlinux.h | 28 -- indra/newview/llappviewerlinux_api.h | 143 -------- indra/newview/llappviewerlinux_api.xml | 14 - indra/newview/llappviewerlinux_api_dbus.cpp | 126 -------- indra/newview/llappviewerlinux_api_dbus.h | 44 --- .../newview/llappviewerlinux_api_dbus_syms_raw.inc | 9 - 39 files changed, 563 insertions(+), 1112 deletions(-) delete mode 100644 indra/cmake/ConfigurePkgConfig.cmake delete mode 100644 indra/cmake/DBusGlib.cmake create mode 100644 indra/cmake/SDL3.cmake delete mode 100644 indra/newview/llappviewerlinux_api.h delete mode 100644 indra/newview/llappviewerlinux_api.xml delete mode 100644 indra/newview/llappviewerlinux_api_dbus.cpp delete mode 100644 indra/newview/llappviewerlinux_api_dbus.h delete mode 100644 indra/newview/llappviewerlinux_api_dbus_syms_raw.inc (limited to 'indra/newview/llappviewer.cpp') diff --git a/.gitignore b/.gitignore index c4accf37b5..a784d6e7d4 100755 --- a/.gitignore +++ b/.gitignore @@ -17,11 +17,11 @@ *~ # Specific paths and/or names +.venv CMakeCache.txt cmake_install.cmake LICENSES -build-darwin-* -build-linux-* +build-* debian/files debian/secondlife-appearance-utility* debian/secondlife-viewer* diff --git a/autobuild.xml b/autobuild.xml index ea46495671..bbd75d9e5a 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -270,11 +270,11 @@ archive hash - d5fb3832a338bbe4891b823c64fdb4806706568e + e21e7755fe740d5ed30bd29441170449a57caa8b hash_algorithm sha1 url - https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-darwin64-d7afe27.tar.zst + https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-cb8785a/cubemaptoequirectangular-1.1.0-darwin64-cb8785a.tar.zst name darwin64 @@ -284,11 +284,11 @@ archive hash - 77c53daf558f51aec6e9f4bd9e930a103630ee7d + aea0bed0f953a9371b9091f09230b41597f891f7 hash_algorithm sha1 url - https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-linux64-d7afe27.tar.zst + https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-cb8785a/cubemaptoequirectangular-1.1.0-linux64-cb8785a.tar.zst name linux64 @@ -298,11 +298,11 @@ archive hash - 6c51855bcf3a8628289881fdaea08c25cf7b1b90 + eabc3b0c9d9084f49b8a4dc5d3834d77f668c27a hash_algorithm sha1 url - https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-d7afe27/cubemaptoequirectangular-1.1.0-windows64-d7afe27.tar.zst + https://github.com/secondlife/3p-cubemap_to_eqr_js/releases/download/v1.1.0-cb8785a/cubemaptoequirectangular-1.1.0-windows64-cb8785a.tar.zst name windows64 @@ -379,36 +379,6 @@ description Library for transferring data specified with URL syntax - dbus_glib - - platforms - - linux64 - - archive - - hash - 7ee7b9aed3c0c8c09e7bf26bba7af8e1 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-dbus-glib/rev/314266/arch/Linux/installer/dbus_glib-0.76-linux64-314266.tar.bz2 - - name - linux64 - - - license - Academic Free License v. 2.1 - license_file - LICENSES/dbus-glib.txt - copyright - Copyright (C) Red Hat Inc. - version - 0.76 - name - dbus_glib - description - D-Bus bindings for glib - dictionaries platforms @@ -595,36 +565,6 @@ description Expat is an XML parser library written in C - fontconfig - - platforms - - linux64 - - archive - - hash - e2419d56960c160670051fbb055fb729 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-fontconfig/rev/314281/arch/Linux/installer/fontconfig-2.11.0-linux64-314281.tar.bz2 - - name - linux64 - - - license - bsd - license_file - LICENSES/fontconfig.txt - copyright - Copyright (C) 2000,2001,2002,2003,2004,2006,2007 Keith Packard, 2005 Patrick Lam, 2009 Roozbeh Pournader, 2008,2009 Red Hat, Inc., 2008 Danilo Šegan, 2012 Google, Inc. - version - 2.11.0 - name - fontconfig - description - Fontconfig is a library for configuring and customizing font access. - freetype platforms @@ -791,62 +731,6 @@ source_type git - gstreamer - - platforms - - linux64 - - archive - - hash - 7c9d7cc88add7831a6afeedc20cad2fe - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gstreamer/rev/314267/arch/Linux/installer/gstreamer-0.10.6.314267-linux64-314267.tar.bz2 - - name - linux64 - - - license - LGPL - license_file - LICENSES/gstreamer.txt - copyright - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - version - 0.10.6.314267 - name - gstreamer - - gtk-atk-pango-glib - - platforms - - linux64 - - archive - - hash - de7bba8fd2275a11b077b124413065d0 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-gtk-atk-pango-glib/rev/314220/arch/Linux/installer/gtk_atk_pango_glib-0.1-linux64-314220.tar.bz2 - - name - linux64 - - - license - lgpl - license_file - LICENSES/gtk-atk-pango-glib.txt - copyright - Copyright (various, see sources) - version - 0.1 - name - gtk-atk-pango-glib - havok-source platforms @@ -858,11 +742,11 @@ creds github hash - ae2c2a215b1bc2e3f37a67e301926dc405902d1a + 1648aeb68395cba38f9326c671609d6730cbcc28 hash_algorithm sha1 url - https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/136778143 + https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/196725921 name darwin64 @@ -871,10 +755,14 @@ archive + creds + github hash - 00d0333936a67059a43a6ec8ac38d564 + 702ad28b6dbace2a68260d69f6d1768d163b5a6f + hash_algorithm + sha1 url - http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/748/1563/havok_source-2012.1-2-linux64-500739.tar.bz2 + https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/196725902 name linux64 @@ -886,11 +774,11 @@ creds github hash - 0393dd75c58f7046bed47e62a8884a78cb02a5c3 + ea980f372981fe7685f91a111da2785825d473ed hash_algorithm sha1 url - https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/136778145 + https://api.github.com/repos/secondlife/3p-havok-source/releases/assets/196725911 name windows64 @@ -1081,22 +969,6 @@ name windows64 - linux - - archive - - creds - github - hash - 85e294becce8b2ac5d2e5e052b0e21ff865d1108 - hash_algorithm - sha1 - url - https://api.github.com/repos/secondlife/3p-kdu/releases/assets/208381806 - - name - linux - license Kakadu @@ -1277,36 +1149,6 @@ description PNG Reference library - libuuid - - platforms - - linux64 - - archive - - hash - fb89f1281dd54d8b99b339fc5b712b27 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-libuuid/rev/314269/arch/Linux/installer/libuuid-1.6.2-linux64-314269.tar.bz2 - - name - linux64 - - - license - UUID - license_file - LICENSES/uuid.txt - copyright - Copyright (c) 2004-2008 The OSSP Project <http://www.ossp.org/> - version - 1.6.2 - name - libuuid - description - OSSP uuid is a ISO-C:1999 application programming interface (API) and corresponding command line interface (CLI) for the generation of DCE 1.1, ISO/IEC 11578:1996 and RFC 4122 compliant Universally Unique Identifier (UUID). - libxml2 platforms @@ -1512,32 +1354,6 @@ name llphysicsextensions_tpv - mesa - - platforms - - linux - - archive - - hash - 22c50a5d362cad311b4f413cfcffbba2 - url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/mesa_3p-update-mesa/rev/297294/arch/Linux/installer/mesa-7.11.1.297294-linux-297294.tar.bz2 - - name - linux - - - license - mesa - license_file - LICENSES/mesa.txt - version - 7.11.1.297294 - name - mesa - meshoptimizer platforms @@ -2542,7 +2358,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors description Linden Lab Viewer Management Process suite. source - https://bitbucket.org/lindenlab/vmp-standalone + https://github.com/secondlife/viewer-manager source_type hg @@ -2633,11 +2449,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 43c5f93517794aeade550e4266b959d1f0cfcb7f + a5e72a9d13b6c4646d1e02b5820f16560d204de7 hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-darwin64-17630578914.tar.zst + https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.21/webrtc-m137.7151.04.21.18609120431-darwin64-18609120431.tar.zst name darwin64 @@ -2647,11 +2463,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - efc5b176d878cfc16b8f82445d82ddb96815b6ab + 1030e5086f401d738463223da3ed99c225340f39 hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-linux64-17630578914.tar.zst + https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.21/webrtc-m137.7151.04.21.18609120431-linux64-18609120431.tar.zst name linux64 @@ -2661,11 +2477,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 1e36f100de32c7c71325497a672fb1659b3f206d + d1cae9bc8866ca01aa9f5e72b36d12ef608b1998 hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-windows64-17630578914.tar.zst + https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.21/webrtc-m137.7151.04.21.18609120431-windows64-18609120431.tar.zst name windows64 @@ -2678,7 +2494,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2011, The WebRTC project authors. All rights reserved. version - m137.7151.04.20-universal.17630578914 + m137.7151.04.21.18609120431 name webrtc vcs_branch @@ -2891,11 +2707,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 140d8fc952a10edb5f2d72ab405336019ef32cadfa64f0cfce76c9de4bc6268cbc87cc8cd89d3417fb78b531d441701afc8d016bafe4bd275df2707f7daf1387 + 49046b0b41310d2fb0d72853730b2faad35d3e36 hash_algorithm - blake2b + sha1 url - https://github.com/AlchemyViewer/3p-vhacd/releases/download/v4.1.0-r2/vhacd-4.1.0-r2-common-18166921729.tar.zst + https://github.com/secondlife/3p-vhacd/releases/download/v4.1.0-r1/vhacd-4.1.0-r1-common-18475951995.tar.zst name common @@ -2908,7 +2724,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2011, Khaled Mamou version - 4.1.0-r2 + 4.1.0-r1 name vhacd description @@ -3143,15 +2959,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors configurations - Release + RelWithDebInfo configure options -G - Ninja - -DLL_TESTS=Off + Unix Makefiles arguments @@ -3161,39 +2976,106 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors build command - ninja + cmake + options + + --build + . + --config + Release + --parallel + $AUTOBUILD_CPU_COUNT + default True name - Release + RelWithDebInfo - ReleaseOS + RelWithDebInfoOS configure options -G - Ninja - -DLL_TESTS=Off + Unix Makefiles build command - ninja + cmake + options + + --build + . + --config + Release + --parallel + $AUTOBUILD_CPU_COUNT + name - ReleaseOS + RelWithDebInfoOS + + Release + + configure + + options + + -G + Unix Makefiles + + arguments + + ../indra + + + build + + command + cmake + options + + --build + . + --config + Release + --parallel + $AUTOBUILD_CPU_COUNT + + + name + Release - default + ReleaseOS + configure + + options + + -G + Unix Makefiles + + build + command + cmake + options + + --build + . + --config + Release + --parallel + $AUTOBUILD_CPU_COUNT + name - default + ReleaseOS build_directory @@ -3224,15 +3106,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors build command - devenv + cmake options - /build - RelWithDebInfo|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - - arguments - - SecondLife.sln + --build + . + --config + RelWithDebInfo + --parallel + $AUTOBUILD_CPU_COUNT default @@ -3299,15 +3181,15 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors build command - devenv + cmake options - /build - Release|${AUTOBUILD_WIN_VSPLATFORM|NOTWIN} - - arguments - - SecondLife.sln + --build + . + --config + Release + --parallel + $AUTOBUILD_CPU_COUNT name diff --git a/indra/cmake/00-COMPILE-LINK-RUN.txt b/indra/cmake/00-COMPILE-LINK-RUN.txt index 1933072a6d..7b91b5a0d4 100644 --- a/indra/cmake/00-COMPILE-LINK-RUN.txt +++ b/indra/cmake/00-COMPILE-LINK-RUN.txt @@ -117,7 +117,7 @@ Compilation currently being generated with a link path of '@executable_path/../Resources/'. If we were to follow the recommendations in dyld's man page, we’d instead reference - '@loader_path/', use -rpath on the executable link + '@loader_path/', use -rpath on the executable link (pointing to the 'Resources' subdir of the main executable), and be able to avoid some symlinking in the .app tree. @@ -162,7 +162,7 @@ Linking * Update the autobuild.xml of ALL consumers of the library. In the case of zlib, that meant updating freetype, libpng, openssl, - libxml2, fontconfig, curl, Boost, SDL, llqtwebkit, google-mock and + libxml2, fontconfig, curl, Boost, SDL3, llqtwebkit, google-mock and colladadom. * Confirm by test and observation that the consumers actually use diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 99ea22ab4b..c03b2d24ea 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -11,13 +11,20 @@ # # Also realize that CMAKE_CXX_FLAGS may already be partially populated on # entry to this file. +# +# Additionally CMAKE_C_FLAGS is prepended to CMAKE_CXX_FLAGS_RELEASE and +# CMAKE_CXX_FLAGS_RELWITHDEBINFO which risks having flags overriden by cmake +# inserting additional options that are part of the build config type. #***************************************************************************** include_guard() include(Variables) +include(Linking) # We go to some trouble to set LL_BUILD to the set of relevant compiler flags. -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} $ENV{LL_BUILD_RELEASE}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} $ENV{LL_BUILD_RELWITHDEBINFO}") + # Given that, all the flags you see added below are flags NOT present in # https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables. # Before adding new ones here, it's important to ask: can this flag really be @@ -25,7 +32,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}") # as well? # Portable compilation flags. -add_compile_definitions( ADDRESS_SIZE=${ADDRESS_SIZE}) +add_compile_definitions(ADDRESS_SIZE=${ADDRESS_SIZE}) # Because older versions of Boost.Bind dumped placeholders _1, _2 et al. into # the global namespace, Boost now requires either BOOST_BIND_NO_PLACEHOLDERS # to avoid that or BOOST_BIND_GLOBAL_PLACEHOLDERS to state that we require it @@ -111,7 +118,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}") @@ -125,9 +132,6 @@ endif (WINDOWS) if (LINUX) set(CMAKE_SKIP_RPATH TRUE) - # EXTERNAL_TOS - # force this platform to accept TOS via external browser - # LL_IGNORE_SIGCHLD # don't catch SIGCHLD in our base application class for the viewer - some of # our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The @@ -135,42 +139,45 @@ if (LINUX) add_compile_definitions( _REENTRANT - _FORTIFY_SOURCE=2 - EXTERNAL_TOS APPID=secondlife LL_IGNORE_SIGCHLD ) + + if(ENABLE_ASAN) + add_compile_options(-U_FORTIFY_SOURCE + -fsanitize=address + --param asan-stack=0 + ) + add_link_options(-fsanitize=address) + else() + add_compile_definitions($<$:_FORTIFY_SOURCE=2>) + endif() + add_compile_options( + $<$,$>:-fstack-protector> -fexceptions -fno-math-errno -fno-strict-aliasing -fsigned-char + -g -msse2 - -mfpmath=sse -pthread - -Wno-parentheses - -Wno-deprecated -fvisibility=hidden ) - if (ADDRESS_SIZE EQUAL 32) - add_compile_options(-march=pentium4) - endif (ADDRESS_SIZE EQUAL 32) - - # this stops us requiring a really recent glibc at runtime - add_compile_options(-fno-stack-protector) - # linking can be very memory-hungry, especially the final viewer link - set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory") - - set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}") + add_link_options( + "LINKER:-z,relro" + "LINKER:-z,now" + "LINKER:--build-id" + "LINKER:--as-needed" + "LINKER:--no-undefined" + ) endif (LINUX) if (DARWIN) # Use rpath loading on macos set(CMAKE_MACOSX_RPATH TRUE) - # Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default - set(CLANG_DISABLE_FATAL_WARNINGS OFF) set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}") @@ -185,20 +192,17 @@ if (LINUX OR DARWIN) add_compile_options(-Wall -Wno-sign-compare -Wno-trigraphs -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - # libstdc++ headers contain deprecated declarations that fail on clang - # macOS currently has many deprecated calls add_compile_options(-Wno-unused-local-typedef) endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - add_compile_options(-Wno-stringop-truncation -Wno-parentheses -Wno-maybe-uninitialized) - endif() + add_compile_options(-Wno-stringop-truncation -Wno-stringop-overflow -Wno-parentheses -Wno-maybe-uninitialized -Wno-unused-local-typedefs) + endif () if (NOT GCC_DISABLE_FATAL_WARNINGS AND NOT CLANG_DISABLE_FATAL_WARNINGS) add_compile_options(-Werror) endif () - add_compile_options(${GCC_WARNINGS}) add_compile_options(-m${ADDRESS_SIZE}) endif (LINUX OR DARWIN) diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index b57c33c3e0..610a4f6232 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -1,5 +1,6 @@ # -*- cmake -*- include(Prebuilt) +include(Linking) include_guard() @@ -16,107 +17,69 @@ use_prebuilt_binary(boost) # with the address size. set(addrsfx "-x${ADDRESS_SIZE}") -if (WINDOWS) - - find_library(BOOST_CONTEXT_LIBRARY - NAMES - libboost_context-mt - libboost_context-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_FIBER_LIBRARY - NAMES - libboost_fiber-mt - libboost_fiber-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_FILESYSTEM_LIBRARY - NAMES - libboost_filesystem-mt - libboost_filesystem-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_PROGRAMOPTIONS_LIBRARY - NAMES - libboost_program_options-mt - libboost_program_options-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_REGEX_LIBRARY - NAMES - libboost_regex-mt - libboost_regex-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_SYSTEM_LIBRARY - NAMES - libboost_system-mt - libboost_system-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_THREAD_LIBRARY - NAMES - libboost_thread-mt - libboost_thread-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_URL_LIBRARY - NAMES - libboost_url-mt - libboost_url-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - -else (WINDOWS) - - find_library(BOOST_CONTEXT_LIBRARY - NAMES - boost_context-mt - boost_context-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_FIBER_LIBRARY - NAMES - boost_fiber-mt - boost_fiber-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_FILESYSTEM_LIBRARY - NAMES - boost_filesystem-mt - boost_filesystem-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_PROGRAMOPTIONS_LIBRARY - NAMES - boost_program_options-mt - boost_program_options-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_REGEX_LIBRARY - NAMES - boost_regex-mt - boost_regex-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_SYSTEM_LIBRARY - NAMES - boost_system-mt - boost_system-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_THREAD_LIBRARY - NAMES - boost_thread-mt - boost_thread-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - find_library(BOOST_URL_LIBRARY - NAMES - boost_url-mt - boost_url-mt${addrsfx} - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - -endif (WINDOWS) +find_library(BOOST_CONTEXT_LIBRARY + NAMES + libboost_context-mt + libboost_context-mt${addrsfx} + boost_context-mt + boost_context-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(BOOST_FIBER_LIBRARY + NAMES + libboost_fiber-mt + libboost_fiber-mt${addrsfx} + boost_fiber-mt + boost_fiber-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(BOOST_FILESYSTEM_LIBRARY + NAMES + libboost_filesystem-mt + libboost_filesystem-mt${addrsfx} + boost_filesystem-mt + boost_filesystem-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(BOOST_PROGRAMOPTIONS_LIBRARY + NAMES + libboost_program_options-mt + libboost_program_options-mt${addrsfx} + boost_program_options-mt + boost_program_options-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(BOOST_REGEX_LIBRARY + NAMES + libboost_regex-mt + libboost_regex-mt${addrsfx} + boost_regex-mt + boost_regex-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(BOOST_SYSTEM_LIBRARY + NAMES + libboost_system-mt + libboost_system-mt${addrsfx} + boost_system-mt + boost_system-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(BOOST_THREAD_LIBRARY + NAMES + libboost_thread-mt + libboost_thread-mt${addrsfx} + boost_thread-mt + boost_thread-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + +find_library(BOOST_URL_LIBRARY + NAMES + libboost_url-mt + libboost_url-mt${addrsfx} + boost_url-mt + boost_url-mt${addrsfx} + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) target_link_libraries(ll::boost INTERFACE ${BOOST_FIBER_LIBRARY} diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake index e27929fa08..5f5c55f0e9 100644 --- a/indra/cmake/CEFPlugin.cmake +++ b/indra/cmake/CEFPlugin.cmake @@ -10,9 +10,9 @@ target_include_directories( ll::cef SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/inclu if (WINDOWS) target_link_libraries( ll::cef INTERFACE - libcef.lib - libcef_dll_wrapper.lib - dullahan.lib + ${ARCH_PREBUILT_DIRS_RELEASE}/libcef.lib + ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.lib + ${ARCH_PREBUILT_DIRS_RELEASE}/dullahan.lib ) elseif (DARWIN) FIND_LIBRARY(APPKIT_LIBRARY AppKit) @@ -32,4 +32,9 @@ elseif (DARWIN) ) elseif (LINUX) + target_link_libraries( ll::cef INTERFACE + ${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a + ${ARCH_PREBUILT_DIRS_RELEASE}/libcef.so + ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a + ) endif (WINDOWS) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 0aed268c29..5847553993 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -11,22 +11,23 @@ set(cmake_SOURCE_FILES Audio.cmake Boost.cmake bugsplat.cmake + BuildPackagesInfo.cmake BuildVersion.cmake CEFPlugin.cmake CEFPlugin.cmake CMakeCopyIfDifferent.cmake - ConfigurePkgConfig.cmake - CURL.cmake Copy3rdPartyLibs.cmake - DBusGlib.cmake + CURL.cmake DeploySharedLibs.cmake Discord.cmake DragDrop.cmake EXPAT.cmake FindAutobuild.cmake + FindPipeWire.cmake FreeType.cmake GLEXT.cmake GLH.cmake + GLIB.cmake GLM.cmake GStreamer10Plugin.cmake Havok.cmake @@ -54,6 +55,7 @@ set(cmake_SOURCE_FILES Prebuilt.cmake PulseAudio.cmake Python.cmake + SDL3.cmake SSE2NEON.cmake TemplateCheck.cmake TinyEXR.cmake diff --git a/indra/cmake/ConfigurePkgConfig.cmake b/indra/cmake/ConfigurePkgConfig.cmake deleted file mode 100644 index 9e798d663b..0000000000 --- a/indra/cmake/ConfigurePkgConfig.cmake +++ /dev/null @@ -1,74 +0,0 @@ -# -*- cmake -*- - -SET(DEBUG_PKG_CONFIG "YES") - -# Don't change this if manually set by user. -IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "") - - # Guess at architecture-specific system library paths. - if (ADDRESS_SIZE EQUAL 32) - SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib) - SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib) - SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu) - SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu) - else (ADDRESS_SIZE EQUAL 32) - SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib) - SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib) - SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu) - SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu) - endif (ADDRESS_SIZE EQUAL 32) - - # Use DPKG architecture, if available. - IF (${DPKG_ARCH}) - SET(PKG_CONFIG_MULTI_GUESS /usr/lib/${DPKG_ARCH}) - SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usrlocal/lib/${DPKG_ARCH}) - ENDIF (${DPKG_ARCH}) - - # Explicitly include anything listed in PKG_CONFIG_PATH - string(REPLACE ":" ";" PKG_CONFIG_PATH_LIST "$ENV{PKG_CONFIG_PATH}") - FOREACH(PKG_CONFIG_DIR ${PKG_CONFIG_PATH_LIST}) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_DIR}/pkgconfig") - ENDFOREACH(PKG_CONFIG_DIR) - - # Look for valid pkgconfig directories. - FIND_PATH(PKG_CONFIG_ENV pkgconfig ENV LD_LIBRARY_PATH) - FIND_PATH(PKG_CONFIG_MULTI pkgconfig HINT ${PKG_CONFIG_MULTI_GUESS}) - FIND_PATH(PKG_CONFIG_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_MULTI_LOCAL_GUESS}) - FIND_PATH(PKG_CONFIG_NO_MULTI pkgconfig HINT ${PKG_CONFIG_NO_MULTI_GUESS}) - FIND_PATH(PKG_CONFIG_NO_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_NO_MULTI_LOCAL_GUESS}) - - # Add anything we found to our list. - IF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_ENV}/pkgconfig") - ENDIF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND) - - IF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI}/pkgconfig") - ENDIF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND) - - IF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI_LOCAL}/pkgconfig") - ENDIF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND) - - IF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI}/pkgconfig") - ENDIF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND) - - IF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND) - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI_LOCAL}/pkgconfig") - ENDIF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND) - - # Also add some non-architecture specific package locations. - SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:/usr/share/pkgconfig:/usr/local/share/pkgconfig") - - # Remove first unwanted ':' - string(SUBSTRING ${VALID_PKG_LIBDIRS} 1 -1 VALID_PKG_LIBDIRS) - - # Set PKG_CONFIG_LIBDIR environment. - SET(ENV{PKG_CONFIG_LIBDIR} ${VALID_PKG_LIBDIRS}) -ENDIF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "") - -IF(DEBUG_PKG_CONFIG) - MESSAGE(STATUS "Using PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}") -ENDIF(DEBUG_PKG_CONFIG) - diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 680f2f3ac2..3e89118a4e 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -211,17 +211,10 @@ elseif(LINUX) if( USE_AUTOBUILD_3P ) list( APPEND release_files - libatk-1.0.so - libfreetype.so.6.6.2 - libfreetype.so.6 - libopenjp2.so - libuuid.so.16 - libuuid.so.16.0.22 - libfontconfig.so.1.8.0 - libfontconfig.so.1 - libgmodule-2.0.so - libgobject-2.0.so - ) + libSDL3.so + libSDL3.so.0 + libSDL3.so.0.2.22 + ) endif() else(WINDOWS) diff --git a/indra/cmake/DBusGlib.cmake b/indra/cmake/DBusGlib.cmake deleted file mode 100644 index c9b727ca9d..0000000000 --- a/indra/cmake/DBusGlib.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -*- cmake -*- -include(Prebuilt) - -add_library( ll::dbus INTERFACE IMPORTED) - -if( LINUX ) - # Only define this when not using the prebuild 3ps, lls prebuild is broken - if( NOT USE_AUTOBUILD_3P ) - target_compile_definitions( ll::dbus INTERFACE LL_DBUS_ENABLED ) - endif() - use_system_binary(dbus) - - use_prebuilt_binary(dbus_glib) -endif() diff --git a/indra/cmake/Discord.cmake b/indra/cmake/Discord.cmake index 95cfaacf5b..0e63d05350 100644 --- a/indra/cmake/Discord.cmake +++ b/indra/cmake/Discord.cmake @@ -2,10 +2,23 @@ include(Prebuilt) include_guard() -add_library(ll::discord_sdk INTERFACE IMPORTED) -target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1) +option(USE_DISCORD "Enable Discord SDK" OFF) -use_prebuilt_binary(discord_sdk) +if(USE_DISCORD) + add_library(ll::discord_sdk INTERFACE IMPORTED) -target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk) -target_link_libraries(ll::discord_sdk INTERFACE discord_partner_sdk) + target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1) + + use_prebuilt_binary(discord_sdk) + + find_library(DISCORD_SDK_LIBRARY + NAMES + discord_partner_sdk + discord_partner_sdk.lib + libdiscord_partner_sdk.so + libdiscord_partner_sdk.dylib + PATHS "${ARCH_PREBUILT_DIRS_ARCH_RELEASE}" "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) + + target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk) + target_link_libraries(ll::discord_sdk INTERFACE ${DISCORD_SDK_LIBRARY}) +endif() diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake index 3c635e851b..eb018c09e9 100644 --- a/indra/cmake/FreeType.cmake +++ b/indra/cmake/FreeType.cmake @@ -1,6 +1,8 @@ # -*- cmake -*- include(Prebuilt) include(Linking) +include(PNG) +include(ZLIBNG) include_guard() add_library( ll::freetype INTERFACE IMPORTED ) @@ -15,4 +17,4 @@ find_library(FREETYPE_LIBRARY libfreetype.a PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) -target_link_libraries(ll::freetype INTERFACE ${FREETYPE_LIBRARY}) +target_link_libraries(ll::freetype INTERFACE ${FREETYPE_LIBRARY} ll::libpng ll::zlib-ng) diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake index c544440adc..64e33f6c83 100644 --- a/indra/cmake/Havok.cmake +++ b/indra/cmake/Havok.cmake @@ -27,26 +27,26 @@ else (LL_DEBUG_HAVOK) endif (LL_DEBUG_HAVOK) set(HAVOK_LIBS - hkBase - hkCompat + hkgpConvexDecomposition hkGeometryUtilities - hkInternal hkSerialize hkSceneData hkpCollide hkpUtilities hkpConstraintSolver hkpDynamics - hkpInternal - hkaiInternal hkaiPathfinding hkaiAiPhysicsBridge - hkcdInternal hkcdCollide hkpVehicle hkVisualize hkaiVisualize - hkgpConvexDecomposition + hkaiInternal + hkcdInternal + hkpInternal + hkInternal + hkCompat + hkBase ) unset(HK_DEBUG_LIBRARIES) @@ -60,16 +60,22 @@ if (DEBUG_PREBUILT) # but making it pretty is a lot more work message(STATUS "${ARGN}") endfunction(DEBUG_MESSAGE) + function(DEBUG_EXEC_FUNC) + execute_process(COMMAND ${ARGN}) + endfunction(DEBUG_EXEC_FUNC) else (DEBUG_PREBUILT) # without DEBUG_PREBUILT, DEBUG_MESSAGE() is a no-op function(DEBUG_MESSAGE) endfunction(DEBUG_MESSAGE) + function(DEBUG_EXEC_FUNC) + execute_process(COMMAND ${ARGN} OUTPUT_QUIET) + endfunction(DEBUG_EXEC_FUNC) endif (DEBUG_PREBUILT) # DEBUG_EXEC() reports each execute_process() before invoking function(DEBUG_EXEC) DEBUG_MESSAGE(${ARGN}) - execute_process(COMMAND ${ARGN}) + DEBUG_EXEC_FUNC(${ARGN}) endfunction(DEBUG_EXEC) # *TODO: Figure out why we need to extract like this... @@ -79,9 +85,7 @@ foreach(HAVOK_LIB ${HAVOK_LIBS}) find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}) if(LINUX) - set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}") set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}") - set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}") # Try to avoid extracting havok library each time we run cmake. if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted") @@ -92,8 +96,8 @@ foreach(HAVOK_LIB ${HAVOK_LIBS}) if(${PREBUILD_TRACKING_DIR}/havok_source_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0) DEBUG_MESSAGE("Extracting ${HAVOK_LIB}...") - foreach(lib ${debug_dir} ${release_dir} ${relwithdebinfo_dir}) - DEBUG_EXEC("mkdir" ${lib}) + foreach(lib ${release_dir}) + DEBUG_EXEC("mkdir" "-p" ${lib}) DEBUG_EXEC("ar" "-xv" "../lib${HAVOK_LIB}.a" WORKING_DIRECTORY ${lib}) endforeach(lib) @@ -104,17 +108,12 @@ foreach(HAVOK_LIB ${HAVOK_LIBS}) endif() - file(GLOB extracted_debug "${debug_dir}/*.o") file(GLOB extracted_release "${release_dir}/*.o") - file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o") - - DEBUG_MESSAGE("extracted_debug ${debug_dir}/*.o") DEBUG_MESSAGE("extracted_release ${release_dir}/*.o") - DEBUG_MESSAGE("extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o") - list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug}) + list(APPEND HK_DEBUG_LIBRARIES ${extracted_release}) list(APPEND HK_RELEASE_LIBRARIES ${extracted_release}) - list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo}) + list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_release}) else(LINUX) # Win32 list(APPEND HK_DEBUG_LIBRARIES ${HAVOK_DEBUG_LIB_${HAVOK_LIB}}) diff --git a/indra/cmake/JPEG.cmake b/indra/cmake/JPEG.cmake index f864ca7f8d..49880e7f72 100644 --- a/indra/cmake/JPEG.cmake +++ b/indra/cmake/JPEG.cmake @@ -11,6 +11,9 @@ use_prebuilt_binary(libjpeg-turbo) find_library(JPEG_LIBRARY NAMES + jpeg + jpeg-static + jpeg-static.lib jpeg.lib libjpeg.a PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) diff --git a/indra/cmake/LLKDU.cmake b/indra/cmake/LLKDU.cmake index 7680ab7b54..3009b4b9cc 100644 --- a/indra/cmake/LLKDU.cmake +++ b/indra/cmake/LLKDU.cmake @@ -14,19 +14,11 @@ if (USE_KDU) include(Prebuilt) use_prebuilt_binary(kdu) - if (WINDOWS) - find_library(KDU_LIBRARY - NAMES - kdu - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - else (WINDOWS) - find_library(KDU_LIBRARY - NAMES - libkdu.a - PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - - endif (WINDOWS) + find_library(KDU_LIBRARY + NAMES + kdu + libkdu.a + PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) target_link_libraries(ll::kdu INTERFACE ${KDU_LIBRARY}) diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake index 2e1b601b79..d5840379ac 100644 --- a/indra/cmake/LLWindow.cmake +++ b/indra/cmake/LLWindow.cmake @@ -3,20 +3,12 @@ include(Variables) include(GLEXT) include(Prebuilt) +include(SDL3) include_guard() -add_library( ll::SDL INTERFACE IMPORTED ) - if (LINUX) - #Must come first as use_system_binary can exit this file early - target_compile_definitions( ll::SDL INTERFACE LL_SDL=1) - - use_system_binary(SDL) - use_prebuilt_binary(SDL) - - target_include_directories( ll::SDL SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) - target_link_libraries( ll::SDL INTERFACE SDL directfb fusion direct X11) + set(USE_SDL_WINDOW ON CACHE BOOL "Build with SDL window backend") +else() + set(USE_SDL_WINDOW OFF CACHE BOOL "Build with SDL window backend") endif (LINUX) - - diff --git a/indra/cmake/NDOF.cmake b/indra/cmake/NDOF.cmake index a8f63f945b..60b29a57fe 100644 --- a/indra/cmake/NDOF.cmake +++ b/indra/cmake/NDOF.cmake @@ -19,7 +19,12 @@ if (NDOF) ndofdev PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) - target_link_libraries(ll::ndof INTERFACE ${NDOF_LIBRARY}) + if (LINUX) + include(SDL3) + target_link_libraries(ll::ndof INTERFACE ${NDOF_LIBRARY} ll::SDL3) + else() + target_link_libraries(ll::ndof INTERFACE ${NDOF_LIBRARY}) + endif() target_compile_definitions(ll::ndof INTERFACE LIB_NDOF=1) endif (NDOF) diff --git a/indra/cmake/OPENAL.cmake b/indra/cmake/OPENAL.cmake index ab1604aa22..523a2d16f6 100644 --- a/indra/cmake/OPENAL.cmake +++ b/indra/cmake/OPENAL.cmake @@ -26,6 +26,7 @@ if (USE_OPENAL) NAMES OpenAL32 openal + OpenAL32.lib libopenal.dylib libopenal.so PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) @@ -33,6 +34,7 @@ if (USE_OPENAL) find_library(ALUT_LIBRARY NAMES alut + alut.lib libalut.dylib libalut.so PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake index 0c01e5ee78..6a66f40385 100644 --- a/indra/cmake/PNG.cmake +++ b/indra/cmake/PNG.cmake @@ -1,5 +1,7 @@ # -*- cmake -*- include(Prebuilt) +include(Linking) +include(ZLIBNG) include_guard() add_library( ll::libpng INTERFACE IMPORTED ) @@ -13,5 +15,5 @@ find_library(LIBPNG_LIBRARY libpng16.a PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH) -target_link_libraries(ll::libpng INTERFACE ${LIBPNG_LIBRARY}) +target_link_libraries(ll::libpng INTERFACE ${LIBPNG_LIBRARY} ll::zlib-ng) target_include_directories(ll::libpng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/libpng16) diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake index 634cc15c21..d0ab341d94 100644 --- a/indra/cmake/Prebuilt.cmake +++ b/indra/cmake/Prebuilt.cmake @@ -2,9 +2,6 @@ include_guard() include(FindAutobuild) -if(INSTALL_PROPRIETARY) - include(FindSCP) -endif(INSTALL_PROPRIETARY) set(PREBUILD_TRACKING_DIR ${AUTOBUILD_INSTALL_DIR}/cmake_tracking) # For the library installation process; @@ -40,8 +37,10 @@ macro (use_prebuilt_binary _binary) --install-dir=${AUTOBUILD_INSTALL_DIR} ${_binary} ") endif(DEBUG_PREBUILT) + message(STATUS "Installing ${_binary}...") execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}" install + --skip-source-environment --install-dir=${AUTOBUILD_INSTALL_DIR} ${_binary} WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake index 7cce190f6a..39fd21c33f 100644 --- a/indra/cmake/Python.cmake +++ b/indra/cmake/Python.cmake @@ -13,7 +13,7 @@ elseif (WINDOWS) foreach(hive HKEY_CURRENT_USER HKEY_LOCAL_MACHINE) # prefer more recent Python versions to older ones, if multiple versions # are installed - foreach(pyver 3.13 3.12 3.11 3.10 3.9 3.8 3.7) + foreach(pyver 3.14 3.13 3.12 3.11 3.10 3.9 3.8 3.7) list(APPEND regpaths "[${hive}\\SOFTWARE\\Python\\PythonCore\\${pyver}\\InstallPath]") endforeach() endforeach() diff --git a/indra/cmake/SDL3.cmake b/indra/cmake/SDL3.cmake new file mode 100644 index 0000000000..b37e1c64c2 --- /dev/null +++ b/indra/cmake/SDL3.cmake @@ -0,0 +1,19 @@ +# -*- cmake -*- +cmake_minimum_required( VERSION 3.13 FATAL_ERROR ) + +include(Linking) +include( Prebuilt ) +include_guard() + +add_library( ll::SDL3 INTERFACE IMPORTED ) + +use_system_binary( SDL3 ) +use_prebuilt_binary( SDL3 ) + +find_library( SDL3_LIBRARY + NAMES SDL3 SDL3.lib libSDL3.so libSDL3.dylib + PATHS "${LIBS_PREBUILT_DIR}/lib/release" REQUIRED) + +target_link_libraries( ll::SDL3 INTERFACE ${SDL3_LIBRARY}) +target_include_directories( ll::SDL3 SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/" ) + diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake index 8f135676d6..afa1350ef0 100644 --- a/indra/cmake/UI.cmake +++ b/indra/cmake/UI.cmake @@ -1,35 +1,33 @@ # -*- cmake -*- include(Prebuilt) include(FreeType) +include(GLIB) +include_guard() add_library( ll::uilibraries INTERFACE IMPORTED ) if (LINUX) - target_compile_definitions(ll::uilibraries INTERFACE LL_GTK=1 LL_X11=1 ) - if( USE_CONAN ) - target_link_libraries( ll::uilibraries INTERFACE CONAN_PKG::gtk ) return() endif() - use_prebuilt_binary(gtk-atk-pango-glib) + + find_package(PkgConfig REQUIRED) + pkg_check_modules(WAYLAND_CLIENT wayland-client) + + if( WAYLAND_CLIENT_FOUND ) + target_compile_definitions( ll::uilibraries INTERFACE LL_WAYLAND=1) + else() + message("pkgconfig could not find wayland client, compiling without full wayland support") + endif() target_link_libraries( ll::uilibraries INTERFACE - atk-1.0 - gdk-x11-2.0 - gdk_pixbuf-2.0 - Xinerama - glib-2.0 - gmodule-2.0 - gobject-2.0 - gthread-2.0 - gtk-x11-2.0 - pango-1.0 - pangoft2-1.0 - pangox-1.0 - pangoxft-1.0 - Xinerama + ll::fontconfig ll::freetype - ) + ll::SDL3 + ll::glib + ll::gio + ) + endif (LINUX) if( WINDOWS ) target_link_libraries( ll::uilibraries INTERFACE diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 22c2156bb8..2341d15a85 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -9,21 +9,51 @@ # LINUX - Linux # WINDOWS - Windows +include_guard() + # Switches set here and in 00-Common.cmake must agree with # https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables # Reading $LL_BUILD is an attempt to directly use those switches. -if ("$ENV{LL_BUILD}" STREQUAL "" AND "${LL_BUILD_ENV}" STREQUAL "" ) - message(FATAL_ERROR "Environment variable LL_BUILD must be set") -elseif("$ENV{LL_BUILD}" STREQUAL "") - set( ENV{LL_BUILD} "${LL_BUILD_ENV}" ) - message( "Setting ENV{LL_BUILD} to cached variable ${LL_BUILD_ENV}" ) +if ("$ENV{AUTOBUILD_ADDRSIZE}" STREQUAL "" AND "${AUTOBUILD_ADDRSIZE_ENV}" STREQUAL "" ) + message(FATAL_ERROR "Environment variable AUTOBUILD_ADDRSIZE must be set") +elseif("$ENV{AUTOBUILD_ADDRSIZE}" STREQUAL "") + set( ENV{AUTOBUILD_ADDRSIZE} "${AUTOBUILD_ADDRSIZE_ENV}" ) + message( "Setting ENV{AUTOBUILD_ADDRSIZE} to cached variable ${AUTOBUILD_ADDRSIZE_ENV}" ) else() - set( LL_BUILD_ENV "$ENV{LL_BUILD}" CACHE STRING "Save environment" FORCE ) + set( AUTOBUILD_ADDRSIZE_ENV "$ENV{AUTOBUILD_ADDRSIZE}" CACHE STRING "Save environment AUTOBUILD_ADDRSIZE" FORCE ) endif () -include_guard() -# Relative and absolute paths to subtrees. +if ("$ENV{AUTOBUILD_PLATFORM}" STREQUAL "" AND "${AUTOBUILD_PLATFORM_ENV}" STREQUAL "" ) + message(FATAL_ERROR "Environment variable AUTOBUILD_PLATFORM must be set") +elseif("$ENV{AUTOBUILD_PLATFORM}" STREQUAL "") + set( ENV{AUTOBUILD_PLATFORM} "${AUTOBUILD_PLATFORM_ENV}" ) + message( "Setting ENV{AUTOBUILD_PLATFORM} to cached variable ${AUTOBUILD_PLATFORM_ENV}" ) +else() + set( AUTOBUILD_PLATFORM_ENV "$ENV{AUTOBUILD_PLATFORM}" CACHE STRING "Save environment AUTOBUILD_PLATFORM" FORCE ) +endif () +# Switches set here and in 00-Common.cmake must agree with +# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables +# Reading $LL_BUILD is an attempt to directly use those switches. +if ("$ENV{LL_BUILD_RELEASE}" STREQUAL "" AND "${LL_BUILD_RELEASE_ENV}" STREQUAL "" ) + message(FATAL_ERROR "Environment variable LL_BUILD_RELEASE must be set") +elseif("$ENV{LL_BUILD_RELEASE}" STREQUAL "") + set( ENV{LL_BUILD_RELEASE} "${LL_BUILD_RELEASE_ENV}" ) + message( "Setting ENV{LL_BUILD_RELEASE} to cached variable ${LL_BUILD_RELEASE_ENV}" ) +else() + set( LL_BUILD_RELEASE_ENV "$ENV{LL_BUILD_RELEASE}" CACHE STRING "Save environment RELEASE" FORCE ) +endif () + +if ("$ENV{LL_BUILD_RELWITHDEBINFO}" STREQUAL "" AND "${LL_BUILD_RELWITHDEBINFO_ENV}" STREQUAL "" ) + message(FATAL_ERROR "Environment variable LL_BUILD_RELWITHDEBINFO must be set") +elseif("$ENV{LL_BUILD_RELWITHDEBINFO}" STREQUAL "") + set( ENV{LL_BUILD_RELWITHDEBINFO} "${LL_BUILD_RELWITHDEBINFO_ENV}" ) + message( "Setting ENV{LL_BUILD_RELWITHDEBINFO} to cached variable ${LL_BUILD_RELWITHDEBINFO_ENV}" ) +else() + set( LL_BUILD_RELWITHDEBINFO_ENV "$ENV{LL_BUILD_RELWITHDEBINFO}" CACHE STRING "Save environment RELWITHDEBINFO" FORCE ) +endif () + +# Relative and absolute paths to subtrees. if(NOT DEFINED COMMON_CMAKE_DIR) set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake") endif(NOT DEFINED COMMON_CMAKE_DIR) @@ -67,7 +97,7 @@ set(TEMPLATE_VERIFIER_MASTER_URL "https://github.com/secondlife/master-message-t if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING - "Build type. One of: Debug Release RelWithDebInfo" FORCE) + "Build type. One of: Release RelWithDebInfo" FORCE) endif (NOT CMAKE_BUILD_TYPE) # If someone has specified an address size, use that to determine the @@ -127,16 +157,12 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/${DPKG_ARCH} /usr/local/lib/${DPKG_ARCH} ${CMAKE_SYSTEM_LIBRARY_PATH}) endif (DPKG_RESULT EQUAL 0) - include(ConfigurePkgConfig) - - if (INSTALL_PROPRIETARY) - # Only turn on headless if we can find osmesa libraries. - include(FindPkgConfig) - #pkg_check_modules(OSMESA osmesa) - #if (OSMESA_FOUND) - # set(BUILD_HEADLESS ON CACHE BOOL "Build headless libraries.") - #endif (OSMESA_FOUND) - endif (INSTALL_PROPRIETARY) + # Only turn on headless if we can find osmesa libraries. + find_package(PkgConfig) + pkg_check_modules(OSMESA IMPORTED_TARGET GLOBAL osmesa) + if (OSMESA_FOUND) + set(BUILD_HEADLESS ON CACHE BOOL "Build headless libraries.") + endif (OSMESA_FOUND) endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake index cae68fbc11..23fd477ba8 100644 --- a/indra/cmake/ViewerMiscLibs.cmake +++ b/indra/cmake/ViewerMiscLibs.cmake @@ -5,11 +5,8 @@ if (LINUX) #use_prebuilt_binary(libuuid) add_library( ll::fontconfig INTERFACE IMPORTED ) - if( NOT USE_CONAN ) - use_prebuilt_binary(fontconfig) - else() - target_link_libraries( ll::fontconfig INTERFACE CONAN_PKG::fontconfig ) - endif() + find_package(Fontconfig REQUIRED) + target_link_libraries( ll::fontconfig INTERFACE Fontconfig::Fontconfig ) endif (LINUX) if( NOT USE_CONAN ) diff --git a/indra/cmake/ZLIBNG.cmake b/indra/cmake/ZLIBNG.cmake index a6d67489e7..9f8f12d973 100644 --- a/indra/cmake/ZLIBNG.cmake +++ b/indra/cmake/ZLIBNG.cmake @@ -1,6 +1,7 @@ # -*- cmake -*- include(Prebuilt) +include(Linking) include_guard() add_library( ll::zlib-ng INTERFACE IMPORTED ) diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index 509981d72c..8916cb282c 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -1,18 +1,19 @@ -if (INSTALL_PROPRIETARY) +if (INSTALL_PROPRIETARY AND NOT LINUX) # Note that viewer_manifest.py makes decision based on BUGSPLAT_DB and not USE_BUGSPLAT if (BUGSPLAT_DB) set(USE_BUGSPLAT ON CACHE BOOL "Use the BugSplat crash reporting system") else (BUGSPLAT_DB) set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system") endif (BUGSPLAT_DB) -else (INSTALL_PROPRIETARY) +else () set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system") -endif (INSTALL_PROPRIETARY) + 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(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name") -endif (USE_BUGSPLAT) + set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system" FORCE) + set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name" FORCE) +endif () diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index 6744c8d8a4..40a1036597 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -28,7 +28,7 @@ set(llappearance_SOURCE_FILES llviewervisualparam.cpp llavatarappearancedefines.cpp ) - + set(llappearance_HEADER_FILES CMakeLists.txt @@ -77,6 +77,7 @@ if (BUILD_HEADLESS) llcharacter llinventory llimage + llrenderheadless llfilesystem llmath llxml diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 26a8ff070f..d0ae2d6b93 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -74,18 +74,17 @@ if (BUILD_HEADLESS) add_library (llrenderheadless ${llrender_SOURCE_FILES} ) - - set_property(TARGET llrenderheadless - PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 - ) + target_include_directories( llrenderheadless INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(llrenderheadless llcommon llimage llmath - llrender llxml llfilesystem + llwindowheadless + ll::freetype + OpenGL::GL ) endif (BUILD_HEADLESS) @@ -103,6 +102,5 @@ target_link_libraries(llrender llwindow ll::freetype OpenGL::GL - OpenGL::GLU ) diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt index fe8fee5e7e..600db532d2 100644 --- a/indra/media_plugins/CMakeLists.txt +++ b/indra/media_plugins/CMakeLists.txt @@ -1,20 +1,10 @@ # -*- cmake -*- add_subdirectory(base) +add_subdirectory(cef) +add_subdirectory(libvlc) +add_subdirectory(example) if (LINUX) add_subdirectory(gstreamer10) - add_subdirectory(example) endif (LINUX) - -if (DARWIN) - add_subdirectory(cef) - add_subdirectory(libvlc) - add_subdirectory(example) -endif (DARWIN) - -if (WINDOWS) - add_subdirectory(cef) - add_subdirectory(libvlc) - add_subdirectory(example) -endif (WINDOWS) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 19b8ee3999..d580114099 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -13,7 +13,6 @@ include(BuildPackagesInfo) include(BuildVersion) include(CMakeCopyIfDifferent) include(CubemapToEquirectangularJS) -include(DBusGlib) include(DragDrop) if (USE_DISCORD) include(Discord) @@ -524,6 +523,7 @@ set(viewer_SOURCE_FILES llpathfindingobjectlist.cpp llpathfindingpathtool.cpp llpbrterrainfeatures.cpp + llperfstats.cpp llpersistentnotificationstorage.cpp llphysicsmotion.cpp llphysicsshapebuilderutil.cpp @@ -1185,6 +1185,7 @@ set(viewer_HEADER_FILES llpathfindingobject.h llpathfindingobjectlist.h llpathfindingpathtool.h + llperfstats.h llpbrterrainfeatures.h llpersistentnotificationstorage.h llphysicsmotion.h @@ -1414,9 +1415,6 @@ set(viewer_HEADER_FILES VorbisFramework.h ) - list(APPEND viewer_SOURCE_FILES llperfstats.cpp) - list(APPEND viewer_HEADER_FILES llperfstats.h) - source_group("CMake Rules" FILES ViewerInstall.cmake) #build_data.json creation moved to viewer_manifest.py MAINT-6413 @@ -1489,7 +1487,6 @@ if (LINUX) PROPERTIES COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}" ) - LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") endif (LINUX) @@ -1678,6 +1675,7 @@ set(viewer_APPSETTINGS_FILES packages-info.txt featuretable.txt featuretable_mac.txt + featuretable_linux.txt ) source_group("App Settings" FILES ${viewer_APPSETTINGS_FILES}) @@ -1701,6 +1699,15 @@ set_source_files_properties(${viewer_CHARACTER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES}) +set(viewer_MISC_FILES + viewer_manifest.py + ) + +set_source_files_properties(${viewer_MISC_FILES} + PROPERTIES HEADER_FILE_ONLY TRUE) + +list(APPEND viewer_SOURCE_FILES ${viewer_MISC_FILES}) + if (WINDOWS) file(GLOB viewer_INSTALLER_FILES installers/windows/*.nsi) @@ -1975,11 +1982,13 @@ elseif (DARWIN) target_link_libraries(${VIEWER_BINARY_NAME} llphysicsextensionsos) endif() else (WINDOWS) - # Linux - set_target_properties(${VIEWER_BINARY_NAME} - PROPERTIES - LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -Wl,--Map=${VIEWER_BINARY_NAME}.MAP" - ) + if (HAVOK OR HAVOK_TPV) + # Linux + set_target_properties(${VIEWER_BINARY_NAME} + PROPERTIES + LINK_FLAGS_RELEASE "${LINK_FLAGS_RELEASE} -no-pie -Wl,--Map=${VIEWER_BINARY_NAME}.MAP" + ) + endif () endif (WINDOWS) # *NOTE: - this list is very sensitive to ordering, test carefully on all @@ -2086,8 +2095,11 @@ if (LINUX) set(COPY_INPUT_DEPENDENCIES ${VIEWER_BINARY_NAME} SLPlugin - #media_plugin_gstreamer010 - llcommon + media_plugin_cef + media_plugin_gstreamer10 + media_plugin_libvlc + media_plugin_example + llwebrtc ) #if (NOT USE_BUGSPLAT) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b63e7c66b5..0d2491609b 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -263,10 +263,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 - #ifdef LL_DISCORD #define DISCORDPP_IMPLEMENTATION #include diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 89d19d180b..9366c6f46e 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -34,23 +34,54 @@ #include "llurldispatcher.h" // SLURL from other app instance #include "llviewernetwork.h" #include "llviewercontrol.h" -#include "llwindowsdl.h" #include "llmd5.h" #include "llfindlocale.h" #include +#ifdef LL_GLIB +#include +#endif +#include -#if LL_DBUS_ENABLED -# include "llappviewerlinux_api_dbus.h" - -// regrettable hacks to give us better runtime compatibility with older systems inside llappviewerlinux_api.h: -#define llg_return_if_fail(COND) do{if (!(COND)) return;}while(0) -#undef g_return_if_fail -#define g_return_if_fail(COND) llg_return_if_fail(COND) -// The generated API -# include "llappviewerlinux_api.h" +#if (__GLIBC__*1000 + __GLIBC_MINOR__) >= 2034 +extern "C" +{ + int __res_nquery(res_state statep, + const char *dname, int qclass, int type, + unsigned char *answer, int anslen) + { + return res_nquery( statep, dname, qclass, type, answer, anslen ); + } + + int __dn_expand(const unsigned char *msg, + const unsigned char *eomorig, + const unsigned char *comp_dn, char *exp_dn, + int length) + { + return dn_expand( msg,eomorig,comp_dn,exp_dn,length); + } +} #endif +#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService" +#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI" +#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI" + +static const char * DBUS_SERVER = "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + ""; + +typedef struct +{ + GObject parent; +} ViewerAppAPI; + namespace { int gArgC = 0; @@ -86,6 +117,8 @@ int main( int argc, char **argv ) // install unexpected exception handler gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); + unsetenv( "LD_PRELOAD" ); // Get rid of any preloading, we do not want this to happen during startup of plugins. + bool ok = viewer_app_ptr->init(); if(!ok) { @@ -93,7 +126,7 @@ int main( int argc, char **argv ) return -1; } - // Run the application main loop + // Run the application main loop while (! viewer_app_ptr->frame()) {} @@ -148,7 +181,7 @@ bool LLAppViewerLinux::restoreErrorTrap() } ///////////////////////////////////////// -#if LL_DBUS_ENABLED +#if LL_GLIB typedef struct { @@ -158,101 +191,77 @@ typedef struct static void viewerappapi_init(ViewerAppAPI *server); static void viewerappapi_class_init(ViewerAppAPIClass *klass); -/// - -// regrettable hacks to give us better runtime compatibility with older systems in general -static GType llg_type_register_static_simple_ONCE(GType parent_type, - const gchar *type_name, - guint class_size, - GClassInitFunc class_init, - guint instance_size, - GInstanceInitFunc instance_init, - GTypeFlags flags) -{ - static GTypeInfo type_info; - memset(&type_info, 0, sizeof(type_info)); - - type_info.class_size = class_size; - type_info.class_init = class_init; - type_info.instance_size = instance_size; - type_info.instance_init = instance_init; - - return g_type_register_static(parent_type, type_name, &type_info, flags); -} -#define llg_intern_static_string(S) (S) -#define g_intern_static_string(S) llg_intern_static_string(S) -#define g_type_register_static_simple(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags) llg_type_register_static_simple_ONCE(parent_type, type_name, class_size, class_init, instance_size, instance_init, flags) - G_DEFINE_TYPE(ViewerAppAPI, viewerappapi, G_TYPE_OBJECT); void viewerappapi_class_init(ViewerAppAPIClass *klass) { } -static bool dbus_server_init = false; - -void viewerappapi_init(ViewerAppAPI *server) +static void dispatchSLURL(gchar const *slurl) { - // Connect to the default DBUS, register our service/API. - - if (!dbus_server_init) - { - GError *error = NULL; - - server->connection = lldbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (server->connection) - { - lldbus_g_object_type_install_info(viewerappapi_get_type(), &dbus_glib_viewerapp_object_info); + LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL; - lldbus_g_connection_register_g_object(server->connection, VIEWERAPI_PATH, G_OBJECT(server)); + std::string url = slurl; + LLMediaCtrl* web = NULL; + const bool trusted_browser = false; + LLURLDispatcher::dispatch(url, "", web, trusted_browser); +} - DBusGProxy *serverproxy = lldbus_g_proxy_new_for_name(server->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); +static void DoMethodeCall (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + LL_INFOS() << "DBUS message " << method_name << " from: " << sender << " interface: " << interface_name << LL_ENDL; + const gchar *slurl; - guint request_name_ret_unused; - // akin to org_freedesktop_DBus_request_name - if (lldbus_g_proxy_call(serverproxy, "RequestName", &error, G_TYPE_STRING, VIEWERAPI_SERVICE, G_TYPE_UINT, 0, G_TYPE_INVALID, G_TYPE_UINT, &request_name_ret_unused, G_TYPE_INVALID)) - { - // total success. - dbus_server_init = true; - } - else - { - LL_WARNS() << "Unable to register service name: " << error->message << LL_ENDL; - } + g_variant_get (parameters, "(&s)", &slurl); + dispatchSLURL(slurl); +} - g_object_unref(serverproxy); - } - else +GDBusNodeInfo *gBusNodeInfo = nullptr; +static const GDBusInterfaceVTable interface_vtable = { - g_warning("Unable to connect to dbus: %s", error->message); - } - - if (error) - g_error_free(error); - } + DoMethodeCall + }; +static void busAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ + auto id = g_dbus_connection_register_object(connection, + VIEWERAPI_PATH, + gBusNodeInfo->interfaces[0], + &interface_vtable, + NULL, /* user_data */ + NULL, /* user_data_free_func */ + NULL); /* GError** */ + g_assert (id > 0); } -gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error) +static void nameAcquired(GDBusConnection *connection, const gchar *name, gpointer user_data) { - bool success = false; - - LL_INFOS() << "Was asked to go to slurl: " << slurl << LL_ENDL; +} - std::string url = slurl; - LLMediaCtrl* web = NULL; - const bool trusted_browser = false; - if (LLURLDispatcher::dispatch(url, "", web, trusted_browser)) - { - // bring window to foreground, as it has just been "launched" from a URL - // todo: hmm, how to get there from here? - //xxx->mWindow->bringToFront(); - success = true; - } +static void nameLost(GDBusConnection *connection, const gchar *name, gpointer user_data) +{ - *success_rtn = g_new (gboolean, 1); - (*success_rtn)[0] = (gboolean)success; +} +void viewerappapi_init(ViewerAppAPI *server) +{ + gBusNodeInfo = g_dbus_node_info_new_for_xml (DBUS_SERVER, NULL); + g_assert (gBusNodeInfo != NULL); + + g_bus_own_name(G_BUS_TYPE_SESSION, + VIEWERAPI_SERVICE, + G_BUS_NAME_OWNER_FLAGS_NONE, + busAcquired, + nameAcquired, + nameLost, + NULL, + NULL); - return TRUE; // the invokation succeeded, even if the actual dispatch didn't. } /// @@ -260,13 +269,6 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ //virtual bool LLAppViewerLinux::initSLURLHandler() { - if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME)) - { - return false; // failed - } - - g_type_init(); - //ViewerAppAPI *api_server = (ViewerAppAPI*) g_object_new(viewerappapi_get_type(), NULL); @@ -276,49 +278,49 @@ bool LLAppViewerLinux::initSLURLHandler() //virtual bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) { - if (!grab_dbus_syms(DBUSGLIB_DYLIB_DEFAULT_NAME)) + auto *pBus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, nullptr); + + if( !pBus ) { - return false; // failed + LL_WARNS() << "Getting dbus failed." << LL_ENDL; + return false; } - bool success = false; - DBusGConnection *bus; - GError *error = NULL; - - g_type_init(); + auto pProxy = g_dbus_proxy_new_sync(pBus, G_DBUS_PROXY_FLAGS_NONE, nullptr, + VIEWERAPI_SERVICE, VIEWERAPI_PATH, + VIEWERAPI_INTERFACE, nullptr, nullptr); - bus = lldbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (bus) + if( !pProxy ) { - gboolean rtn = FALSE; - DBusGProxy *remote_object = - lldbus_g_proxy_new_for_name(bus, VIEWERAPI_SERVICE, VIEWERAPI_PATH, VIEWERAPI_INTERFACE); - - if (lldbus_g_proxy_call(remote_object, "GoSLURL", &error, - G_TYPE_STRING, url.c_str(), G_TYPE_INVALID, - G_TYPE_BOOLEAN, &rtn, G_TYPE_INVALID)) - { - success = rtn; - } - else - { - LL_INFOS() << "Call-out to other instance failed (perhaps not running): " << error->message << LL_ENDL; - } - - g_object_unref(G_OBJECT(remote_object)); + LL_WARNS() << "Cannot create new dbus proxy." << LL_ENDL; + g_object_unref( pBus ); + return false; } - else + + auto *pArgs = g_variant_new( "(s)", url.c_str() ); + if( !pArgs ) { - LL_WARNS() << "Couldn't connect to session bus: " << error->message << LL_ENDL; + LL_WARNS() << "Cannot create new variant." << LL_ENDL; + g_object_unref( pBus ); + return false; } - if (error) - g_error_free(error); + auto pRes = g_dbus_proxy_call_sync(pProxy, + "GoSLURL", + pArgs, + G_DBUS_CALL_FLAGS_NONE, + -1, nullptr, nullptr); - return success; + + + if( pRes ) + g_variant_unref( pRes ); + g_object_unref( pProxy ); + g_object_unref( pBus ); + return true; } -#else // LL_DBUS_ENABLED +#else // LL_GLIB bool LLAppViewerLinux::initSLURLHandler() { return false; // not implemented without dbus @@ -327,7 +329,7 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) { return false; // not implemented without dbus } -#endif // LL_DBUS_ENABLED +#endif // LL_GLIB void LLAppViewerLinux::initCrashReporting(bool reportFreeze) { @@ -343,15 +345,18 @@ void LLAppViewerLinux::initCrashReporting(bool reportFreeze) pid_str << LLApp::getPid(); std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); std::string appname = gDirUtilp->getExecutableFilename(); + std::string grid{ LLGridManager::getInstance()->getGridId() }; + std::string title{ LLAppViewer::instance()->getSecondLifeTitle() }; + std::string pidstr{ pid_str.str() }; // launch the actual crash logger const char * cmdargv[] = {cmd.c_str(), "-user", - (char*)LLGridManager::getInstance()->getGridId().c_str(), + grid.c_str(), "-name", - LLAppViewer::instance()->getSecondLifeTitle().c_str(), + title.c_str(), "-pid", - pid_str.str().c_str(), + pidstr.c_str(), "-dumpdir", logdir.c_str(), "-procname", diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index dde223878d..460ca721f1 100644 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -27,17 +27,6 @@ #ifndef LL_LLAPPVIEWERLINUX_H #define LL_LLAPPVIEWERLINUX_H -extern "C" { -# include -} - -#if LL_DBUS_ENABLED -extern "C" { -# include -# include -} -#endif - #ifndef LL_LLAPPVIEWER_H #include "llappviewer.h" #endif @@ -70,21 +59,4 @@ protected: virtual bool sendURLToOtherInstance(const std::string& url); }; -#if LL_DBUS_ENABLED -typedef struct -{ - GObject parent; - DBusGConnection *connection; -} ViewerAppAPI; - -extern "C" { - gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **success_rtn, GError **error); -} - -#define VIEWERAPI_SERVICE "com.secondlife.ViewerAppAPIService" -#define VIEWERAPI_PATH "/com/secondlife/ViewerAppAPI" -#define VIEWERAPI_INTERFACE "com.secondlife.ViewerAppAPI" - -#endif // LL_DBUS_ENABLED - #endif // LL_LLAPPVIEWERLINUX_H diff --git a/indra/newview/llappviewerlinux_api.h b/indra/newview/llappviewerlinux_api.h deleted file mode 100644 index 3d1324dd19..0000000000 --- a/indra/newview/llappviewerlinux_api.h +++ /dev/null @@ -1,143 +0,0 @@ -/* Generated by dbus-binding-tool; do not edit! */ -/** - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef __dbus_glib_marshal_viewerapp_MARSHAL_H__ -#define __dbus_glib_marshal_viewerapp_MARSHAL_H__ - -#include - -G_BEGIN_DECLS - -#ifdef G_ENABLE_DEBUG -#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) -#define g_marshal_value_peek_char(v) g_value_get_char (v) -#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) -#define g_marshal_value_peek_int(v) g_value_get_int (v) -#define g_marshal_value_peek_uint(v) g_value_get_uint (v) -#define g_marshal_value_peek_long(v) g_value_get_long (v) -#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) -#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) -#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) -#define g_marshal_value_peek_enum(v) g_value_get_enum (v) -#define g_marshal_value_peek_flags(v) g_value_get_flags (v) -#define g_marshal_value_peek_float(v) g_value_get_float (v) -#define g_marshal_value_peek_double(v) g_value_get_double (v) -#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) -#define g_marshal_value_peek_param(v) g_value_get_param (v) -#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) -#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) -#define g_marshal_value_peek_object(v) g_value_get_object (v) -#else /* !G_ENABLE_DEBUG */ -/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. - * Do not access GValues directly in your code. Instead, use the - * g_value_get_*() functions - */ -#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int -#define g_marshal_value_peek_char(v) (v)->data[0].v_int -#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint -#define g_marshal_value_peek_int(v) (v)->data[0].v_int -#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint -#define g_marshal_value_peek_long(v) (v)->data[0].v_long -#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 -#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 -#define g_marshal_value_peek_enum(v) (v)->data[0].v_long -#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong -#define g_marshal_value_peek_float(v) (v)->data[0].v_float -#define g_marshal_value_peek_double(v) (v)->data[0].v_double -#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer -#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer -#endif /* !G_ENABLE_DEBUG */ - - -/* BOOLEAN:STRING,POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.5XXD8T:1) */ -extern void dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); -void -dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - typedef gboolean (*GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gpointer arg_3, - gpointer data2); - register GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER callback; - register GCClosure *cc = (GCClosure*) closure; - register gpointer data1, data2; - gboolean v_return; - - g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); - - if (G_CCLOSURE_SWAP_DATA (closure)) - { - data1 = closure->data; - data2 = g_value_peek_pointer (param_values + 0); - } - else - { - data1 = g_value_peek_pointer (param_values + 0); - data2 = closure->data; - } - callback = (GMarshalFunc_BOOLEAN__STRING_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); - - v_return = callback (data1, - g_marshal_value_peek_string (param_values + 1), - g_marshal_value_peek_pointer (param_values + 2), - g_marshal_value_peek_pointer (param_values + 3), - data2); - - g_value_set_boolean (return_value, v_return); -} - -G_END_DECLS - -#endif /* __dbus_glib_marshal_viewerapp_MARSHAL_H__ */ - -#include -static const DBusGMethodInfo dbus_glib_viewerapp_methods[] = { - { (GCallback) viewer_app_api_GoSLURL, dbus_glib_marshal_viewerapp_BOOLEAN__STRING_POINTER_POINTER, 0 }, -}; - -const DBusGObjectInfo dbus_glib_viewerapp_object_info = { - 0, - dbus_glib_viewerapp_methods, - 1, -"com.secondlife.ViewerAppAPI\0GoSLURL\0S\0slurl\0I\0s\0success_ret\0O\0F\0N\0b\0\0\0", -"\0", -"\0" -}; - diff --git a/indra/newview/llappviewerlinux_api.xml b/indra/newview/llappviewerlinux_api.xml deleted file mode 100644 index fac35b7adc..0000000000 --- a/indra/newview/llappviewerlinux_api.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp deleted file mode 100644 index 9aed8a98d4..0000000000 --- a/indra/newview/llappviewerlinux_api_dbus.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @file llappviewerlinux_api_dbus.cpp - * @brief dynamic DBus symbol-grabbing code - * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#if LL_DBUS_ENABLED - -#include "linden_common.h" - -extern "C" { -#include - -#include "apr_pools.h" -#include "apr_dso.h" -} - -#define DEBUGMSG(...) do { LL_DEBUGS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0) -#define INFOMSG(...) do { LL_INFOS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0) -#define WARNMSG(...) do { LL_WARNS() << llformat(__VA_ARGS__) << LL_ENDL; } while(0) - -#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) RTN (*ll##DBUSSYM)(__VA_ARGS__) = NULL -#include "llappviewerlinux_api_dbus_syms_raw.inc" -#undef LL_DBUS_SYM - -static bool sSymsGrabbed = false; -static apr_pool_t *sSymDBUSDSOMemoryPool = NULL; -static apr_dso_handle_t *sSymDBUSDSOHandleG = NULL; - -bool grab_dbus_syms(std::string dbus_dso_name) -{ - if (sSymsGrabbed) - { - // already have grabbed good syms - return true; - } - - bool sym_error = false; - bool rtn = false; - apr_status_t rv; - apr_dso_handle_t *sSymDBUSDSOHandle = NULL; - -#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##DBUSSYM, sSymDBUSDSOHandle, #DBUSSYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #DBUSSYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #DBUSSYM, (void*)ll##DBUSSYM);}while(0) - - //attempt to load the shared library - apr_pool_create(&sSymDBUSDSOMemoryPool, NULL); - - if ( APR_SUCCESS == (rv = apr_dso_load(&sSymDBUSDSOHandle, - dbus_dso_name.c_str(), - sSymDBUSDSOMemoryPool) )) - { - INFOMSG("Found DSO: %s", dbus_dso_name.c_str()); - -#include "llappviewerlinux_api_dbus_syms_raw.inc" - - if ( sSymDBUSDSOHandle ) - { - sSymDBUSDSOHandleG = sSymDBUSDSOHandle; - sSymDBUSDSOHandle = NULL; - } - - rtn = !sym_error; - } - else - { - INFOMSG("Couldn't load DSO: %s", dbus_dso_name.c_str()); - rtn = false; // failure - } - - if (sym_error) - { - WARNMSG("Failed to find necessary symbols in DBUS-GLIB libraries."); - } -#undef LL_DBUS_SYM - - sSymsGrabbed = rtn; - return rtn; -} - - -void ungrab_dbus_syms() -{ - // should be safe to call regardless of whether we've - // actually grabbed syms. - - if ( sSymDBUSDSOHandleG ) - { - apr_dso_unload(sSymDBUSDSOHandleG); - sSymDBUSDSOHandleG = NULL; - } - - if ( sSymDBUSDSOMemoryPool ) - { - apr_pool_destroy(sSymDBUSDSOMemoryPool); - sSymDBUSDSOMemoryPool = NULL; - } - - // NULL-out all of the symbols we'd grabbed -#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) do{ll##DBUSSYM = NULL;}while(0) -#include "llappviewerlinux_api_dbus_syms_raw.inc" -#undef LL_DBUS_SYM - - sSymsGrabbed = false; -} - -#endif // LL_DBUS_ENABLED diff --git a/indra/newview/llappviewerlinux_api_dbus.h b/indra/newview/llappviewerlinux_api_dbus.h deleted file mode 100644 index 2f4492bd7a..0000000000 --- a/indra/newview/llappviewerlinux_api_dbus.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @file llappviewerlinux_api_dbus.h - * @brief DBus-glib symbol handling - * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#if LL_DBUS_ENABLED - -extern "C" { -#include -} - -#define DBUSGLIB_DYLIB_DEFAULT_NAME "libdbus-glib-1.so.2" - -bool grab_dbus_syms(std::string dbus_dso_name); -void ungrab_dbus_syms(); - -#define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) extern RTN (*ll##DBUSSYM)(__VA_ARGS__) -#include "llappviewerlinux_api_dbus_syms_raw.inc" -#undef LL_DBUS_SYM - -#endif // LL_DBUS_ENABLED diff --git a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc b/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc deleted file mode 100644 index c0548e2fba..0000000000 --- a/indra/newview/llappviewerlinux_api_dbus_syms_raw.inc +++ /dev/null @@ -1,9 +0,0 @@ - -// required symbols to grab -LL_DBUS_SYM(true, dbus_g_bus_get, DBusGConnection*, DBusBusType, GError**); -LL_DBUS_SYM(true, dbus_g_proxy_new_for_name, DBusGProxy*, DBusGConnection*, const char *, const char*, const char*); -LL_DBUS_SYM(true, dbus_g_proxy_call, gboolean, DBusGProxy*, const char*, GError**, GType, ...); -LL_DBUS_SYM(true, dbus_g_object_type_install_info, void, GType, const DBusGObjectInfo*); -LL_DBUS_SYM(true, dbus_g_connection_register_g_object, void, DBusGConnection*, const char*, GObject*); - -// optional symbols to grab -- cgit v1.3 From 134a13960831938514e444c84da323da37b443c0 Mon Sep 17 00:00:00 2001 From: Rye Date: Mon, 27 Oct 2025 02:48:36 -0400 Subject: Introduce SDL3 based windowing backend support and dir picker Signed-off-by: Rye --- autobuild.xml | 65 +- indra/cmake/Copy3rdPartyLibs.cmake | 2 +- indra/llwindow/CMakeLists.txt | 97 +- indra/llwindow/llkeyboard.cpp | 18 +- indra/llwindow/llkeyboard.h | 26 +- indra/llwindow/llkeyboardheadless.cpp | 21 +- indra/llwindow/llkeyboardheadless.h | 16 +- indra/llwindow/llkeyboardmacosx.cpp | 13 +- indra/llwindow/llkeyboardmacosx.h | 16 +- indra/llwindow/llkeyboardsdl.cpp | 446 +++- indra/llwindow/llkeyboardsdl.h | 27 +- indra/llwindow/llkeyboardwin32.cpp | 4 +- indra/llwindow/llkeyboardwin32.h | 19 +- indra/llwindow/llmousehandler.cpp | 2 + indra/llwindow/llsdl.cpp | 146 ++ indra/llwindow/llsdl.h | 34 + indra/llwindow/llwindow.cpp | 52 +- indra/llwindow/llwindow.h | 5 +- indra/llwindow/llwindowheadless.h | 2 +- indra/llwindow/llwindowmesaheadless.h | 120 +- indra/llwindow/llwindowsdl.cpp | 2568 +++++++------------- indra/llwindow/llwindowsdl.h | 289 +-- indra/newview/llappviewer.cpp | 7 +- indra/newview/llappviewerlinux.cpp | 250 +- indra/newview/llappviewerlinux.h | 21 +- indra/newview/lldirpicker.cpp | 176 +- indra/newview/lldirpicker.h | 8 + .../llfloaterpreferencesgraphicsadvanced.cpp | 2 +- indra/newview/llviewerwindow.cpp | 5 - indra/newview/llviewerwindow.h | 1 - indra/newview/viewer_manifest.py | 69 +- 31 files changed, 2284 insertions(+), 2243 deletions(-) create mode 100644 indra/llwindow/llsdl.cpp create mode 100644 indra/llwindow/llsdl.h (limited to 'indra/newview/llappviewer.cpp') diff --git a/autobuild.xml b/autobuild.xml index bbd75d9e5a..78b235fabb 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -7,33 +7,65 @@ autobuild installables - SDL + SDL3 platforms + windows64 + + archive + + hash + 121b209bbf8ffb2f7f668a74de0e654f4be7339f + hash_algorithm + sha1 + url + https://github.com/secondlife/3p-sdl3/releases/download/v3.2.24-r1/SDL3-3.2.24-r1-windows64-18539840462.tar.zst + + name + windows64 + linux64 archive hash - 7ea2df03bfc35c06acf23dd9e734adac + 06226c54c57afd601707c0f5f7a2e0736ab1f326 + hash_algorithm + sha1 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1103/2554/SDL-1.2.15-linux64-501092.tar.bz2 + https://github.com/secondlife/3p-sdl3/releases/download/v3.2.24-r1/SDL3-3.2.24-r1-linux64-18539840462.tar.zst name linux64 + darwin64 + + archive + + hash + aff68fb5655629c698e198af1581835267588f77 + hash_algorithm + sha1 + url + https://github.com/secondlife/3p-sdl3/releases/download/v3.2.24-r1/SDL3-3.2.24-r1-darwin64-18539840462.tar.zst + + name + darwin64 + license lgpl license_file - LICENSES/SDL.txt + LICENSES/SDL3.txt copyright - Copyright (C) 1997-2012 Sam Lantinga + Copyright (C) 1997-2022 Sam Lantinga (slouken@libsdl.org) version - 1.2.15 + 3.2.24-r1 + use_scm_version + true name - SDL + SDL3 description Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. @@ -1753,6 +1785,23 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors open-libndofdev + platforms + + linux64 + + archive + + hash + 795d1e60f3e1e9092788214a6750e6506391cac5 + hash_algorithm + sha1 + url + https://github.com/secondlife/3p-open-libndofdev/releases/download/v1.14-r6/open_libndofdev-0.14.18543500856-linux64-18543500856.tar.zst + + name + linux64 + + license BSD license_file @@ -1760,7 +1809,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors copyright Copyright (c) 2008, Jan Ciger (jan.ciger (at) gmail.com) version - 0.14.11968684513 + 0.14.18543500856 name open-libndofdev description diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 3e89118a4e..9760dc653c 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -213,7 +213,7 @@ elseif(LINUX) list( APPEND release_files libSDL3.so libSDL3.so.0 - libSDL3.so.0.2.22 + libSDL3.so.0.2.24 ) endif() diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 08b3df87ab..fe45df4021 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -12,12 +12,14 @@ project(llwindow) include(00-Common) include(DragDrop) +include(Linking) include(LLCommon) include(LLImage) include(LLWindow) include(UI) include(ViewerMiscLibs) include(GLM) +include(SDL3) set(llwindow_SOURCE_FILES llcursortypes.cpp @@ -58,34 +60,24 @@ set(llwindow_LINK_LIBRARIES ll::glm ll::glext ll::uilibraries - ll::SDL ) -# Libraries on which this library depends, needed for Linux builds -# Sort by high-level to low-level -if (LINUX) + +if (USE_SDL_WINDOW) list(APPEND viewer_SOURCE_FILES + llsdl.cpp llkeyboardsdl.cpp llwindowsdl.cpp ) list(APPEND viewer_HEADER_FILES + llsdl.h llkeyboardsdl.h llwindowsdl.h ) - if (BUILD_HEADLESS) - set(llwindowheadless_LINK_LIBRARIES - ${LLCOMMON_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLRENDER_HEADLESS_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLWINDOW_HEADLESS_LIBRARIES} - ${LLXML_LIBRARIES} - fontconfig # For FCInit and other FC* functions. - ) - endif (BUILD_HEADLESS) - -endif (LINUX) + list(APPEND llwindow_LINK_LIBRARIES + ll::SDL3 + ) +endif () if (DARWIN) list(APPEND llwindow_SOURCE_FILES @@ -133,32 +125,51 @@ if (WINDOWS) ) endif (WINDOWS) -if (SOLARIS) - list(APPEND llwindow_SOURCE_FILES - llwindowsolaris.cpp - ) - list(APPEND llwindow_HEADER_FILES - llwindowsolaris.h - ) -endif (SOLARIS) if (BUILD_HEADLESS) set(llwindowheadless_SOURCE_FILES - llwindowmesaheadless.cpp - llmousehandler.cpp - ) + llcursortypes.cpp + llkeyboard.cpp + llkeyboardheadless.cpp + llwindowheadless.cpp + llwindowcallbacks.cpp + llwindow.cpp + llwindowmesaheadless.cpp + llmousehandler.cpp + ) + set(llwindowheadless_HEADER_FILES - llwindowmesaheadless.h - llmousehandler.h - ) + llcursortypes.h + llkeyboard.h + llkeyboardheadless.h + llwindowheadless.h + llwindowcallbacks.h + llwindowmesaheadless.h + llmousehandler.h + ) + add_library (llwindowheadless - ${llwindow_SOURCE_FILES} ${llwindowheadless_SOURCE_FILES} + ${llwindowheadless_HEADER_FILES} ) - set_property(TARGET llwindowheadless - PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1 - ) - target_link_libraries (llwindowheadless ${llwindowheadless_LINK_LIBRARIES} dl) + + target_compile_definitions( llwindowheadless PUBLIC LL_MESA=1 LL_MESA_HEADLESS=1 ) + + target_link_libraries (llwindowheadless + llcommon + llimage + llmath + llrenderheadless + llfilesystem + llxml + ll::glm + ll::glext + ll::zlib-ng + PkgConfig::OSMESA + fontconfig + dl + ) + target_include_directories(llwindowheadless INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) endif (BUILD_HEADLESS) if (llwindow_HEADER_FILES) @@ -172,14 +183,12 @@ endif (llwindow_HEADER_FILES) ${viewer_SOURCE_FILES} ) -if (SDL_FOUND) - set_property(TARGET llwindow - PROPERTY COMPILE_DEFINITIONS LL_SDL=1 - ) -endif (SDL_FOUND) +target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) +target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) - target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) - target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +if (USE_SDL_WINDOW) + target_compile_definitions( llwindow PUBLIC LL_SDL_WINDOW=1 ) +endif() if (DARWIN) target_link_libraries(llwindow ${CARBON_LIBRARY}) diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index 33eebdadd1..761b4a1870 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -41,7 +41,6 @@ std::map LLKeyboard::sKeysToNames; std::map LLKeyboard::sNamesToKeys; LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10n + PC/Mac/Linux accelerator labeling - // // Class Implementation // @@ -162,6 +161,7 @@ void LLKeyboard::resetKeyDownAndHandle() mCallbacks->handleTranslatedKeyUp(i, mask); } } + mCurTranslatedKey = KEY_NONE; } // BUG this has to be called when an OS dialog is shown, otherwise modifier key state @@ -195,12 +195,10 @@ void LLKeyboard::resetKeys() } -bool LLKeyboard::translateKey(const U16 os_key, KEY *out_key) +bool LLKeyboard::translateKey(const NATIVE_KEY_TYPE os_key, KEY *out_key) { - std::map::iterator iter; - // Only translate keys in the map, ignore all other keys for now - iter = mTranslateKeyMap.find(os_key); + auto iter = mTranslateKeyMap.find(os_key); if (iter == mTranslateKeyMap.end()) { //LL_WARNS() << "Unknown virtual key " << os_key << LL_ENDL; @@ -214,11 +212,9 @@ bool LLKeyboard::translateKey(const U16 os_key, KEY *out_key) } } - -U16 LLKeyboard::inverseTranslateKey(const KEY translated_key) +LLKeyboard::NATIVE_KEY_TYPE LLKeyboard::inverseTranslateKey(const KEY translated_key) { - std::map::iterator iter; - iter = mInvTranslateKeyMap.find(translated_key); + auto iter = mInvTranslateKeyMap.find(translated_key); if (iter == mInvTranslateKeyMap.end()) { return 0; @@ -230,7 +226,7 @@ U16 LLKeyboard::inverseTranslateKey(const KEY translated_key) } -bool LLKeyboard::handleTranslatedKeyDown(KEY translated_key, U32 translated_mask) +bool LLKeyboard::handleTranslatedKeyDown(KEY translated_key, MASK translated_mask) { bool handled = false; bool repeated = false; @@ -258,7 +254,7 @@ bool LLKeyboard::handleTranslatedKeyDown(KEY translated_key, U32 translated_mask } -bool LLKeyboard::handleTranslatedKeyUp(KEY translated_key, U32 translated_mask) +bool LLKeyboard::handleTranslatedKeyUp(KEY translated_key, MASK translated_mask) { bool handled = false; if( mKeyLevel[translated_key] ) diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 713eb7aec2..b4ab562cd5 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -55,6 +55,13 @@ class LLWindowCallbacks; class LLKeyboard { public: +#ifdef LL_SDL_WINDOW + // linux relies on SDL2 which uses U32 for its native key type + typedef U32 NATIVE_KEY_TYPE; +#else + // on non-linux platforms we can get by with a smaller native key type + typedef U16 NATIVE_KEY_TYPE; +#endif LLKeyboard(); virtual ~LLKeyboard(); @@ -67,16 +74,15 @@ public: bool getKeyDown(const KEY key) { return mKeyLevel[key]; } bool getKeyRepeated(const KEY key) { return mKeyRepeated[key]; } - bool translateKey(const U16 os_key, KEY *translated_key); - U16 inverseTranslateKey(const KEY translated_key); - bool handleTranslatedKeyUp(KEY translated_key, U32 translated_mask); // Translated into "Linden" keycodes - bool handleTranslatedKeyDown(KEY translated_key, U32 translated_mask); // Translated into "Linden" keycodes - + bool translateKey(const NATIVE_KEY_TYPE os_key, KEY *translated_key); + NATIVE_KEY_TYPE inverseTranslateKey(const KEY translated_key); + bool handleTranslatedKeyUp(KEY translated_key, MASK translated_mask); // Translated into "Linden" keycodes + bool handleTranslatedKeyDown(KEY translated_key, MASK translated_mask); // Translated into "Linden" keycodes - virtual bool handleKeyUp(const U16 key, MASK mask) = 0; - virtual bool handleKeyDown(const U16 key, MASK mask) = 0; + virtual bool handleKeyUp(const NATIVE_KEY_TYPE key, MASK mask) = 0; + virtual bool handleKeyDown(const NATIVE_KEY_TYPE key, MASK mask) = 0; -#ifdef LL_DARWIN +#if LL_DARWIN && !LL_SDL_WINDOW // We only actually use this for macOS. virtual void handleModifier(MASK mask) = 0; #endif // LL_DARWIN @@ -111,8 +117,8 @@ protected: void addKeyName(KEY key, const std::string& name); protected: - std::map mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs - std::map mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys + std::map mTranslateKeyMap; // Map of translations from OS keys to Linden KEYs + std::map mInvTranslateKeyMap; // Map of translations from Linden KEYs to OS keys LLWindowCallbacks *mCallbacks; LLTimer mKeyLevelTimer[KEY_COUNT]; // Time since level was set diff --git a/indra/llwindow/llkeyboardheadless.cpp b/indra/llwindow/llkeyboardheadless.cpp index 8669a5b41a..50d03aaf20 100644 --- a/indra/llwindow/llkeyboardheadless.cpp +++ b/indra/llwindow/llkeyboardheadless.cpp @@ -31,21 +31,23 @@ LLKeyboardHeadless::LLKeyboardHeadless() { } -void LLKeyboardHeadless::resetMaskKeys() -{ } - - -bool LLKeyboardHeadless::handleKeyDown(const U16 key, const U32 mask) -{ return false; } +bool LLKeyboardHeadless::handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) +{ + return false; +} +bool LLKeyboardHeadless::handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) +{ + return false; +} -bool LLKeyboardHeadless::handleKeyUp(const U16 key, const U32 mask) -{ return false; } +void LLKeyboardHeadless::resetMaskKeys() +{ } MASK LLKeyboardHeadless::currentMask(bool for_mouse_event) { return MASK_NONE; } -#ifdef LL_DARWIN +#if LL_DARWIN && !LL_SDL_WINDOW void LLKeyboardHeadless::handleModifier(MASK mask) { @@ -65,6 +67,7 @@ void LLKeyboardHeadless::scanKeyboard() mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); } } + mCurScanKey = KEY_NONE; // Reset edges for next frame for (S32 key = 0; key < KEY_COUNT; key++) diff --git a/indra/llwindow/llkeyboardheadless.h b/indra/llwindow/llkeyboardheadless.h index 2528f0e3f1..364fb03fe7 100644 --- a/indra/llwindow/llkeyboardheadless.h +++ b/indra/llwindow/llkeyboardheadless.h @@ -33,15 +33,15 @@ class LLKeyboardHeadless : public LLKeyboard { public: LLKeyboardHeadless(); - /*virtual*/ ~LLKeyboardHeadless() {}; + ~LLKeyboardHeadless() = default; - /*virtual*/ bool handleKeyUp(const U16 key, MASK mask); - /*virtual*/ bool handleKeyDown(const U16 key, MASK mask); - /*virtual*/ void resetMaskKeys(); - /*virtual*/ MASK currentMask(bool for_mouse_event); - /*virtual*/ void scanKeyboard(); -#ifdef LL_DARWIN - /*virtual*/ void handleModifier(MASK mask); + bool handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override; + bool handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override; + void resetMaskKeys() override; + MASK currentMask(bool for_mouse_event) override; + void scanKeyboard() override; +#if LL_DARWIN && !LL_SDL_WINDOW + void handleModifier(MASK mask) override; #endif }; diff --git a/indra/llwindow/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp index 89ff7c6d3f..1a403e5d94 100644 --- a/indra/llwindow/llkeyboardmacosx.cpp +++ b/indra/llwindow/llkeyboardmacosx.cpp @@ -162,7 +162,7 @@ LLKeyboardMacOSX::LLKeyboardMacOSX() void LLKeyboardMacOSX::resetMaskKeys() { - U32 mask = getModifiers(); + MASK mask = getModifiers(); // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys(). // It looks a bit suspicious, as it won't correct for keys that have been released. @@ -187,7 +187,7 @@ void LLKeyboardMacOSX::resetMaskKeys() } /* -static bool translateKeyMac(const U16 key, const U32 mask, KEY &outKey, U32 &outMask) +static bool translateKeyMac(const U16 key, const MASK mask, KEY &outKey, U32 &outMask) { // Translate the virtual keycode into the keycodes the keyboard system expects. U16 virtualKey = (mask >> 24) & 0x0000007F; @@ -203,7 +203,7 @@ void LLKeyboardMacOSX::handleModifier(MASK mask) updateModifiers(mask); } -MASK LLKeyboardMacOSX::updateModifiers(const U32 mask) +MASK LLKeyboardMacOSX::updateModifiers(const MASK mask) { // translate the mask MASK out_mask = 0; @@ -226,7 +226,7 @@ MASK LLKeyboardMacOSX::updateModifiers(const U32 mask) return out_mask; } -bool LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask) +bool LLKeyboardMacOSX::handleKeyDown(const U16 key, MASK mask) { KEY translated_key = 0; U32 translated_mask = 0; @@ -243,7 +243,7 @@ bool LLKeyboardMacOSX::handleKeyDown(const U16 key, const U32 mask) } -bool LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask) +bool LLKeyboardMacOSX::handleKeyUp(const U16 key, MASK mask) { KEY translated_key = 0; U32 translated_mask = 0; @@ -262,7 +262,7 @@ bool LLKeyboardMacOSX::handleKeyUp(const U16 key, const U32 mask) MASK LLKeyboardMacOSX::currentMask(bool for_mouse_event) { MASK result = MASK_NONE; - U32 mask = getModifiers(); + MASK mask = getModifiers(); if (mask & MAC_SHIFT_KEY) result |= MASK_SHIFT; if (mask & MAC_CTRL_KEY) result |= MASK_CONTROL; @@ -291,6 +291,7 @@ void LLKeyboardMacOSX::scanKeyboard() mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); } } + mCurScanKey = KEY_NONE; // Reset edges for next frame for (key = 0; key < KEY_COUNT; key++) diff --git a/indra/llwindow/llkeyboardmacosx.h b/indra/llwindow/llkeyboardmacosx.h index 92ab5c9a85..c824e7b713 100644 --- a/indra/llwindow/llkeyboardmacosx.h +++ b/indra/llwindow/llkeyboardmacosx.h @@ -42,17 +42,17 @@ class LLKeyboardMacOSX : public LLKeyboard { public: LLKeyboardMacOSX(); - /*virtual*/ ~LLKeyboardMacOSX() {}; + ~LLKeyboardMacOSX() = default; - /*virtual*/ bool handleKeyUp(const U16 key, MASK mask); - /*virtual*/ bool handleKeyDown(const U16 key, MASK mask); - /*virtual*/ void resetMaskKeys(); - /*virtual*/ MASK currentMask(bool for_mouse_event); - /*virtual*/ void scanKeyboard(); - /*virtual*/ void handleModifier(MASK mask); + bool handleKeyUp(const NATIVE_KEY_TYPE key, MASK mask) override; + bool handleKeyDown(const NATIVE_KEY_TYPE key, MASK mask) override; + void resetMaskKeys() override; + MASK currentMask(bool for_mouse_event) override; + void scanKeyboard() override; + void handleModifier(MASK mask) override; protected: - MASK updateModifiers(const U32 mask); + MASK updateModifiers(const MASK mask); void setModifierKeyLevel( KEY key, bool new_state ); bool translateNumpadKey( const U16 os_key, KEY *translated_key ); U16 inverseTranslateNumpadKey(const KEY translated_key); diff --git a/indra/llwindow/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp index 97198f0cc0..803a5b8c23 100644 --- a/indra/llwindow/llkeyboardsdl.cpp +++ b/indra/llwindow/llkeyboardsdl.cpp @@ -24,12 +24,11 @@ * $/LicenseInfo$ */ -#if LL_SDL - #include "linden_common.h" #include "llkeyboardsdl.h" #include "llwindowcallbacks.h" -#include "SDL/SDL.h" + +#include "SDL3/SDL_keycode.h" LLKeyboardSDL::LLKeyboardSDL() { @@ -40,7 +39,7 @@ LLKeyboardSDL::LLKeyboardSDL() // Virtual key mappings from SDL_keysym.h ... // SDL maps the letter keys to the ASCII you'd expect, but it's lowercase... - U16 cur_char; + LLKeyboard::NATIVE_KEY_TYPE cur_char; for (cur_char = 'A'; cur_char <= 'Z'; cur_char++) { mTranslateKeyMap[cur_char] = cur_char; @@ -74,7 +73,6 @@ LLKeyboardSDL::LLKeyboardSDL() mTranslateKeyMap[SDLK_RIGHT] = KEY_RIGHT; mTranslateKeyMap[SDLK_UP] = KEY_UP; mTranslateKeyMap[SDLK_DOWN] = KEY_DOWN; - mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE; mTranslateKeyMap[SDLK_KP_ENTER] = KEY_RETURN; mTranslateKeyMap[SDLK_ESCAPE] = KEY_ESCAPE; mTranslateKeyMap[SDLK_BACKSPACE] = KEY_BACKSPACE; @@ -115,36 +113,35 @@ LLKeyboardSDL::LLKeyboardSDL() mTranslateKeyMap[SDLK_COMMA] = ','; mTranslateKeyMap[SDLK_MINUS] = '-'; mTranslateKeyMap[SDLK_PERIOD] = '.'; - mTranslateKeyMap[SDLK_BACKQUOTE] = '`'; + mTranslateKeyMap[SDLK_GRAVE] = '`'; mTranslateKeyMap[SDLK_SLASH] = KEY_DIVIDE; mTranslateKeyMap[SDLK_SEMICOLON] = ';'; mTranslateKeyMap[SDLK_LEFTBRACKET] = '['; mTranslateKeyMap[SDLK_BACKSLASH] = '\\'; mTranslateKeyMap[SDLK_RIGHTBRACKET] = ']'; - mTranslateKeyMap[SDLK_QUOTE] = '\''; + mTranslateKeyMap[SDLK_APOSTROPHE] = '\''; // Build inverse map - std::map::iterator iter; - for (iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) + for (auto iter = mTranslateKeyMap.begin(); iter != mTranslateKeyMap.end(); iter++) { mInvTranslateKeyMap[iter->second] = iter->first; } // numpad map - mTranslateNumpadMap[SDLK_KP0] = KEY_PAD_INS; - mTranslateNumpadMap[SDLK_KP1] = KEY_PAD_END; - mTranslateNumpadMap[SDLK_KP2] = KEY_PAD_DOWN; - mTranslateNumpadMap[SDLK_KP3] = KEY_PAD_PGDN; - mTranslateNumpadMap[SDLK_KP4] = KEY_PAD_LEFT; - mTranslateNumpadMap[SDLK_KP5] = KEY_PAD_CENTER; - mTranslateNumpadMap[SDLK_KP6] = KEY_PAD_RIGHT; - mTranslateNumpadMap[SDLK_KP7] = KEY_PAD_HOME; - mTranslateNumpadMap[SDLK_KP8] = KEY_PAD_UP; - mTranslateNumpadMap[SDLK_KP9] = KEY_PAD_PGUP; + mTranslateNumpadMap[SDLK_KP_0] = KEY_PAD_INS; + mTranslateNumpadMap[SDLK_KP_1] = KEY_PAD_END; + mTranslateNumpadMap[SDLK_KP_2] = KEY_PAD_DOWN; + mTranslateNumpadMap[SDLK_KP_3] = KEY_PAD_PGDN; + mTranslateNumpadMap[SDLK_KP_4] = KEY_PAD_LEFT; + mTranslateNumpadMap[SDLK_KP_5] = KEY_PAD_CENTER; + mTranslateNumpadMap[SDLK_KP_6] = KEY_PAD_RIGHT; + mTranslateNumpadMap[SDLK_KP_7] = KEY_PAD_HOME; + mTranslateNumpadMap[SDLK_KP_8] = KEY_PAD_UP; + mTranslateNumpadMap[SDLK_KP_9] = KEY_PAD_PGUP; mTranslateNumpadMap[SDLK_KP_PERIOD] = KEY_PAD_DEL; // build inverse numpad map - for (iter = mTranslateNumpadMap.begin(); + for (auto iter = mTranslateNumpadMap.begin(); iter != mTranslateNumpadMap.end(); iter++) { @@ -154,45 +151,45 @@ LLKeyboardSDL::LLKeyboardSDL() void LLKeyboardSDL::resetMaskKeys() { - SDLMod mask = SDL_GetModState(); + SDL_Keymod mask = SDL_GetModState(); // MBW -- XXX -- This mirrors the operation of the Windows version of resetMaskKeys(). // It looks a bit suspicious, as it won't correct for keys that have been released. // Is this the way it's supposed to work? - if(mask & KMOD_SHIFT) + if(mask & SDL_KMOD_SHIFT) { mKeyLevel[KEY_SHIFT] = true; } - if(mask & KMOD_CTRL) + if(mask & SDL_KMOD_CTRL) { mKeyLevel[KEY_CONTROL] = true; } - if(mask & KMOD_ALT) + if(mask & SDL_KMOD_ALT) { mKeyLevel[KEY_ALT] = true; } } -MASK LLKeyboardSDL::updateModifiers(const U32 mask) +MASK LLKeyboardSDL::updateModifiers(const MASK mask) { // translate the mask MASK out_mask = MASK_NONE; - if(mask & KMOD_SHIFT) + if(mask & SDL_KMOD_SHIFT) { out_mask |= MASK_SHIFT; } - if(mask & KMOD_CTRL) + if(mask & SDL_KMOD_CTRL) { out_mask |= MASK_CONTROL; } - if(mask & KMOD_ALT) + if(mask & SDL_KMOD_ALT) { out_mask |= MASK_ALT; } @@ -201,37 +198,37 @@ MASK LLKeyboardSDL::updateModifiers(const U32 mask) } -static U16 adjustNativekeyFromUnhandledMask(const U16 key, const U32 mask) +LLKeyboard::NATIVE_KEY_TYPE adjustNativekeyFromUnhandledMask(const LLKeyboard::NATIVE_KEY_TYPE key, const MASK mask) { // SDL doesn't automatically adjust the keysym according to // whether NUMLOCK is engaged, so we massage the keysym manually. - U16 rtn = key; - if (!(mask & KMOD_NUM)) + LLKeyboard::NATIVE_KEY_TYPE rtn = key; + if (!(mask & SDL_KMOD_NUM)) { switch (key) { - case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; - case SDLK_KP0: rtn = SDLK_INSERT; break; - case SDLK_KP1: rtn = SDLK_END; break; - case SDLK_KP2: rtn = SDLK_DOWN; break; - case SDLK_KP3: rtn = SDLK_PAGEDOWN; break; - case SDLK_KP4: rtn = SDLK_LEFT; break; - case SDLK_KP6: rtn = SDLK_RIGHT; break; - case SDLK_KP7: rtn = SDLK_HOME; break; - case SDLK_KP8: rtn = SDLK_UP; break; - case SDLK_KP9: rtn = SDLK_PAGEUP; break; + case SDLK_KP_PERIOD: rtn = SDLK_DELETE; break; + case SDLK_KP_0: rtn = SDLK_INSERT; break; + case SDLK_KP_1: rtn = SDLK_END; break; + case SDLK_KP_2: rtn = SDLK_DOWN; break; + case SDLK_KP_3: rtn = SDLK_PAGEDOWN; break; + case SDLK_KP_4: rtn = SDLK_LEFT; break; + case SDLK_KP_6: rtn = SDLK_RIGHT; break; + case SDLK_KP_7: rtn = SDLK_HOME; break; + case SDLK_KP_8: rtn = SDLK_UP; break; + case SDLK_KP_9: rtn = SDLK_PAGEUP; break; } } return rtn; } -bool LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask) +bool LLKeyboardSDL::handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, const MASK mask) { - U16 adjusted_nativekey; + LLKeyboard::NATIVE_KEY_TYPE adjusted_nativekey; KEY translated_key = 0; - U32 translated_mask = MASK_NONE; - bool handled = false; + MASK translated_mask = MASK_NONE; + bool handled = false; adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask); @@ -246,12 +243,12 @@ bool LLKeyboardSDL::handleKeyDown(const U16 key, const U32 mask) } -bool LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask) +bool LLKeyboardSDL::handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, const MASK mask) { - U16 adjusted_nativekey; + LLKeyboard::NATIVE_KEY_TYPE adjusted_nativekey; KEY translated_key = 0; U32 translated_mask = MASK_NONE; - bool handled = false; + bool handled = false; adjusted_nativekey = adjustNativekeyFromUnhandledMask(key, mask); @@ -268,16 +265,20 @@ bool LLKeyboardSDL::handleKeyUp(const U16 key, const U32 mask) MASK LLKeyboardSDL::currentMask(bool for_mouse_event) { MASK result = MASK_NONE; - SDLMod mask = SDL_GetModState(); + SDL_Keymod mask = SDL_GetModState(); - if (mask & KMOD_SHIFT) result |= MASK_SHIFT; - if (mask & KMOD_CTRL) result |= MASK_CONTROL; - if (mask & KMOD_ALT) result |= MASK_ALT; + if (mask & SDL_KMOD_SHIFT) + result |= MASK_SHIFT; + if (mask & SDL_KMOD_CTRL) + result |= MASK_CONTROL; + if (mask & SDL_KMOD_ALT) + result |= MASK_ALT; // For keyboard events, consider Meta keys equivalent to Control if (!for_mouse_event) { - if (mask & KMOD_META) result |= MASK_CONTROL; + if (mask & SDL_KMOD_GUI) + result |= MASK_CONTROL; } return result; @@ -296,6 +297,7 @@ void LLKeyboardSDL::scanKeyboard() mCallbacks->handleScanKey(key, mKeyDown[key], mKeyUp[key], mKeyLevel[key]); } } + mCurScanKey = KEY_NONE; // Reset edges for next frame for (S32 key = 0; key < KEY_COUNT; key++) @@ -310,15 +312,347 @@ void LLKeyboardSDL::scanKeyboard() } -bool LLKeyboardSDL::translateNumpadKey( const U16 os_key, KEY *translated_key) +bool LLKeyboardSDL::translateNumpadKey( const LLKeyboard::NATIVE_KEY_TYPE os_key, KEY *translated_key) { return translateKey(os_key, translated_key); } -U16 LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key) +LLKeyboard::NATIVE_KEY_TYPE LLKeyboardSDL::inverseTranslateNumpadKey(const KEY translated_key) { return inverseTranslateKey(translated_key); } -#endif +enum class WindowsVK : U32 +{ + LL_VK_UNKNOWN = 0, + LL_VK_CANCEL = 0x03, + LL_VK_BACK = 0x08, + LL_VK_TAB = 0x09, + LL_VK_CLEAR = 0x0C, + LL_VK_RETURN = 0x0D, + LL_VK_SHIFT = 0x10, + LL_VK_CONTROL = 0x11, + LL_VK_MENU = 0x12, + LL_VK_PAUSE = 0x13, + LL_VK_CAPITAL = 0x14, + LL_VK_KANA = 0x15, + LL_VK_HANGUL = 0x15, + LL_VK_JUNJA = 0x17, + LL_VK_FINAL = 0x18, + LL_VK_HANJA = 0x19, + LL_VK_KANJI = 0x19, + LL_VK_ESCAPE = 0x1B, + LL_VK_CONVERT = 0x1C, + LL_VK_NONCONVERT = 0x1D, + LL_VK_ACCEPT = 0x1E, + LL_VK_MODECHANGE = 0x1F, + LL_VK_SPACE = 0x20, + LL_VK_PRIOR = 0x21, + LL_VK_NEXT = 0x22, + LL_VK_END = 0x23, + LL_VK_HOME = 0x24, + LL_VK_LEFT = 0x25, + LL_VK_UP = 0x26, + LL_VK_RIGHT = 0x27, + LL_VK_DOWN = 0x28, + LL_VK_SELECT = 0x29, + LL_VK_PRINT = 0x2A, + LL_VK_EXECUTE = 0x2B, + LL_VK_SNAPSHOT = 0x2C, + LL_VK_INSERT = 0x2D, + LL_VK_DELETE = 0x2E, + LL_VK_HELP = 0x2F, + LL_VK_0 = 0x30, + LL_VK_1 = 0x31, + LL_VK_2 = 0x32, + LL_VK_3 = 0x33, + LL_VK_4 = 0x34, + LL_VK_5 = 0x35, + LL_VK_6 = 0x36, + LL_VK_7 = 0x37, + LL_VK_8 = 0x38, + LL_VK_9 = 0x39, + LL_VK_A = 0x41, + LL_VK_B = 0x42, + LL_VK_C = 0x43, + LL_VK_D = 0x44, + LL_VK_E = 0x45, + LL_VK_F = 0x46, + LL_VK_G = 0x47, + LL_VK_H = 0x48, + LL_VK_I = 0x49, + LL_VK_J = 0x4A, + LL_VK_K = 0x4B, + LL_VK_L = 0x4C, + LL_VK_M = 0x4D, + LL_VK_N = 0x4E, + LL_VK_O = 0x4F, + LL_VK_P = 0x50, + LL_VK_Q = 0x51, + LL_VK_R = 0x52, + LL_VK_S = 0x53, + LL_VK_T = 0x54, + LL_VK_U = 0x55, + LL_VK_V = 0x56, + LL_VK_W = 0x57, + LL_VK_X = 0x58, + LL_VK_Y = 0x59, + LL_VK_Z = 0x5A, + LL_VK_LWIN = 0x5B, + LL_VK_RWIN = 0x5C, + LL_VK_APPS = 0x5D, + LL_VK_SLEEP = 0x5F, + LL_VK_NUMPAD0 = 0x60, + LL_VK_NUMPAD1 = 0x61, + LL_VK_NUMPAD2 = 0x62, + LL_VK_NUMPAD3 = 0x63, + LL_VK_NUMPAD4 = 0x64, + LL_VK_NUMPAD5 = 0x65, + LL_VK_NUMPAD6 = 0x66, + LL_VK_NUMPAD7 = 0x67, + LL_VK_NUMPAD8 = 0x68, + LL_VK_NUMPAD9 = 0x69, + LL_VK_MULTIPLY = 0x6A, + LL_VK_ADD = 0x6B, + LL_VK_SEPARATOR = 0x6C, + LL_VK_SUBTRACT = 0x6D, + LL_VK_DECIMAL = 0x6E, + LL_VK_DIVIDE = 0x6F, + LL_VK_F1 = 0x70, + LL_VK_F2 = 0x71, + LL_VK_F3 = 0x72, + LL_VK_F4 = 0x73, + LL_VK_F5 = 0x74, + LL_VK_F6 = 0x75, + LL_VK_F7 = 0x76, + LL_VK_F8 = 0x77, + LL_VK_F9 = 0x78, + LL_VK_F10 = 0x79, + LL_VK_F11 = 0x7A, + LL_VK_F12 = 0x7B, + LL_VK_F13 = 0x7C, + LL_VK_F14 = 0x7D, + LL_VK_F15 = 0x7E, + LL_VK_F16 = 0x7F, + LL_VK_F17 = 0x80, + LL_VK_F18 = 0x81, + LL_VK_F19 = 0x82, + LL_VK_F20 = 0x83, + LL_VK_F21 = 0x84, + LL_VK_F22 = 0x85, + LL_VK_F23 = 0x86, + LL_VK_F24 = 0x87, + LL_VK_NUMLOCK = 0x90, + LL_VK_SCROLL = 0x91, + LL_VK_LSHIFT = 0xA0, + LL_VK_RSHIFT = 0xA1, + LL_VK_LCONTROL = 0xA2, + LL_VK_RCONTROL = 0xA3, + LL_VK_LMENU = 0xA4, + LL_VK_RMENU = 0xA5, + LL_VK_BROWSER_BACK = 0xA6, + LL_VK_BROWSER_FORWARD = 0xA7, + LL_VK_BROWSER_REFRESH = 0xA8, + LL_VK_BROWSER_STOP = 0xA9, + LL_VK_BROWSER_SEARCH = 0xAA, + LL_VK_BROWSER_FAVORITES = 0xAB, + LL_VK_BROWSER_HOME = 0xAC, + LL_VK_VOLUME_MUTE = 0xAD, + LL_VK_VOLUME_DOWN = 0xAE, + LL_VK_VOLUME_UP = 0xAF, + LL_VK_MEDIA_NEXT_TRACK = 0xB0, + LL_VK_MEDIA_PREV_TRACK = 0xB1, + LL_VK_MEDIA_STOP = 0xB2, + LL_VK_MEDIA_PLAY_PAUSE = 0xB3, + LL_VK_MEDIA_LAUNCH_MAIL = 0xB4, + LL_VK_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5, + LL_VK_MEDIA_LAUNCH_APP1 = 0xB6, + LL_VK_MEDIA_LAUNCH_APP2 = 0xB7, + LL_VK_OEM_1 = 0xBA, + LL_VK_OEM_PLUS = 0xBB, + LL_VK_OEM_COMMA = 0xBC, + LL_VK_OEM_MINUS = 0xBD, + LL_VK_OEM_PERIOD = 0xBE, + LL_VK_OEM_2 = 0xBF, + LL_VK_OEM_3 = 0xC0, + LL_VK_OEM_4 = 0xDB, + LL_VK_OEM_5 = 0xDC, + LL_VK_OEM_6 = 0xDD, + LL_VK_OEM_7 = 0xDE, + LL_VK_OEM_8 = 0xDF, + LL_VK_OEM_102 = 0xE2, + LL_VK_PROCESSKEY = 0xE5, + LL_VK_PACKET = 0xE7, + LL_VK_ATTN = 0xF6, + LL_VK_CRSEL = 0xF7, + LL_VK_EXSEL = 0xF8, + LL_VK_EREOF = 0xF9, + LL_VK_PLAY = 0xFA, + LL_VK_ZOOM = 0xFB, + LL_VK_NONAME = 0xFC, + LL_VK_PA1 = 0xFD, + LL_VK_OEM_CLEAR = 0xFE, +}; + +std::map< U32, U32 > mSDL2_to_Win; + +U32 LLKeyboardSDL::mapSDL2toWin( U32 aSymbol ) +{ + // Map SDLK_ virtual keys to Windows LL_VK_ virtual keys. + // Text is handled via unicode input (SDL_TEXTINPUT event) and does not need to be translated into LL_VK_ values as those match already. + if( mSDL2_to_Win.empty() ) + { + + mSDL2_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::LL_VK_BACK; + mSDL2_to_Win[ SDLK_TAB ] = (U32)WindowsVK::LL_VK_TAB; + mSDL2_to_Win[ 12 ] = (U32)WindowsVK::LL_VK_CLEAR; + mSDL2_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::LL_VK_RETURN; + mSDL2_to_Win[ 19 ] = (U32)WindowsVK::LL_VK_PAUSE; + mSDL2_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::LL_VK_ESCAPE; + mSDL2_to_Win[ SDLK_SPACE ] = (U32)WindowsVK::LL_VK_SPACE; + mSDL2_to_Win[ SDLK_APOSTROPHE ] = (U32)WindowsVK::LL_VK_OEM_7; + mSDL2_to_Win[ SDLK_COMMA ] = (U32)WindowsVK::LL_VK_OEM_COMMA; + mSDL2_to_Win[ SDLK_MINUS ] = (U32)WindowsVK::LL_VK_OEM_MINUS; + mSDL2_to_Win[ SDLK_PERIOD ] = (U32)WindowsVK::LL_VK_OEM_PERIOD; + mSDL2_to_Win[ SDLK_SLASH ] = (U32)WindowsVK::LL_VK_OEM_2; + + mSDL2_to_Win[ SDLK_0 ] = (U32)WindowsVK::LL_VK_0; + mSDL2_to_Win[ SDLK_1 ] = (U32)WindowsVK::LL_VK_1; + mSDL2_to_Win[ SDLK_2 ] = (U32)WindowsVK::LL_VK_2; + mSDL2_to_Win[ SDLK_3 ] = (U32)WindowsVK::LL_VK_3; + mSDL2_to_Win[ SDLK_4 ] = (U32)WindowsVK::LL_VK_4; + mSDL2_to_Win[ SDLK_5 ] = (U32)WindowsVK::LL_VK_5; + mSDL2_to_Win[ SDLK_6 ] = (U32)WindowsVK::LL_VK_6; + mSDL2_to_Win[ SDLK_7 ] = (U32)WindowsVK::LL_VK_7; + mSDL2_to_Win[ SDLK_8 ] = (U32)WindowsVK::LL_VK_8; + mSDL2_to_Win[ SDLK_9 ] = (U32)WindowsVK::LL_VK_9; + + mSDL2_to_Win[ SDLK_SEMICOLON ] = (U32)WindowsVK::LL_VK_OEM_1; + mSDL2_to_Win[ SDLK_LESS ] = (U32)WindowsVK::LL_VK_OEM_102; + mSDL2_to_Win[ SDLK_EQUALS ] = (U32)WindowsVK::LL_VK_OEM_PLUS; + mSDL2_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::LL_VK_OEM_PLUS; + + mSDL2_to_Win[ SDLK_LEFTBRACKET ] = (U32)WindowsVK::LL_VK_OEM_4; + mSDL2_to_Win[ SDLK_BACKSLASH ] = (U32)WindowsVK::LL_VK_OEM_5; + mSDL2_to_Win[ SDLK_RIGHTBRACKET ] = (U32)WindowsVK::LL_VK_OEM_6; + mSDL2_to_Win[ SDLK_GRAVE ] = (U32)WindowsVK::LL_VK_OEM_8; + + mSDL2_to_Win[ SDLK_A ] = (U32)WindowsVK::LL_VK_A; + mSDL2_to_Win[ SDLK_B ] = (U32)WindowsVK::LL_VK_B; + mSDL2_to_Win[ SDLK_C ] = (U32)WindowsVK::LL_VK_C; + mSDL2_to_Win[ SDLK_D ] = (U32)WindowsVK::LL_VK_D; + mSDL2_to_Win[ SDLK_E ] = (U32)WindowsVK::LL_VK_E; + mSDL2_to_Win[ SDLK_F ] = (U32)WindowsVK::LL_VK_F; + mSDL2_to_Win[ SDLK_G ] = (U32)WindowsVK::LL_VK_G; + mSDL2_to_Win[ SDLK_H ] = (U32)WindowsVK::LL_VK_H; + mSDL2_to_Win[ SDLK_I ] = (U32)WindowsVK::LL_VK_I; + mSDL2_to_Win[ SDLK_J ] = (U32)WindowsVK::LL_VK_J; + mSDL2_to_Win[ SDLK_K ] = (U32)WindowsVK::LL_VK_K; + mSDL2_to_Win[ SDLK_L ] = (U32)WindowsVK::LL_VK_L; + mSDL2_to_Win[ SDLK_M ] = (U32)WindowsVK::LL_VK_M; + mSDL2_to_Win[ SDLK_N ] = (U32)WindowsVK::LL_VK_N; + mSDL2_to_Win[ SDLK_O ] = (U32)WindowsVK::LL_VK_O; + mSDL2_to_Win[ SDLK_P ] = (U32)WindowsVK::LL_VK_P; + mSDL2_to_Win[ SDLK_Q ] = (U32)WindowsVK::LL_VK_Q; + mSDL2_to_Win[ SDLK_R ] = (U32)WindowsVK::LL_VK_R; + mSDL2_to_Win[ SDLK_S ] = (U32)WindowsVK::LL_VK_S; + mSDL2_to_Win[ SDLK_T ] = (U32)WindowsVK::LL_VK_T; + mSDL2_to_Win[ SDLK_Y ] = (U32)WindowsVK::LL_VK_U; + mSDL2_to_Win[ SDLK_V ] = (U32)WindowsVK::LL_VK_V; + mSDL2_to_Win[ SDLK_W ] = (U32)WindowsVK::LL_VK_W; + mSDL2_to_Win[ SDLK_X ] = (U32)WindowsVK::LL_VK_X; + mSDL2_to_Win[ SDLK_Y ] = (U32)WindowsVK::LL_VK_Y; + mSDL2_to_Win[ SDLK_Z ] = (U32)WindowsVK::LL_VK_Z; + + mSDL2_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::LL_VK_DELETE; + + + mSDL2_to_Win[ SDLK_NUMLOCKCLEAR ] = (U32)WindowsVK::LL_VK_NUMLOCK; + mSDL2_to_Win[ SDLK_SCROLLLOCK ] = (U32)WindowsVK::LL_VK_SCROLL; + + mSDL2_to_Win[ SDLK_HELP ] = (U32)WindowsVK::LL_VK_HELP; + mSDL2_to_Win[ SDLK_PRINTSCREEN ] = (U32)WindowsVK::LL_VK_SNAPSHOT; + mSDL2_to_Win[ SDLK_CANCEL ] = (U32)WindowsVK::LL_VK_CANCEL; + mSDL2_to_Win[ SDLK_APPLICATION ] = (U32)WindowsVK::LL_VK_APPS; + + mSDL2_to_Win[ SDLK_UNKNOWN ] = (U32)WindowsVK::LL_VK_UNKNOWN; + mSDL2_to_Win[ SDLK_BACKSPACE ] = (U32)WindowsVK::LL_VK_BACK; + mSDL2_to_Win[ SDLK_TAB ] = (U32)WindowsVK::LL_VK_TAB; + mSDL2_to_Win[ SDLK_CLEAR ] = (U32)WindowsVK::LL_VK_CLEAR; + mSDL2_to_Win[ SDLK_RETURN ] = (U32)WindowsVK::LL_VK_RETURN; + mSDL2_to_Win[ SDLK_PAUSE ] = (U32)WindowsVK::LL_VK_PAUSE; + mSDL2_to_Win[ SDLK_ESCAPE ] = (U32)WindowsVK::LL_VK_ESCAPE; + mSDL2_to_Win[ SDLK_DELETE ] = (U32)WindowsVK::LL_VK_DELETE; + + mSDL2_to_Win[ SDLK_KP_PERIOD ] = (U32)WindowsVK::LL_VK_DELETE; // LL_VK_DECIMAL? + mSDL2_to_Win[ SDLK_KP_DIVIDE ] = (U32)WindowsVK::LL_VK_DIVIDE; + mSDL2_to_Win[ SDLK_KP_MULTIPLY] = (U32)WindowsVK::LL_VK_MULTIPLY; + mSDL2_to_Win[ SDLK_KP_MINUS ] = (U32)WindowsVK::LL_VK_OEM_MINUS; // LL_VK_SUBSTRACT? + mSDL2_to_Win[ SDLK_KP_PLUS ] = (U32)WindowsVK::LL_VK_OEM_PLUS; // LL_VK_ADD? + mSDL2_to_Win[ SDLK_KP_ENTER ] = (U32)WindowsVK::LL_VK_RETURN; + mSDL2_to_Win[ SDLK_KP_0 ] = (U32)WindowsVK::LL_VK_INSERT; + mSDL2_to_Win[ SDLK_KP_1 ] = (U32)WindowsVK::LL_VK_END; + mSDL2_to_Win[ SDLK_KP_2 ] = (U32)WindowsVK::LL_VK_DOWN; + mSDL2_to_Win[ SDLK_KP_3 ] = (U32)WindowsVK::LL_VK_NEXT; + mSDL2_to_Win[ SDLK_KP_4 ] = (U32)WindowsVK::LL_VK_LEFT; + mSDL2_to_Win[ SDLK_KP_5 ] = (U32)WindowsVK::LL_VK_NUMPAD5; + mSDL2_to_Win[ SDLK_KP_6 ] = (U32)WindowsVK::LL_VK_RIGHT; + mSDL2_to_Win[ SDLK_KP_7 ] = (U32)WindowsVK::LL_VK_HOME; + mSDL2_to_Win[ SDLK_KP_8 ] = (U32)WindowsVK::LL_VK_UP; + mSDL2_to_Win[ SDLK_KP_9 ] = (U32)WindowsVK::LL_VK_PRIOR; + + // ? + + mSDL2_to_Win[ SDLK_UP ] = (U32)WindowsVK::LL_VK_UP; + mSDL2_to_Win[ SDLK_DOWN ] = (U32)WindowsVK::LL_VK_DOWN; + mSDL2_to_Win[ SDLK_RIGHT ] = (U32)WindowsVK::LL_VK_RIGHT; + mSDL2_to_Win[ SDLK_LEFT ] = (U32)WindowsVK::LL_VK_LEFT; + mSDL2_to_Win[ SDLK_INSERT ] = (U32)WindowsVK::LL_VK_INSERT; + mSDL2_to_Win[ SDLK_HOME ] = (U32)WindowsVK::LL_VK_HOME; + mSDL2_to_Win[ SDLK_END ] = (U32)WindowsVK::LL_VK_END; + mSDL2_to_Win[ SDLK_PAGEUP ] = (U32)WindowsVK::LL_VK_PRIOR; + mSDL2_to_Win[ SDLK_PAGEDOWN ] = (U32)WindowsVK::LL_VK_NEXT; + mSDL2_to_Win[ SDLK_F1 ] = (U32)WindowsVK::LL_VK_F1; + mSDL2_to_Win[ SDLK_F2 ] = (U32)WindowsVK::LL_VK_F2; + mSDL2_to_Win[ SDLK_F3 ] = (U32)WindowsVK::LL_VK_F3; + mSDL2_to_Win[ SDLK_F4 ] = (U32)WindowsVK::LL_VK_F4; + mSDL2_to_Win[ SDLK_F5 ] = (U32)WindowsVK::LL_VK_F5; + mSDL2_to_Win[ SDLK_F6 ] = (U32)WindowsVK::LL_VK_F6; + mSDL2_to_Win[ SDLK_F7 ] = (U32)WindowsVK::LL_VK_F7; + mSDL2_to_Win[ SDLK_F8 ] = (U32)WindowsVK::LL_VK_F8; + mSDL2_to_Win[ SDLK_F9 ] = (U32)WindowsVK::LL_VK_F9; + mSDL2_to_Win[ SDLK_F10 ] = (U32)WindowsVK::LL_VK_F10; + mSDL2_to_Win[ SDLK_F11 ] = (U32)WindowsVK::LL_VK_F11; + mSDL2_to_Win[ SDLK_F12 ] = (U32)WindowsVK::LL_VK_F12; + mSDL2_to_Win[ SDLK_F13 ] = (U32)WindowsVK::LL_VK_F13; + mSDL2_to_Win[ SDLK_F14 ] = (U32)WindowsVK::LL_VK_F14; + mSDL2_to_Win[ SDLK_F15 ] = (U32)WindowsVK::LL_VK_F15; + mSDL2_to_Win[ SDLK_CAPSLOCK ] = (U32)WindowsVK::LL_VK_CAPITAL; + mSDL2_to_Win[ SDLK_RSHIFT ] = (U32)WindowsVK::LL_VK_SHIFT; + mSDL2_to_Win[ SDLK_LSHIFT ] = (U32)WindowsVK::LL_VK_SHIFT; + mSDL2_to_Win[ SDLK_RCTRL ] = (U32)WindowsVK::LL_VK_CONTROL; + mSDL2_to_Win[ SDLK_LCTRL ] = (U32)WindowsVK::LL_VK_CONTROL; + mSDL2_to_Win[ SDLK_RALT ] = (U32)WindowsVK::LL_VK_MENU; + mSDL2_to_Win[ SDLK_LALT ] = (U32)WindowsVK::LL_VK_MENU; + + mSDL2_to_Win[ SDLK_MENU ] = (U32)WindowsVK::LL_VK_MENU; + + // LL_VK_MODECHANGE ? + // mSDL2_to_Win[ SDLK_MODE ] = (U32)WindowsVK::LL_VK_MODE; + + // ? + // mSDL2_to_Win[ SDLK_SYSREQ ] = (U32)WindowsVK::LL_VK_SYSREQ; + // mSDL2_to_Win[ SDLK_POWER ] = (U32)WindowsVK::LL_VK_POWER; + // mSDL2_to_Win[ SDLK_UNDO ] = (U32)WindowsVK::LL_VK_UNDO; + // mSDL2_to_Win[ SDLK_KP_EQUALS ] = (U32)WindowsVK::LL_VK_EQUALS; + // mSDL2_to_Win[ 311 ] = (U32)WindowsVK::LL_VK_LWIN; + // mSDL2_to_Win[ 312 ] = (U32)WindowsVK::LL_VK_RWIN; + // mSDL2_to_Win[ SDLK_COLON ] = ? + } + auto itr = mSDL2_to_Win.find( aSymbol ); + if( itr != mSDL2_to_Win.end() ) + return itr->second; + + return aSymbol; +} diff --git a/indra/llwindow/llkeyboardsdl.h b/indra/llwindow/llkeyboardsdl.h index fd348b28f2..f23b4cca6c 100644 --- a/indra/llwindow/llkeyboardsdl.h +++ b/indra/llwindow/llkeyboardsdl.h @@ -28,28 +28,31 @@ #define LL_LLKEYBOARDSDL_H #include "llkeyboard.h" -#include "SDL/SDL.h" +#include "SDL3/SDL.h" class LLKeyboardSDL : public LLKeyboard { public: LLKeyboardSDL(); - /*virtual*/ ~LLKeyboardSDL() {}; + ~LLKeyboardSDL() = default; - /*virtual*/ bool handleKeyUp(const U16 key, MASK mask); - /*virtual*/ bool handleKeyDown(const U16 key, MASK mask); - /*virtual*/ void resetMaskKeys(); - /*virtual*/ MASK currentMask(bool for_mouse_event); - /*virtual*/ void scanKeyboard(); + bool handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override; + bool handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override; + void resetMaskKeys() override; + MASK currentMask(bool for_mouse_event) override; + void scanKeyboard() override; protected: - MASK updateModifiers(const U32 mask); + MASK updateModifiers(const MASK mask); void setModifierKeyLevel( KEY key, bool new_state ); - bool translateNumpadKey( const U16 os_key, KEY *translated_key ); - U16 inverseTranslateNumpadKey(const KEY translated_key); + bool translateNumpadKey( const LLKeyboard::NATIVE_KEY_TYPE os_key, KEY *translated_key ); + LLKeyboard::NATIVE_KEY_TYPE inverseTranslateNumpadKey(const KEY translated_key); private: - std::map mTranslateNumpadMap; // special map for translating OS keys to numpad keys - std::map mInvTranslateNumpadMap; // inverse of the above + std::map mTranslateNumpadMap; // special map for translating OS keys to numpad keys + std::map mInvTranslateNumpadMap; // inverse of the above + +public: + static U32 mapSDL2toWin( U32 ); }; #endif diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index 8d6b8d9b93..4ef0b493a5 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -197,7 +197,7 @@ MASK LLKeyboardWin32::updateModifiers() // mask is ignored, except for extended flag -- we poll the modifier keys for the other flags -bool LLKeyboardWin32::handleKeyDown(const U16 key, MASK mask) +bool LLKeyboardWin32::handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) { KEY translated_key; U32 translated_mask; @@ -214,7 +214,7 @@ bool LLKeyboardWin32::handleKeyDown(const U16 key, MASK mask) } // mask is ignored, except for extended flag -- we poll the modifier keys for the other flags -bool LLKeyboardWin32::handleKeyUp(const U16 key, MASK mask) +bool LLKeyboardWin32::handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) { KEY translated_key; U32 translated_mask; diff --git a/indra/llwindow/llkeyboardwin32.h b/indra/llwindow/llkeyboardwin32.h index d0dfc5cfdd..fa223a2904 100644 --- a/indra/llwindow/llkeyboardwin32.h +++ b/indra/llwindow/llkeyboardwin32.h @@ -37,15 +37,16 @@ class LLKeyboardWin32 : public LLKeyboard { public: LLKeyboardWin32(); - /*virtual*/ ~LLKeyboardWin32() {}; - - /*virtual*/ bool handleKeyUp(const U16 key, MASK mask); - /*virtual*/ bool handleKeyDown(const U16 key, MASK mask); - /*virtual*/ void resetMaskKeys(); - /*virtual*/ MASK currentMask(bool for_mouse_event); - /*virtual*/ void scanKeyboard(); - bool translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key); - U16 inverseTranslateExtendedKey(const KEY translated_key); + ~LLKeyboardWin32() = default; + + bool handleKeyUp(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override; + bool handleKeyDown(const LLKeyboard::NATIVE_KEY_TYPE key, MASK mask) override; + void resetMaskKeys() override; + MASK currentMask(bool for_mouse_event) override; + void scanKeyboard() override; + + bool translateExtendedKey(const U16 os_key, const MASK mask, KEY *translated_key); + U16 inverseTranslateExtendedKey(const KEY translated_key); protected: MASK updateModifiers(); diff --git a/indra/llwindow/llmousehandler.cpp b/indra/llwindow/llmousehandler.cpp index eeceab502a..959dde70b4 100644 --- a/indra/llwindow/llmousehandler.cpp +++ b/indra/llwindow/llmousehandler.cpp @@ -24,6 +24,8 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "llmousehandler.h" //virtual diff --git a/indra/llwindow/llsdl.cpp b/indra/llwindow/llsdl.cpp new file mode 100644 index 0000000000..c97356ee80 --- /dev/null +++ b/indra/llwindow/llsdl.cpp @@ -0,0 +1,146 @@ +/** + * @file llsdl.cpp + * @brief SDL2 initialization + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include +#include + +#include "SDL3/SDL.h" + +#ifndef LL_SDL_APP +#define SDL_MAIN_HANDLED 1 +#include "SDL3/SDL_main.h" +#endif + +#include "llerror.h" +#include "llwindow.h" + +bool gSDLMainHandled = false; + +void sdl_logger(void *userdata, int category, SDL_LogPriority priority, const char *message) +{ + switch (priority) + { + case SDL_LOG_PRIORITY_TRACE: + case SDL_LOG_PRIORITY_VERBOSE: + case SDL_LOG_PRIORITY_DEBUG: + LL_DEBUGS("SDL") << "log='" << message << "'" << LL_ENDL; + break; + case SDL_LOG_PRIORITY_INFO: + LL_INFOS("SDL") << "log='" << message << "'" << LL_ENDL; + break; + case SDL_LOG_PRIORITY_WARN: + case SDL_LOG_PRIORITY_ERROR: + case SDL_LOG_PRIORITY_CRITICAL: + LL_WARNS("SDL") << "log='" << message << "'" << LL_ENDL; + break; + case SDL_LOG_PRIORITY_INVALID: + default: + break; + } +} + +void init_sdl(const std::string& app_name) +{ + if (!gSDLMainHandled) + { + SDL_SetMainReady(); + } + + SDL_SetLogOutputFunction(&sdl_logger, nullptr); + + const int c_sdl_version = SDL_VERSION; + LL_INFOS() << "Compiled against SDL " + << SDL_VERSIONNUM_MAJOR(c_sdl_version) << "." + << SDL_VERSIONNUM_MINOR(c_sdl_version) << "." + << SDL_VERSIONNUM_MICRO(c_sdl_version) << LL_ENDL; + const int r_sdl_version = SDL_GetVersion(); + LL_INFOS() << "Running with SDL " + << SDL_VERSIONNUM_MAJOR(r_sdl_version) << "." + << SDL_VERSIONNUM_MINOR(r_sdl_version) << "." + << SDL_VERSIONNUM_MICRO(r_sdl_version) << LL_ENDL; + +#if LL_WINDOWS && defined(LL_SDL_WINDOW) + Uint32 style = 0; +#if defined(CS_BYTEALIGNCLIENT) && defined(CS_OWNDC) + style = (CS_BYTEALIGNCLIENT | CS_OWNDC); +#endif + SDL_RegisterApp(app_name.c_str(), style, nullptr); +#endif + +#if LL_SDL_WINDOW + // For linux we SDL_INIT_VIDEO and _AUDIO + std::initializer_list > hintList = + { + {SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR,"0"}, + {SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH,"1"}, + {SDL_HINT_MOUSE_EMULATE_WARP_WITH_RELATIVE,"0"}, + {SDL_HINT_KEYCODE_OPTIONS,"french_numbers,latin_letters"} + }; + + for (auto hint: hintList) + { + SDL_SetHint(std::get<0>(hint), std::get<1>(hint)); + } + + std::initializer_list> initList= + { + {SDL_INIT_VIDEO,"SDL_INIT_VIDEO", true}, + {SDL_INIT_JOYSTICK,"SDL_INIT_JOYSTICK", true}, + {SDL_INIT_GAMEPAD,"SDL_INIT_GAMEPAD", true}, + }; +#else + // For non-linux platforms we still SDL_INIT_VIDEO because it is a pre-requisite + // for SDL_INIT_GAMECONTROLLER. + std::initializer_list> initList= + { + {SDL_INIT_VIDEO,"SDL_INIT_VIDEO", false}, + }; +#endif // LL_LINUX + // We SDL_INIT_GAMECONTROLLER later in the startup process to make it + // more likely we'll catch initial SDL_CONTROLLERDEVICEADDED events. + + for (auto subSystem : initList) + { + if (!SDL_InitSubSystem(std::get<0>(subSystem))) + { + LL_WARNS() << "SDL_InitSubSystem for " << std::get<1>(subSystem) << " failed " << SDL_GetError() << LL_ENDL; + + if (std::get<2>(subSystem)) + { + OSMessageBox("SDL_Init() failure", "error", OSMB_OK); + return; + } + } + } +} + +void quit_sdl() +{ +#if LL_WINDOWS && defined(LL_SDL_WINDOW) + SDL_UnregisterApp(); +#endif + SDL_Quit(); +} diff --git a/indra/llwindow/llsdl.h b/indra/llwindow/llsdl.h new file mode 100644 index 0000000000..1a8a12c61c --- /dev/null +++ b/indra/llwindow/llsdl.h @@ -0,0 +1,34 @@ +/** + * @file llsdl.h + * @brief SDL2 initialization + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#pragma once + +#include "llpreprocessor.h" + +extern bool gSDLMainHandled; + +void init_sdl(const std::string& app_name); +void quit_sdl(); diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index eb11a28360..2313aeda50 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -29,7 +29,7 @@ #if LL_MESA_HEADLESS #include "llwindowmesaheadless.h" -#elif LL_SDL +#elif LL_SDL_WINDOW #include "llwindowsdl.h" #elif LL_WINDOWS #include "llwindowwin32.h" @@ -39,6 +39,9 @@ #include "llerror.h" #include "llkeyboard.h" +#if LL_SDL_WINDOW && !defined(LL_MESA_HEADLESS) +#include "llsdl.h" +#endif #include "llwindowcallbacks.h" @@ -74,14 +77,15 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type) LL_WARNS() << "OSMessageBox: " << text << LL_ENDL; #if LL_MESA_HEADLESS // !!! *FIX: (?) return OSBTN_OK; +#elif LL_SDL_WINDOW + result = OSMessageBoxSDL(text, caption, type); #elif LL_WINDOWS result = OSMessageBoxWin32(text, caption, type); #elif LL_DARWIN result = OSMessageBoxMacOSX(text, caption, type); -#elif LL_SDL - result = OSMessageBoxSDL(text, caption, type); #else -#error("OSMessageBox not implemented for this platform!") + LL_WARNS() << "OSMessageBox not implemented for this platform!" << LL_ENDL; + return OSBTN_OK; #endif if (was_visible) @@ -182,12 +186,6 @@ bool LLWindow::dialogColorPicker(F32 *r, F32 *g, F32 *b) return false; } -void *LLWindow::getMediaWindow() -{ - // Default to returning the platform window. - return getPlatformWindow(); -} - bool LLWindow::setSize(LLCoordScreen size) { if (!getMaximized()) @@ -258,12 +256,12 @@ bool LLWindow::copyTextToPrimary(const LLWString &src) // static std::vector LLWindow::getDynamicFallbackFontList() { -#if LL_WINDOWS +#if LL_SDL_WINDOW && !LL_MESA_HEADLESS + return LLWindowSDL::getDynamicFallbackFontList(); +#elif LL_WINDOWS return LLWindowWin32::getDynamicFallbackFontList(); #elif LL_DARWIN return LLWindowMacOSX::getDynamicFallbackFontList(); -#elif LL_SDL - return LLWindowSDL::getDynamicFallbackFontList(); #else return std::vector(); #endif @@ -272,7 +270,9 @@ std::vector LLWindow::getDynamicFallbackFontList() // static std::vector LLWindow::getDisplaysResolutionList() { -#if LL_WINDOWS +#if LL_SDL_WINDOW && !LL_MESA_HEADLESS + return LLWindowSDL::getDisplaysResolutionList(); +#elif LL_WINDOWS return LLWindowWin32::getDisplaysResolutionList(); #elif LL_DARWIN return LLWindowMacOSX::getDisplaysResolutionList(); @@ -341,14 +341,17 @@ bool LLSplashScreen::isVisible() // static LLSplashScreen *LLSplashScreen::create() { -#if LL_MESA_HEADLESS || LL_SDL // !!! *FIX: (?) - return 0; +#if LL_MESA_HEADLESS + return nullptr; +#elif LL_SDL_WINDOW + return new LLSplashScreenSDL; #elif LL_WINDOWS return new LLSplashScreenWin32; #elif LL_DARWIN return new LLSplashScreenMacOSX; #else -#error("LLSplashScreen not implemented on this platform!") + LL_WARNS() << ("LLSplashScreen not implemented on this platform!") << LL_ENDL; + return nullptr; #endif } @@ -358,7 +361,9 @@ void LLSplashScreen::show() { if (!gSplashScreenp) { -#if LL_WINDOWS && !LL_MESA_HEADLESS +#if LL_SDL_WINDOW && !LL_MESA_HEADLESS + gSplashScreenp = new LLSplashScreenSDL; +#elif LL_WINDOWS && !LL_MESA_HEADLESS gSplashScreenp = new LLSplashScreenWin32; #elif LL_DARWIN gSplashScreenp = new LLSplashScreenMacOSX; @@ -412,15 +417,19 @@ LLWindow* LLWindowManager::createWindow( { LLWindow* new_window; +#if LL_SDL_WINDOW && !defined(LL_MESA_HEADLESS) + init_sdl(name); +#endif + if (use_gl) { #if LL_MESA_HEADLESS new_window = new LLWindowMesaHeadless(callbacks, title, name, x, y, width, height, flags, fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth); -#elif LL_SDL +#elif LL_SDL_WINDOW new_window = new LLWindowSDL(callbacks, - title, x, y, width, height, flags, + title, name, x, y, width, height, flags, fullscreen, clearBg, enable_vsync, use_gl, ignore_pixel_depth, fsaa_samples); #elif LL_WINDOWS new_window = new LLWindowWin32(callbacks, @@ -461,6 +470,9 @@ bool LLWindowManager::destroyWindow(LLWindow* window) window->close(); sWindowList.erase(window); +#if LL_SDL_WINDOW && !defined(LL_MESA_HEADLESS) + quit_sdl(); +#endif delete window; diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 7a5404e615..2d8fc80b9e 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -92,7 +92,7 @@ public: virtual bool setCursorPosition(LLCoordWindow position) = 0; virtual bool getCursorPosition(LLCoordWindow *position) = 0; -#if LL_WINDOWS +#if LL_WINDOWS && !LL_SDL_WINDOW virtual bool getCursorDelta(LLCoordCommon* delta) = 0; #endif virtual bool isWrapMouse() const = 0; @@ -174,9 +174,6 @@ public: // return a platform-specific window reference (HWND on Windows, WindowRef on the Mac, Gtk window on Linux) virtual void *getPlatformWindow() = 0; -// return the platform-specific window reference we use to initialize llmozlib (HWND on Windows, WindowRef on the Mac, Gtk window on Linux) - virtual void *getMediaWindow(); - // control platform's Language Text Input mechanisms. virtual void allowLanguageTextInput(LLPreeditor *preeditor, bool b) {} virtual void setLanguageTextInput( const LLCoordGL & pos ) {}; diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h index dc7b833013..8b7b0ef55c 100644 --- a/indra/llwindow/llwindowheadless.h +++ b/indra/llwindow/llwindowheadless.h @@ -60,7 +60,7 @@ public: /*virtual*/ void toggleVSync(bool enable_vsync) override { } /*virtual*/ bool setCursorPosition(LLCoordWindow position) override {return false;} /*virtual*/ bool getCursorPosition(LLCoordWindow *position) override {return false;} -#if LL_WINDOWS +#if LL_WINDOWS && !LL_SDL_WINDOW /*virtual*/ bool getCursorDelta(LLCoordCommon* delta) override { return false; } #endif /*virtual*/ bool isWrapMouse() const override { return true; } diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h index 0bf8c46a30..ad08c4f065 100644 --- a/indra/llwindow/llwindowmesaheadless.h +++ b/indra/llwindow/llwindowmesaheadless.h @@ -30,70 +30,74 @@ #if LL_MESA_HEADLESS #include "llwindow.h" -#include "GL/glu.h" #include "GL/osmesa.h" class LLWindowMesaHeadless : public LLWindow { public: - /*virtual*/ void show() {}; - /*virtual*/ void hide() {}; - /*virtual*/ void close() {}; - /*virtual*/ bool getVisible() {return false;}; - /*virtual*/ bool getMinimized() {return false;}; - /*virtual*/ bool getMaximized() {return false;}; - /*virtual*/ bool maximize() {return false;}; - /*virtual*/ void minimize() {}; - /*virtual*/ void restore() {}; - /*virtual*/ bool getFullscreen() {return false;}; - /*virtual*/ bool getPosition(LLCoordScreen *position) {return false;}; - /*virtual*/ bool getSize(LLCoordScreen *size) {return false;}; - /*virtual*/ bool getSize(LLCoordWindow *size) {return false;}; - /*virtual*/ bool setPosition(LLCoordScreen position) {return false;}; - /*virtual*/ bool setSizeImpl(LLCoordScreen size) {return false;}; - /*virtual*/ bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp = NULL) {return false;}; - /*virtual*/ bool setCursorPosition(LLCoordWindow position) {return false;}; - /*virtual*/ bool getCursorPosition(LLCoordWindow *position) {return false;}; - /*virtual*/ void showCursor() {}; - /*virtual*/ void hideCursor() {}; - /*virtual*/ void showCursorFromMouseMove() {}; - /*virtual*/ void hideCursorUntilMouseMove() {}; - /*virtual*/ bool isCursorHidden() {return false;}; - /*virtual*/ void updateCursor() {}; - //virtual ECursorType getCursor() { return mCurrentCursor; }; - /*virtual*/ void captureMouse() {}; - /*virtual*/ void releaseMouse() {}; - /*virtual*/ void setMouseClipping( bool b ) {}; - /*virtual*/ bool isClipboardTextAvailable() {return false; }; - /*virtual*/ bool pasteTextFromClipboard(LLWString &dst) {return false; }; - /*virtual*/ bool copyTextToClipboard(const LLWString &src) {return false; }; - /*virtual*/ void flashIcon(F32 seconds) {}; - /*virtual*/ F32 getGamma() {return 1.0f; }; - /*virtual*/ bool setGamma(const F32 gamma) {return false; }; // Set the gamma - /*virtual*/ bool restoreGamma() {return false; }; // Restore original gamma table (before updating gamma) - /*virtual*/ void setFSAASamples(const U32 fsaa_samples) { /* FSAA not supported yet on Mesa headless.*/ } - /*virtual*/ U32 getFSAASamples() { return 0; } - //virtual ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void gatherInput() {}; - /*virtual*/ void delayInputProcessing() {}; - /*virtual*/ void swapBuffers(); - /*virtual*/ void restoreGLContext() {}; + void show() override {}; + void hide() override {}; + void close() override {}; + bool getVisible() override {return false;}; + bool getMinimized() override {return false;}; + bool getMaximized() override {return false;}; + bool maximize() override {return false;}; + void minimize() override {}; + void restore() override {}; + bool getFullscreen() {return false;}; + bool getPosition(LLCoordScreen *position) override {return false;}; + bool getSize(LLCoordScreen *size) override {return false;}; + bool getSize(LLCoordWindow *size) override {return false;}; + bool setPosition(LLCoordScreen position) override {return false;}; + bool setSizeImpl(LLCoordScreen size) override {return false;}; + bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp = NULL) override {return false;}; + bool setCursorPosition(LLCoordWindow position) override {return false;}; + bool getCursorPosition(LLCoordWindow *position) override {return false;}; + void showCursor() override {}; + void hideCursor() override {}; + void showCursorFromMouseMove() override {}; + void hideCursorUntilMouseMove() override {}; + bool isCursorHidden() override {return false;}; + void updateCursor() override {}; + //virtual ECursorType getCursor() override { return mCurrentCursor; }; + void captureMouse() override {}; + void releaseMouse() override {}; + void setMouseClipping( bool b ) override {}; + bool isClipboardTextAvailable() override {return false; }; + bool pasteTextFromClipboard(LLWString &dst) override {return false; }; + bool copyTextToClipboard(const LLWString &src) override {return false; }; + void flashIcon(F32 seconds) override {}; + F32 getGamma() override {return 1.0f; }; + bool setGamma(const F32 gamma) override {return false; }; // Set the gamma + bool restoreGamma() override {return false; }; // Restore original gamma table (before updating gamma) + void setFSAASamples(const U32 fsaa_samples) override { /* FSAA not supported yet on Mesa headless.*/ } + U32 getFSAASamples() override { return 0; } + //virtual ESwapMethod getSwapMethod() override { return mSwapMethod; } + void gatherInput() override {}; + void delayInputProcessing() override {}; + void swapBuffers() override; + + void* createSharedContext()override{return nullptr;}; + void makeContextCurrent(void* context)override{}; + void destroySharedContext(void* context)override{}; + void toggleVSync(bool enable_vsync) override {}; + bool setSizeImpl(LLCoordWindow size) override { return false; }; // handy coordinate space conversion routines - /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordWindow *to) { return false; }; - /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordScreen *to) { return false; }; - /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordGL *to) { return false; }; - /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordWindow *to) { return false; }; - /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordGL *to) { return false; }; - /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordScreen *to) { return false; }; + bool convertCoords(LLCoordScreen from, LLCoordWindow *to) override { return false; }; + bool convertCoords(LLCoordWindow from, LLCoordScreen *to) override { return false; }; + bool convertCoords(LLCoordWindow from, LLCoordGL *to) override { return false; }; + bool convertCoords(LLCoordGL from, LLCoordWindow *to) override { return false; }; + bool convertCoords(LLCoordScreen from, LLCoordGL *to) override { return false; }; + bool convertCoords(LLCoordGL from, LLCoordScreen *to) override { return false; }; - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) { return NULL; }; - /*virtual*/ F32 getNativeAspectRatio() { return 1.0f; }; - /*virtual*/ F32 getPixelAspectRatio() { return 1.0f; }; - /*virtual*/ void setNativeAspectRatio(F32 ratio) {} + LLWindowResolution* getSupportedResolutions(S32 &num_resolutions) override { return NULL; }; + F32 getNativeAspectRatio() override { return 1.0f; }; + F32 getPixelAspectRatio() override { return 1.0f; }; + void setNativeAspectRatio(F32 ratio) override {} - /*virtual*/ void *getPlatformWindow() { return 0; }; - /*virtual*/ void bringToFront() {}; + void *getPlatformWindow() override { return 0; }; + void bringToFront() override {}; LLWindowMesaHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, @@ -112,9 +116,9 @@ public: LLSplashScreenMesaHeadless() {}; virtual ~LLSplashScreenMesaHeadless() {}; - /*virtual*/ void showImpl() {}; - /*virtual*/ void updateImpl(const std::string& mesg) {}; - /*virtual*/ void hideImpl() {}; + void showImpl() override {}; + void updateImpl(const std::string& mesg) override {}; + void hideImpl() override {}; }; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 05be319c0b..57110f8634 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -25,8 +25,6 @@ * $/LicenseInfo$ */ -#if LL_SDL - #include "linden_common.h" #include "llwindowsdl.h" @@ -39,197 +37,77 @@ #include "llstring.h" #include "lldir.h" #include "llfindlocale.h" +#include "llpreeditor.h" +#include "llsdl.h" -#if LL_GTK -extern "C" { -# include "gtk/gtk.h" -} -#include -#endif // LL_GTK +#ifdef LL_GLIB +#include +#endif +#if LL_LINUX extern "C" { # include "fontconfig/fontconfig.h" } -#if LL_LINUX // not necessarily available on random SDL platforms, so #if LL_LINUX // for execv(), waitpid(), fork() -# include -# include -# include +#include +#include +#include +#include #endif // LL_LINUX -extern bool gDebugWindowProc; +#if LL_DARWIN +#include +#include +#include +#include -const S32 MAX_NUM_RESOLUTIONS = 200; +bool LLWindowSDL::sUseMultGL = false; +#endif -// static variable for ATI mouse cursor crash work-around: -static bool ATIbug = false; +bool gHiDPISupport = true; + +const S32 MAX_NUM_RESOLUTIONS = 200; +const S32 DEFAULT_REFRESH_RATE = 60; // // LLWindowSDL // -#if LL_X11 -# include -#endif //LL_X11 - // TOFU HACK -- (*exactly* the same hack as LLWindowMacOSX for a similar // set of reasons): Stash a pointer to the LLWindowSDL object here and // maintain in the constructor and destructor. This assumes that there will // be only one object of this class at any time. Currently this is true. -static LLWindowSDL *gWindowImplementation = NULL; - - -void maybe_lock_display(void) -{ - if (gWindowImplementation && gWindowImplementation->Lock_Display) { - gWindowImplementation->Lock_Display(); - } -} - - -void maybe_unlock_display(void) -{ - if (gWindowImplementation && gWindowImplementation->Unlock_Display) { - gWindowImplementation->Unlock_Display(); - } -} - - -#if LL_GTK -// Lazily initialize and check the runtime GTK version for goodness. -// static -bool LLWindowSDL::ll_try_gtk_init(void) -{ - static bool done_gtk_diag = false; - static bool gtk_is_good = false; - static bool done_setlocale = false; - static bool tried_gtk_init = false; - - if (!done_setlocale) - { - LL_INFOS() << "Starting GTK Initialization." << LL_ENDL; - maybe_lock_display(); - gtk_disable_setlocale(); - maybe_unlock_display(); - done_setlocale = true; - } - - if (!tried_gtk_init) - { - tried_gtk_init = true; - if (!g_thread_supported ()) g_thread_init (NULL); - maybe_lock_display(); - gtk_is_good = gtk_init_check(NULL, NULL); - maybe_unlock_display(); - if (!gtk_is_good) - LL_WARNS() << "GTK Initialization failed." << LL_ENDL; - } - - if (gtk_is_good && !done_gtk_diag) - { - LL_INFOS() << "GTK Initialized." << LL_ENDL; - LL_INFOS() << "- Compiled against GTK version " - << GTK_MAJOR_VERSION << "." - << GTK_MINOR_VERSION << "." - << GTK_MICRO_VERSION << LL_ENDL; - LL_INFOS() << "- Running against GTK version " - << gtk_major_version << "." - << gtk_minor_version << "." - << gtk_micro_version << LL_ENDL; - maybe_lock_display(); - const gchar* gtk_warning = gtk_check_version( - GTK_MAJOR_VERSION, - GTK_MINOR_VERSION, - GTK_MICRO_VERSION); - maybe_unlock_display(); - if (gtk_warning) - { - LL_WARNS() << "- GTK COMPATIBILITY WARNING: " << - gtk_warning << LL_ENDL; - gtk_is_good = false; - } else { - LL_INFOS() << "- GTK version is good." << LL_ENDL; - } - - done_gtk_diag = true; - } - - return gtk_is_good; -} -#endif // LL_GTK - - -#if LL_X11 -// static -Window LLWindowSDL::get_SDL_XWindowID(void) -{ - if (gWindowImplementation) { - return gWindowImplementation->mSDL_XWindowID; - } - return None; -} - -//static -Display* LLWindowSDL::get_SDL_Display(void) -{ - if (gWindowImplementation) { - return gWindowImplementation->mSDL_Display; - } - return NULL; -} -#endif // LL_X11 - +static LLWindowSDL *gWindowImplementation = nullptr; LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, - const std::string& title, S32 x, S32 y, S32 width, - S32 height, U32 flags, - bool fullscreen, bool clearBg, - bool disable_vsync, bool use_gl, - bool ignore_pixel_depth, U32 fsaa_samples) - : LLWindow(callbacks, fullscreen, flags), - Lock_Display(NULL), - Unlock_Display(NULL), mGamma(1.0f) + const std::string& title, const std::string& name, S32 x, S32 y, S32 width, + S32 height, U32 flags, + bool fullscreen, bool clearBg, + bool enable_vsync, bool use_gl, + bool ignore_pixel_depth, U32 fsaa_samples) + : LLWindow(callbacks, fullscreen, flags), + mGamma(1.0f), mFlashing(false) { + SDL_GL_LoadLibrary(nullptr); + // Initialize the keyboard gKeyboard = new LLKeyboardSDL(); gKeyboard->setCallbacks(callbacks); - // Note that we can't set up key-repeat until after SDL has init'd video - - // Ignore use_gl for now, only used for drones on PC - mWindow = NULL; - mNeedsResize = false; - mOverrideAspectRatio = 0.f; - mGrabbyKeyFlags = 0; - mReallyCapturedCount = 0; - mHaveInputFocus = -1; - mIsMinimized = -1; - mFSAASamples = fsaa_samples; - -#if LL_X11 - mSDL_XWindowID = None; - mSDL_Display = NULL; -#endif // LL_X11 - -#if LL_GTK - // We MUST be the first to initialize GTK so that GTK doesn't get badly - // initialized with a non-C locale and cause lots of serious random - // weirdness. - ll_try_gtk_init(); -#endif // LL_GTK // Assume 4:3 aspect ratio until we know better - mOriginalAspectRatio = 1024.0 / 768.0; + mNativeAspectRatio = 1024.f / 768.f; if (title.empty()) - mWindowTitle = "SDL Window"; // *FIX: (?) + mWindowTitle = "Second Life"; else mWindowTitle = title; // Create the GL context and set it up for windowed or fullscreen, as appropriate. - if(createContext(x, y, width, height, 32, fullscreen, disable_vsync)) + if(createContext(x, y, width, height, 32, fullscreen, enable_vsync)) { + gGLManager.initWGL(); gGLManager.initGL(); //start with arrow cursor @@ -241,14 +119,6 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, // Stash an object pointer for OSMessageBox() gWindowImplementation = this; - -#if LL_X11 - mFlashing = false; -#endif // LL_X11 - - mKeyScanCode = 0; - mKeyVirtualKey = 0; - mKeyModifiers = KMOD_NONE; } static SDL_Surface *Load_BMP_Resource(const char *basename) @@ -258,480 +128,297 @@ static SDL_Surface *Load_BMP_Resource(const char *basename) // Figure out where our BMP is living on the disk snprintf(path_buffer, PATH_BUFFER_SIZE-1, "%s%sres-sdl%s%s", - gDirUtilp->getAppRODataDir().c_str(), - gDirUtilp->getDirDelimiter().c_str(), - gDirUtilp->getDirDelimiter().c_str(), - basename); + gDirUtilp->getAppRODataDir().c_str(), + gDirUtilp->getDirDelimiter().c_str(), + gDirUtilp->getDirDelimiter().c_str(), + basename); path_buffer[PATH_BUFFER_SIZE-1] = '\0'; return SDL_LoadBMP(path_buffer); } -#if LL_X11 -// This is an XFree86/XOrg-specific hack for detecting the amount of Video RAM -// on this machine. It works by searching /var/log/var/log/Xorg.?.log or -// /var/log/XFree86.?.log for a ': (VideoRAM ?|Memory): (%d+) kB' regex, where -// '?' is the X11 display number derived from $DISPLAY -static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str) -{ - const int line_buf_size = 1000; - char line_buf[line_buf_size]; - while (fgets(line_buf, line_buf_size, fp)) - { - //LL_DEBUGS() << "XLOG: " << line_buf << LL_ENDL; - - // Why the ad-hoc parser instead of using a regex? Our - // favourite regex implementation - libboost_regex - is - // quite a heavy and troublesome dependency for the client, so - // it seems a shame to introduce it for such a simple task. - // *FIXME: libboost_regex is a dependency now anyway, so we may - // as well use it instead of this hand-rolled nonsense. - const char *part1_template = prefix_str; - const char part2_template[] = " kB"; - char *part1 = strstr(line_buf, part1_template); - if (part1) // found start of matching line - { - part1 = &part1[strlen(part1_template)]; // -> after - char *part2 = strstr(part1, part2_template); - if (part2) // found end of matching line - { - // now everything between part1 and part2 is - // supposed to be numeric, describing the - // number of kB of Video RAM supported - int rtn = 0; - for (; part1 < part2; ++part1) - { - if (*part1 < '0' || *part1 > '9') - { - // unexpected char, abort parse - rtn = 0; - break; - } - rtn *= 10; - rtn += (*part1) - '0'; - } - if (rtn > 0) - { - // got the kB number. return it now. - return rtn; - } - } - } - } - return 0; // 'could not detect' +void LLWindowSDL::setTitle(const std::string title) +{ + SDL_SetWindowTitle( mWindow, title.c_str() ); } -static int x11_detect_VRAM_kb() +void LLWindowSDL::tryFindFullscreenSize( int &width, int &height ) { - std::string x_log_location("/var/log/"); - std::string fname; - int rtn = 0; // 'could not detect' - int display_num = 0; - FILE *fp; - char *display_env = getenv("DISPLAY"); // e.g. :0 or :0.0 or :1.0 etc - // parse DISPLAY number so we can go grab the right log file - if (display_env[0] == ':' && - display_env[1] >= '0' && display_env[1] <= '9') - { - display_num = display_env[1] - '0'; - } + LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; - // *TODO: we could be smarter and see which of Xorg/XFree86 has the - // freshest time-stamp. - - // Try Xorg log first - fname = x_log_location; - fname += "Xorg."; - fname += ('0' + display_num); - fname += ".log"; - fp = fopen(fname.c_str(), "r"); - if (fp) + // If the requested width or height is 0, find the best default for the monitor. + if(width == 0 || height == 0) { - LL_INFOS() << "Looking in " << fname - << " for VRAM info..." << LL_ENDL; - rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); - fclose(fp); - if (0 == rtn) + // Scan through the list of modes, looking for one which has: + // height between 700 and 800 + // aspect ratio closest to the user's original mode + S32 resolutionCount = 0; + LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); + + if(resolutionList != nullptr) { - fp = fopen(fname.c_str(), "r"); - if (fp) + F32 closestAspect = 0; + U32 closestHeight = 0; + U32 closestWidth = 0; + + LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mNativeAspectRatio << LL_ENDL; + + for(S32 i=0; i < resolutionCount; i++) { - rtn = x11_detect_VRAM_kb_fp(fp, ": Video RAM: "); - fclose(fp); - if (0 == rtn) + F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight; + + LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL; + + if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) && + (fabs(aspect - mNativeAspectRatio) < fabs(closestAspect - mNativeAspectRatio))) { - fp = fopen(fname.c_str(), "r"); - if (fp) - { - rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); - fclose(fp); - } + LL_INFOS() << " (new closest mode) " << LL_ENDL; + + // This is the closest mode we've seen yet. + closestWidth = resolutionList[i].mWidth; + closestHeight = resolutionList[i].mHeight; + closestAspect = aspect; } } + + width = closestWidth; + height = closestHeight; } } - else + + if(width == 0 || height == 0) { - LL_INFOS() << "Could not open " << fname - << " - skipped." << LL_ENDL; - // Try old XFree86 log otherwise - fname = x_log_location; - fname += "XFree86."; - fname += ('0' + display_num); - fname += ".log"; - fp = fopen(fname.c_str(), "r"); - if (fp) - { - LL_INFOS() << "Looking in " << fname - << " for VRAM info..." << LL_ENDL; - rtn = x11_detect_VRAM_kb_fp(fp, ": VideoRAM: "); - fclose(fp); - if (0 == rtn) - { - fp = fopen(fname.c_str(), "r"); - if (fp) - { - rtn = x11_detect_VRAM_kb_fp(fp, ": Memory: "); - fclose(fp); - } - } - } - else - { - LL_INFOS() << "Could not open " << fname - << " - skipped." << LL_ENDL; - } + // Mode search failed for some reason. Use the old-school default. + width = 1024; + height = 768; } - return rtn; } -#endif // LL_X11 -bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync) +bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool enable_vsync) { - //bool glneedsinit = false; - - LL_INFOS() << "createContext, fullscreen=" << fullscreen << - " size=" << width << "x" << height << LL_ENDL; + LL_INFOS() << "createContext, fullscreen=" << fullscreen << " size=" << width << "x" << height << LL_ENDL; // captures don't survive contexts mGrabbyKeyFlags = 0; - mReallyCapturedCount = 0; - - if (SDL_Init(SDL_INIT_VIDEO) < 0) - { - LL_INFOS() << "sdl_init() failed! " << SDL_GetError() << LL_ENDL; - setupFailure("sdl_init() failure, window creation error", "error", OSMB_OK); - return false; - } - - SDL_version c_sdl_version; - SDL_VERSION(&c_sdl_version); - LL_INFOS() << "Compiled against SDL " - << int(c_sdl_version.major) << "." - << int(c_sdl_version.minor) << "." - << int(c_sdl_version.patch) << LL_ENDL; - const SDL_version *r_sdl_version; - r_sdl_version = SDL_Linked_Version(); - LL_INFOS() << " Running against SDL " - << int(r_sdl_version->major) << "." - << int(r_sdl_version->minor) << "." - << int(r_sdl_version->patch) << LL_ENDL; - - const SDL_VideoInfo *video_info = SDL_GetVideoInfo( ); - if (!video_info) - { - LL_INFOS() << "SDL_GetVideoInfo() failed! " << SDL_GetError() << LL_ENDL; - setupFailure("SDL_GetVideoInfo() failed, Window creation error", "Error", OSMB_OK); - return false; - } - - if (video_info->current_h > 0) - { - mOriginalAspectRatio = (float)video_info->current_w / (float)video_info->current_h; - LL_INFOS() << "Original aspect ratio was " << video_info->current_w << ":" << video_info->current_h << "=" << mOriginalAspectRatio << LL_ENDL; - } - SDL_EnableUNICODE(1); - SDL_WM_SetCaption(mWindowTitle.c_str(), mWindowTitle.c_str()); - - // Set the application icon. - SDL_Surface *bmpsurface; - bmpsurface = Load_BMP_Resource("ll_icon.BMP"); - if (bmpsurface) - { - // This attempts to give a black-keyed mask to the icon. - SDL_SetColorKey(bmpsurface, - SDL_SRCCOLORKEY, - SDL_MapRGB(bmpsurface->format, 0,0,0) ); - SDL_WM_SetIcon(bmpsurface, NULL); - // The SDL examples cheerfully avoid freeing the icon - // surface, but I'm betting that's leaky. - SDL_FreeSurface(bmpsurface); - bmpsurface = NULL; - } - - // note: these SetAttributes make Tom's 9600-on-AMD64 fail to - // get a visual, but it's broken anyway when it does, and without - // these SetAttributes we might easily get an avoidable substandard - // visual to work with on most other machines. - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24); - // We need stencil support for a few (minor) things. - if (!getenv("LL_GL_NO_STENCIL")) - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, (bits <= 16) ? 1 : 8); - - // *FIX: try to toggle vsync here? + if (width == 0) + width = 1024; + if (height == 0) + width = 768; + if (x == 0) + x = SDL_WINDOWPOS_UNDEFINED; + if (y == 0) + y = SDL_WINDOWPOS_UNDEFINED; mFullscreen = fullscreen; - int sdlflags = SDL_OPENGL | SDL_RESIZABLE | SDL_ANYFORMAT; + // Setup default backing colors + GLint redBits{8}, greenBits{8}, blueBits{8}, alphaBits{8}; + GLint depthBits{24}, stencilBits{8}; + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, redBits); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, greenBits); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, blueBits); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, alphaBits); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depthBits); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencilBits); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (mFSAASamples > 0) + if(LLRender::sGLCoreProfile) { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mFSAASamples); - } +#if LL_DARWIN + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); +#endif - mSDLFlags = sdlflags; + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + } - if (mFullscreen) + SDL_GLContextFlag context_flags{}; + if (gDebugGL) { - LL_INFOS() << "createContext: setting up fullscreen " << width << "x" << height << LL_ENDL; - - // If the requested width or height is 0, find the best default for the monitor. - if((width == 0) || (height == 0)) - { - // Scan through the list of modes, looking for one which has: - // height between 700 and 800 - // aspect ratio closest to the user's original mode - S32 resolutionCount = 0; - LLWindowResolution *resolutionList = getSupportedResolutions(resolutionCount); - - if(resolutionList != NULL) - { - F32 closestAspect = 0; - U32 closestHeight = 0; - U32 closestWidth = 0; - int i; - - LL_INFOS() << "createContext: searching for a display mode, original aspect is " << mOriginalAspectRatio << LL_ENDL; - - for(i=0; i < resolutionCount; i++) - { - F32 aspect = (F32)resolutionList[i].mWidth / (F32)resolutionList[i].mHeight; + context_flags |= SDL_GL_CONTEXT_DEBUG_FLAG; + } - LL_INFOS() << "createContext: width " << resolutionList[i].mWidth << " height " << resolutionList[i].mHeight << " aspect " << aspect << LL_ENDL; +#if LL_DARWIN + context_flags |= SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG; +#endif + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, context_flags); + SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); - if( (resolutionList[i].mHeight >= 700) && (resolutionList[i].mHeight <= 800) && - (fabs(aspect - mOriginalAspectRatio) < fabs(closestAspect - mOriginalAspectRatio))) - { - LL_INFOS() << " (new closest mode) " << LL_ENDL; + if(mFullscreen) + { + tryFindFullscreenSize( width, height ); + } - // This is the closest mode we've seen yet. - closestWidth = resolutionList[i].mWidth; - closestHeight = resolutionList[i].mHeight; - closestAspect = aspect; - } - } + SDL_PropertiesID props = SDL_CreateProperties(); + SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, mWindowTitle.c_str()); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width); + SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, true); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, mFullscreen); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN, true); + SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN, gHiDPISupport); - width = closestWidth; - height = closestHeight; - } - } + mWindow = SDL_CreateWindowWithProperties(props); + if (mWindow == nullptr) + { + LL_WARNS() << "Window creation failure. SDL: " << SDL_GetError() << LL_ENDL; + setupFailure("Window creation error", "Error", OSMB_OK); + return false; + } + SDL_DestroyProperties(props); // Free properties once window is created - if((width == 0) || (height == 0)) - { - // Mode search failed for some reason. Use the old-school default. - width = 1024; - height = 768; - } + // Create the context + mContext = SDL_GL_CreateContext(mWindow); + if(!mContext) + { + LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL; + setupFailure("GL Context creation error", "Error", OSMB_OK); + return false; + } - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); - if (!mWindow && bits > 16) - { - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags | SDL_FULLSCREEN); - } + if (!SDL_GL_MakeCurrent(mWindow, mContext)) + { + LL_WARNS() << "Failed to make context current. SDL: " << SDL_GetError() << LL_ENDL; + setupFailure("GL Context failed to set current failure", "Error", OSMB_OK); + return false; + } - if (mWindow) + const SDL_DisplayMode* displayMode = SDL_GetCurrentDisplayMode(SDL_GetDisplayForWindow(mWindow)); + if(displayMode) + { + mRefreshRate = ll_round(displayMode->refresh_rate); + mNativeAspectRatio = ((F32)displayMode->w) / ((F32)displayMode->h); + if(mFullscreen) { - mFullscreen = true; - mFullscreenWidth = mWindow->w; - mFullscreenHeight = mWindow->h; - mFullscreenBits = mWindow->format->BitsPerPixel; - mFullscreenRefresh = -1; + mFullscreenWidth = displayMode->w; + mFullscreenHeight = displayMode->h; + mFullscreenRefresh = ll_round(displayMode->refresh_rate); LL_INFOS() << "Running at " << mFullscreenWidth - << "x" << mFullscreenHeight - << "x" << mFullscreenBits - << " @ " << mFullscreenRefresh - << LL_ENDL; - } - else - { - LL_WARNS() << "createContext: fullscreen creation failure. SDL: " << SDL_GetError() << LL_ENDL; - // No fullscreen support - mFullscreen = false; - mFullscreenWidth = -1; - mFullscreenHeight = -1; - mFullscreenBits = -1; - mFullscreenRefresh = -1; - - std::string error = llformat("Unable to run fullscreen at %d x %d.\nRunning in window.", width, height); - OSMessageBox(error, "Error", OSMB_OK); + << "x" << mFullscreenHeight + << " @ " << mFullscreenRefresh + << LL_ENDL; } } - - if(!mFullscreen && (mWindow == NULL)) + else { - if (width == 0) - width = 1024; - if (height == 0) - width = 768; - - LL_INFOS() << "createContext: creating window " << width << "x" << height << "x" << bits << LL_ENDL; - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); - if (!mWindow && bits > 16) + LL_WARNS() << "Failed to get current display mode and refresh rate" << LL_ENDL; + mRefreshRate = 0; + mNativeAspectRatio = 1024.f / 768.f; + if(mFullscreen) // Fallback to window size { - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - mWindow = SDL_SetVideoMode(width, height, bits, sdlflags); - } - - if (!mWindow) - { - LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL; - setupFailure("Window creation error", "Error", OSMB_OK); - return false; + SDL_GetWindowSize(mWindow, &mFullscreenWidth, &mFullscreenHeight); + mFullscreenRefresh = -1; } - } else if (!mFullscreen && (mWindow != NULL)) - { - LL_INFOS() << "createContext: SKIPPING - !fullscreen, but +mWindow " << width << "x" << height << "x" << bits << LL_ENDL; } - // Detect video memory size. -# if LL_X11 - gGLManager.mVRAM = x11_detect_VRAM_kb() / 1024; - if (gGLManager.mVRAM != 0) + if(mRefreshRate == 0) // We failed to get a valid refresh rate above { - LL_INFOS() << "X11 log-parser detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; - } else -# endif // LL_X11 - { - // fallback to letting SDL detect VRAM. - // note: I've not seen SDL's detection ever actually find - // VRAM != 0, but if SDL *does* detect it then that's a bonus. - gGLManager.mVRAM = video_info->video_mem / 1024; - if (gGLManager.mVRAM != 0) - { - LL_INFOS() << "SDL detected " << gGLManager.mVRAM << "MB VRAM." << LL_ENDL; - } + mRefreshRate = DEFAULT_REFRESH_RATE; } - // If VRAM is not detected, that is handled later - // *TODO: Now would be an appropriate time to check for some - // explicitly unsupported cards. - //const char* RENDERER = (const char*) glGetString(GL_RENDERER); - - GLint depthBits, stencilBits, redBits, greenBits, blueBits, alphaBits; - - glGetIntegerv(GL_RED_BITS, &redBits); - glGetIntegerv(GL_GREEN_BITS, &greenBits); - glGetIntegerv(GL_BLUE_BITS, &blueBits); - glGetIntegerv(GL_ALPHA_BITS, &alphaBits); - glGetIntegerv(GL_DEPTH_BITS, &depthBits); - glGetIntegerv(GL_STENCIL_BITS, &stencilBits); + SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits); + SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits); + SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits); + SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alphaBits); + SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depthBits); + SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencilBits); LL_INFOS() << "GL buffer:" << LL_ENDL; - LL_INFOS() << " Red Bits " << S32(redBits) << LL_ENDL; - LL_INFOS() << " Green Bits " << S32(greenBits) << LL_ENDL; - LL_INFOS() << " Blue Bits " << S32(blueBits) << LL_ENDL; - LL_INFOS() << " Alpha Bits " << S32(alphaBits) << LL_ENDL; - LL_INFOS() << " Depth Bits " << S32(depthBits) << LL_ENDL; - LL_INFOS() << " Stencil Bits " << S32(stencilBits) << LL_ENDL; + LL_INFOS() << " Red Bits " << S32(redBits) << LL_ENDL; + LL_INFOS() << " Green Bits " << S32(greenBits) << LL_ENDL; + LL_INFOS() << " Blue Bits " << S32(blueBits) << LL_ENDL; + LL_INFOS() << " Alpha Bits " << S32(alphaBits) << LL_ENDL; + LL_INFOS() << " Depth Bits " << S32(depthBits) << LL_ENDL; + 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(); setupFailure( - "Second Life requires True Color (32-bit) to run in a window.\n" - "Please go to Control Panels -> Display -> Settings and\n" - "set the screen to 32-bit color.\n" - "Alternately, if you choose to run fullscreen, Second Life\n" - "will automatically adjust the screen each time it runs.", - "Error", - OSMB_OK); + "Second Life requires True Color (32-bit) to run in a window.\n" + "Please go to Control Panels -> Display -> Settings and\n" + "set the screen to 32-bit color.\n" + "Alternately, if you choose to run fullscreen, Second Life\n" + "will automatically adjust the screen each time it runs.", + "Error", + OSMB_OK); return false; } -#if 0 // *FIX: we're going to brave it for now... - if (alphaBits < 8) - { - close(); - setupFailure( - "Second Life is unable to run because it can't get an 8 bit alpha\n" - "channel. Usually this is due to video card driver issues.\n" - "Please make sure you have the latest video card drivers installed.\n" - "Also be sure your monitor is set to True Color (32-bit) in\n" - "Control Panels -> Display -> Settings.\n" - "If you continue to receive this message, contact customer service.", - "Error", - OSMB_OK); - return false; - } + LL_PROFILER_GPU_CONTEXT; + + // Enable vertical sync + toggleVSync(enable_vsync); + +#if LL_DARWIN + setUseMultGL(sUseMultGL); + + // Get vram via CGL on macos + gGLManager.mVRAM = getVramSize(); #endif -#if LL_X11 - /* Grab the window manager specific information */ - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - if ( SDL_GetWMInfo(&info) ) + // Set the application icon. + SDL_Surface* bmpsurface = Load_BMP_Resource("ll_icon.BMP"); + if (bmpsurface) { - /* Save the information for later use */ - if ( info.subsystem == SDL_SYSWM_X11 ) - { - mSDL_Display = info.info.x11.display; - mSDL_XWindowID = info.info.x11.wmwindow; - Lock_Display = info.info.x11.lock_func; - Unlock_Display = info.info.x11.unlock_func; - } - else - { - LL_WARNS() << "We're not running under X11? Wild." - << LL_ENDL; - } + SDL_SetWindowIcon(mWindow, bmpsurface); + SDL_DestroySurface(bmpsurface); + bmpsurface = nullptr; } - else + + SDL_StartTextInput(mWindow); + return true; +} + +void* LLWindowSDL::createSharedContext() +{ + SDL_GLContext pContext = SDL_GL_CreateContext(mWindow); + if (pContext) { - LL_WARNS() << "We're not running under any known WM. Wild." - << LL_ENDL; + // HACK to ensure windows GL context is set correctly when threaded - Rye + SDL_GL_MakeCurrent(mWindow, pContext); + SDL_GL_MakeCurrent(mWindow, mContext); + LL_DEBUGS() << "Creating shared OpenGL context successful!" << LL_ENDL; + return (void*)pContext; } -#endif // LL_X11 + LL_WARNS() << "Creating shared OpenGL context failed!" << LL_ENDL; + return nullptr; +} - //make sure multisampling is disabled by default - glDisable(GL_MULTISAMPLE_ARB); - - // We need to do this here, once video is init'd - if (-1 == SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, - SDL_DEFAULT_REPEAT_INTERVAL)) - LL_WARNS() << "Couldn't enable key-repeat: " << SDL_GetError() <mX = 0; - position->mY = 0; - return true; + if (mWindow) + { + SDL_GetWindowPosition(mWindow, &position->mX, &position->mY); + return true; + } + return false; } bool LLWindowSDL::getSize(LLCoordScreen *size) { if (mWindow) { - size->mX = mWindow->w; - size->mY = mWindow->h; - return (true); + SDL_GetWindowSize(mWindow, &size->mX, &size->mY); + return true; } - return (false); + return false; } bool LLWindowSDL::getSize(LLCoordWindow *size) { if (mWindow) { - size->mX = mWindow->w; - size->mY = mWindow->h; - return (true); + SDL_GetWindowSizeInPixels(mWindow, &size->mX, &size->mY); + return true; } - return (false); + return false; } bool LLWindowSDL::setPosition(const LLCoordScreen position) { - if(mWindow) + if (mWindow) { - // *FIX: (?) - //MacMoveWindow(mWindow, position.mX, position.mY, false); + SDL_SetWindowPosition(mWindow, position.mX, position.mY); + return true; } - return true; + return false; } -bool LLWindowSDL::setSizeImpl(const LLCoordScreen size) +template< typename T > bool setSizeImpl( const T& newSize, SDL_Window *pWin ) { - if(mWindow) - { - // Push a resize event onto SDL's queue - we'll handle it - // when it comes out again. - SDL_Event event; - event.type = SDL_VIDEORESIZE; - event.resize.w = size.mX; - event.resize.h = size.mY; - SDL_PushEvent(&event); // copied into queue + if( !pWin ) + return false; - return true; - } + SDL_WindowFlags winFlags = SDL_GetWindowFlags(pWin); - return false; + if( winFlags & SDL_WINDOW_MAXIMIZED) + SDL_RestoreWindow(pWin); + + SDL_SetWindowSize(pWin, newSize.mX, newSize.mY); + return true; } -bool LLWindowSDL::setSizeImpl(const LLCoordWindow size) +bool LLWindowSDL::setSizeImpl(const LLCoordScreen size) { - if(mWindow) - { - // Push a resize event onto SDL's queue - we'll handle it - // when it comes out again. - SDL_Event event; - event.type = SDL_VIDEORESIZE; - event.resize.w = size.mX; - event.resize.h = size.mY; - SDL_PushEvent(&event); // copied into queue - - return true; - } + return ::setSizeImpl( size, mWindow ); +} - return false; +bool LLWindowSDL::setSizeImpl(const LLCoordWindow size) +{ + return ::setSizeImpl( size, mWindow ); } @@ -968,8 +667,9 @@ void LLWindowSDL::swapBuffers() { if (mWindow) { - SDL_GL_SwapBuffers(); + SDL_GL_SwapWindow(mWindow); } + LL_PROFILER_GPU_COLLECT; } U32 LLWindowSDL::getFSAASamples() @@ -984,22 +684,23 @@ void LLWindowSDL::setFSAASamples(const U32 samples) F32 LLWindowSDL::getGamma() { - return 1/mGamma; + return 1.f / mGamma; } bool LLWindowSDL::restoreGamma() { - //CGDisplayRestoreColorSyncSettings(); - SDL_SetGamma(1.0f, 1.0f, 1.0f); return true; } bool LLWindowSDL::setGamma(const F32 gamma) { - mGamma = gamma; - if (mGamma == 0) mGamma = 0.1f; - mGamma = 1/mGamma; - SDL_SetGamma(mGamma, mGamma, mGamma); + if (mWindow) + { + mGamma = gamma; + if (mGamma == 0) + mGamma = 0.1f; + mGamma = 1.f / mGamma; + } return true; } @@ -1008,12 +709,13 @@ bool LLWindowSDL::isCursorHidden() return mCursorHidden; } - - // Constrains the mouse to the window. -void LLWindowSDL::setMouseClipping( bool b ) +void LLWindowSDL::setMouseClipping(bool b) { - //SDL_WM_GrabInput(b ? SDL_GRAB_ON : SDL_GRAB_OFF); + if (mWindow) + { + SDL_SetWindowMouseGrab(mWindow, b); + } } // virtual @@ -1021,38 +723,16 @@ void LLWindowSDL::setMinSize(U32 min_width, U32 min_height, bool enforce_immedia { LLWindow::setMinSize(min_width, min_height, enforce_immediately); -#if LL_X11 - // Set the minimum size limits for X11 window - // so the window manager doesn't allow resizing below those limits. - XSizeHints* hints = XAllocSizeHints(); - hints->flags |= PMinSize; - hints->min_width = mMinWindowWidth; - hints->min_height = mMinWindowHeight; - - XSetWMNormalHints(mSDL_Display, mSDL_XWindowID, hints); - - XFree(hints); -#endif + if (mWindow && min_width > 0 && min_height > 0) + { + SDL_SetWindowMinimumSize(mWindow, mMinWindowWidth, mMinWindowHeight); + } } bool LLWindowSDL::setCursorPosition(const LLCoordWindow position) { - bool result = true; - LLCoordScreen screen_pos; - - if (!convertCoords(position, &screen_pos)) - { - return false; - } - - //LL_INFOS() << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << LL_ENDL; - - // do the actual forced cursor move. - SDL_WarpMouse(screen_pos.mX, screen_pos.mY); - - //LL_INFOS() << llformat("llcw %d,%d -> scr %d,%d", position.mX, position.mY, screen_pos.mX, screen_pos.mY) << LL_ENDL; - - return result; + SDL_WarpMouseInWindow(mWindow, (F32)position.mX, (F32)position.mY); + return true; } bool LLWindowSDL::getCursorPosition(LLCoordWindow *position) @@ -1060,54 +740,34 @@ bool LLWindowSDL::getCursorPosition(LLCoordWindow *position) //Point cursor_point; LLCoordScreen screen_pos; - //GetMouse(&cursor_point); - int x, y; + float x, y; SDL_GetMouseState(&x, &y); - screen_pos.mX = x; - screen_pos.mY = y; + screen_pos.mX = (S32)x; + screen_pos.mY = (S32)y; return convertCoords(screen_pos, position); } - F32 LLWindowSDL::getNativeAspectRatio() { -#if 0 + if (mOverrideAspectRatio > 0.f) + { + return mOverrideAspectRatio; + } + else if (mNativeAspectRatio > 0.f) + { + // we grabbed this value at startup, based on the user's desktop settings + return mNativeAspectRatio; + } + // RN: this hack presumes that the largest supported resolution is monitor-limited // and that pixels in that mode are square, therefore defining the native aspect ratio // of the monitor...this seems to work to a close approximation for most CRTs/LCDs S32 num_resolutions; LLWindowResolution* resolutions = getSupportedResolutions(num_resolutions); - return ((F32)resolutions[num_resolutions - 1].mWidth / (F32)resolutions[num_resolutions - 1].mHeight); - //rn: AC -#endif - - // MBW -- there are a couple of bad assumptions here. One is that the display list won't include - // ridiculous resolutions nobody would ever use. The other is that the list is in order. - - // New assumptions: - // - pixels are square (the only reasonable choice, really) - // - The user runs their display at a native resolution, so the resolution of the display - // when the app is launched has an aspect ratio that matches the monitor. - - //RN: actually, the assumption that there are no ridiculous resolutions (above the display's native capabilities) has - // been born out in my experience. - // Pixels are often not square (just ask the people who run their LCDs at 1024x768 or 800x600 when running fullscreen, like me) - // The ordering of display list is a blind assumption though, so we should check for max values - // Things might be different on the Mac though, so I'll defer to MBW - - // The constructor for this class grabs the aspect ratio of the monitor before doing any resolution - // switching, and stashes it in mOriginalAspectRatio. Here, we just return it. - - if (mOverrideAspectRatio > 0.f) - { - return mOverrideAspectRatio; - } - - return mOriginalAspectRatio; } F32 LLWindowSDL::getPixelAspectRatio() @@ -1130,104 +790,26 @@ F32 LLWindowSDL::getPixelAspectRatio() // dialogs are still usable in fullscreen. void LLWindowSDL::beforeDialog() { - bool running_x11 = false; -#if LL_X11 - running_x11 = (mSDL_XWindowID != None); -#endif //LL_X11 - LL_INFOS() << "LLWindowSDL::beforeDialog()" << LL_ENDL; if (SDLReallyCaptureInput(false)) // must ungrab input so popup works! { - if (mFullscreen) - { - // need to temporarily go non-fullscreen; bless SDL - // for providing a SDL_WM_ToggleFullScreen() - though - // it only works in X11 - if (running_x11 && mWindow) - { - SDL_WM_ToggleFullScreen(mWindow); - } - } - } - -#if LL_X11 - if (mSDL_Display) - { - // Everything that we/SDL asked for should happen before we - // potentially hand control over to GTK. - maybe_lock_display(); - XSync(mSDL_Display, False); - maybe_unlock_display(); + if (mFullscreen && mWindow ) + SDL_SetWindowFullscreen( mWindow, 0 ); } -#endif // LL_X11 - -#if LL_GTK - // this is a good time to grab some GTK version information for - // diagnostics, if not already done. - ll_try_gtk_init(); -#endif // LL_GTK - - maybe_lock_display(); } void LLWindowSDL::afterDialog() { - bool running_x11 = false; -#if LL_X11 - running_x11 = (mSDL_XWindowID != None); -#endif //LL_X11 - LL_INFOS() << "LLWindowSDL::afterDialog()" << LL_ENDL; - maybe_unlock_display(); - - if (mFullscreen) - { - // need to restore fullscreen mode after dialog - only works - // in X11 - if (running_x11 && mWindow) - { - SDL_WM_ToggleFullScreen(mWindow); - } - } -} - - -#if LL_X11 -// set/reset the XWMHints flag for 'urgency' that usually makes the icon flash -void LLWindowSDL::x11_set_urgent(bool urgent) -{ - if (mSDL_Display && !mFullscreen) - { - XWMHints *wm_hints; - - LL_INFOS() << "X11 hint for urgency, " << urgent << LL_ENDL; - - maybe_lock_display(); - wm_hints = XGetWMHints(mSDL_Display, mSDL_XWindowID); - if (!wm_hints) - wm_hints = XAllocWMHints(); - - if (urgent) - wm_hints->flags |= XUrgencyHint; - else - wm_hints->flags &= ~XUrgencyHint; - - XSetWMHints(mSDL_Display, mSDL_XWindowID, wm_hints); - XFree(wm_hints); - XSync(mSDL_Display, False); - maybe_unlock_display(); - } + if (mFullscreen && mWindow ) + SDL_SetWindowFullscreen( mWindow, 0 ); } -#endif // LL_X11 void LLWindowSDL::flashIcon(F32 seconds) { -#if !LL_X11 - LL_INFOS() << "Stub LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; -#else - LL_INFOS() << "X11 LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; + LL_INFOS() << "LLWindowSDL::flashIcon(" << seconds << ")" << LL_ENDL; F32 remaining_time = mFlashTimer.getRemainingTimeF32(); if (remaining_time < seconds) @@ -1235,132 +817,71 @@ void LLWindowSDL::flashIcon(F32 seconds) mFlashTimer.reset(); mFlashTimer.setTimerExpirySec(remaining_time); - x11_set_urgent(true); + SDL_FlashWindow(mWindow, SDL_FLASH_UNTIL_FOCUSED); mFlashing = true; -#endif // LL_X11 } - -#if LL_GTK -bool LLWindowSDL::isClipboardTextAvailable() +void LLWindowSDL::maybeStopFlashIcon() { - if (ll_try_gtk_init()) + if (mFlashing && mFlashTimer.hasExpired()) { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_NONE); - return gtk_clipboard_wait_is_text_available(clipboard) ? - true : false; + mFlashing = false; + SDL_FlashWindow( mWindow, SDL_FLASH_CANCEL ); } - return false; // failure } -bool LLWindowSDL::pasteTextFromClipboard(LLWString &text) +bool LLWindowSDL::isClipboardTextAvailable() { - if (ll_try_gtk_init()) + return SDL_HasClipboardText(); +} + +bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst) +{ + if (isClipboardTextAvailable()) { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_NONE); - gchar * const data = gtk_clipboard_wait_for_text(clipboard); + char* data = SDL_GetClipboardText(); if (data) { - text = LLWString(utf8str_to_wstring(data)); - g_free(data); + dst = LLWString(utf8str_to_wstring(data)); + SDL_free(data); return true; } } - return false; // failure + return false; } -bool LLWindowSDL::copyTextToClipboard(const LLWString &text) +bool LLWindowSDL::copyTextToClipboard(const LLWString& text) { - if (ll_try_gtk_init()) - { - const std::string utf8 = wstring_to_utf8str(text); - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_NONE); - gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); - return true; - } - return false; // failure + const std::string utf8 = wstring_to_utf8str(text); + return SDL_SetClipboardText(utf8.c_str()); } - bool LLWindowSDL::isPrimaryTextAvailable() { - if (ll_try_gtk_init()) - { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_SELECTION_PRIMARY); - return gtk_clipboard_wait_is_text_available(clipboard) ? - true : false; - } - return false; // failure + return SDL_HasPrimarySelectionText(); } -bool LLWindowSDL::pasteTextFromPrimary(LLWString &text) +bool LLWindowSDL::pasteTextFromPrimary(LLWString &dst) { - if (ll_try_gtk_init()) + if (isPrimaryTextAvailable()) { - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_SELECTION_PRIMARY); - gchar * const data = gtk_clipboard_wait_for_text(clipboard); + char* data = SDL_GetPrimarySelectionText(); if (data) { - text = LLWString(utf8str_to_wstring(data)); - g_free(data); + dst = LLWString(utf8str_to_wstring(data)); + SDL_free(data); return true; } } - return false; // failure -} - -bool LLWindowSDL::copyTextToPrimary(const LLWString &text) -{ - if (ll_try_gtk_init()) - { - const std::string utf8 = wstring_to_utf8str(text); - GtkClipboard * const clipboard = - gtk_clipboard_get(GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text(clipboard, utf8.c_str(), utf8.length()); - return true; - } - return false; // failure -} - -#else - -bool LLWindowSDL::isClipboardTextAvailable() -{ - return false; // unsupported -} - -bool LLWindowSDL::pasteTextFromClipboard(LLWString &dst) -{ - return false; // unsupported -} - -bool LLWindowSDL::copyTextToClipboard(const LLWString &s) -{ - return false; // unsupported -} - -bool LLWindowSDL::isPrimaryTextAvailable() -{ - return false; // unsupported -} - -bool LLWindowSDL::pasteTextFromPrimary(LLWString &dst) -{ - return false; // unsupported + return false; } -bool LLWindowSDL::copyTextToPrimary(const LLWString &s) +bool LLWindowSDL::copyTextToPrimary(const LLWString& text) { - return false; // unsupported + const std::string utf8 = wstring_to_utf8str(text); + return SDL_SetPrimarySelectionText(utf8.c_str()); } -#endif // LL_GTK - LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_resolutions) { if (!mSupportedResolutions) @@ -1368,28 +889,21 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso mSupportedResolutions = new LLWindowResolution[MAX_NUM_RESOLUTIONS]; mNumSupportedResolutions = 0; - SDL_Rect **modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN); - if ( (modes != NULL) && (modes != ((SDL_Rect **) -1)) ) - { - int count = 0; - while (*modes && countw; - int h = r->h; + SDL_DisplayID display = SDL_GetPrimaryDisplay(); + int num_modes = 0; + SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes); + num_modes = llclamp(num_modes, 0, MAX_NUM_RESOLUTIONS); + if (modes) { + for (int i = 0; i < num_modes; ++i) { + SDL_DisplayMode *mode = modes[i]; + int w = mode->w; + int h = mode->h; if ((w >= 800) && (h >= 600)) { // make sure we don't add the same resolution multiple times! if ( (mNumSupportedResolutions == 0) || - ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) && - (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) ) + ((mSupportedResolutions[mNumSupportedResolutions-1].mWidth != w) && + (mSupportedResolutions[mNumSupportedResolutions-1].mHeight != h)) ) { mSupportedResolutions[mNumSupportedResolutions].mWidth = w; mSupportedResolutions[mNumSupportedResolutions].mHeight = h; @@ -1397,6 +911,7 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso } } } + SDL_free(modes); } } @@ -1404,13 +919,42 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso return mSupportedResolutions; } +//static +std::vector LLWindowSDL::getDisplaysResolutionList() +{ + std::vector ret; + if (gWindowImplementation) + { + S32 resolutionCount = 0; + LLWindowResolution* resolutionList = gWindowImplementation->getSupportedResolutions(resolutionCount); + if (resolutionList != nullptr) + { + for (S32 i = 0; i < resolutionCount; i++) + { + const LLWindowResolution& resolution = resolutionList[i]; + ret.push_back(std::to_string(resolution.mWidth) + "x" + std::to_string(resolution.mHeight)); + } + } + } + return ret; +} + + bool LLWindowSDL::convertCoords(LLCoordGL from, LLCoordWindow *to) { if (!to) return false; - to->mX = from.mX; - to->mY = mWindow->h - from.mY - 1; + if (!mWindow) + return false; + + S32 height; + SDL_GetWindowSizeInPixels(mWindow, nullptr, &height); + + float pixel_scale = SDL_GetWindowPixelDensity(mWindow); + + to->mX = from.mX / pixel_scale; + to->mY = (height - from.mY - 1) / pixel_scale; return true; } @@ -1420,8 +964,15 @@ bool LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordGL* to) if (!to) return false; - to->mX = from.mX; - to->mY = mWindow->h - from.mY - 1; + if (!mWindow) + return false; + S32 height; + SDL_GetWindowSize(mWindow, nullptr, &height); + + float pixel_scale = SDL_GetWindowPixelDensity(mWindow); + + to->mX = from.mX * pixel_scale; + to->mY = (height - from.mY - 1) * pixel_scale; return true; } @@ -1434,7 +985,7 @@ bool LLWindowSDL::convertCoords(LLCoordScreen from, LLCoordWindow* to) // In the fullscreen case, window and screen coordinates are the same. to->mX = from.mX; to->mY = from.mY; - return (true); + return true; } bool LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordScreen *to) @@ -1445,29 +996,26 @@ bool LLWindowSDL::convertCoords(LLCoordWindow from, LLCoordScreen *to) // In the fullscreen case, window and screen coordinates are the same. to->mX = from.mX; to->mY = from.mY; - return (true); + return true; } bool LLWindowSDL::convertCoords(LLCoordScreen from, LLCoordGL *to) { LLCoordWindow window_coord; - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); + return convertCoords(from, &window_coord) && convertCoords(window_coord, to); } bool LLWindowSDL::convertCoords(LLCoordGL from, LLCoordScreen *to) { LLCoordWindow window_coord; - return(convertCoords(from, &window_coord) && convertCoords(window_coord, to)); + return convertCoords(from, &window_coord) && convertCoords(window_coord, to); } - - - void LLWindowSDL::setupFailure(const std::string& text, const std::string& caption, U32 type) { - destroyContext(); + close(); OSMessageBox(text, caption, type); } @@ -1482,13 +1030,13 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture) else mReallyCapturedCount = 0; - SDL_GrabMode wantmode, newmode; + bool wantGrab; if (mReallyCapturedCount <= 0) // uncapture { - wantmode = SDL_GRAB_OFF; + wantGrab = false; } else // capture { - wantmode = SDL_GRAB_ON; + wantGrab = true; } if (mReallyCapturedCount < 0) // yuck, imbalance. @@ -1497,64 +1045,32 @@ bool LLWindowSDL::SDLReallyCaptureInput(bool capture) LL_WARNS() << "ReallyCapture count was < 0" << LL_ENDL; } + bool newGrab = wantGrab; if (!mFullscreen) /* only bother if we're windowed anyway */ { -#if LL_X11 - if (mSDL_Display) + int result; + if (wantGrab) { - /* we dirtily mix raw X11 with SDL so that our pointer - isn't (as often) constrained to the limits of the - window while grabbed, which feels nicer and - hopefully eliminates some reported 'sticky pointer' - problems. We use raw X11 instead of - SDL_WM_GrabInput() because the latter constrains - the pointer to the window and also steals all - *keyboard* input from the window manager, which was - frustrating users. */ - int result; - if (wantmode == SDL_GRAB_ON) - { - //LL_INFOS() << "X11 POINTER GRABBY" << LL_ENDL; - //newmode = SDL_WM_GrabInput(wantmode); - maybe_lock_display(); - result = XGrabPointer(mSDL_Display, mSDL_XWindowID, - True, 0, GrabModeAsync, - GrabModeAsync, - None, None, CurrentTime); - maybe_unlock_display(); - if (GrabSuccess == result) - newmode = SDL_GRAB_ON; - else - newmode = SDL_GRAB_OFF; - } else if (wantmode == SDL_GRAB_OFF) - { - //LL_INFOS() << "X11 POINTER UNGRABBY" << LL_ENDL; - newmode = SDL_GRAB_OFF; - //newmode = SDL_WM_GrabInput(SDL_GRAB_OFF); - - maybe_lock_display(); - XUngrabPointer(mSDL_Display, CurrentTime); - // Make sure the ungrab happens RIGHT NOW. - XSync(mSDL_Display, False); - maybe_unlock_display(); - } else - { - newmode = SDL_GRAB_QUERY; // neutral - } - } else // not actually running on X11, for some reason - newmode = wantmode; -#endif // LL_X11 - } else { - // pretend we got what we wanted, when really we don't care. - newmode = wantmode; + // LL_INFOS() << "X11 POINTER GRABBY" << LL_ENDL; + result = SDL_SetWindowMouseGrab(mWindow, true); + if (0 == result) + newGrab = true; + else + newGrab = false; + } + else + { + newGrab = false; + result = SDL_SetWindowMouseGrab(mWindow, false); + } } + // pretend we got what we wanted, when really we don't care. // return boolean success for whether we ended up in the desired state - return (capture && SDL_GRAB_ON==newmode) || - (!capture && SDL_GRAB_OFF==newmode); + return capture == newGrab; } -U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain) +U32 LLWindowSDL::SDLCheckGrabbyKeys(U32 keysym, bool gain) { /* part of the fix for SL-13243: Some popular window managers like to totally eat alt-drag for the purposes of moving windows. We @@ -1572,16 +1088,16 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain) U32 mask = 0; switch (keysym) { - case SDLK_LALT: - mask = 1U << 0; break; - case SDLK_RALT: - mask = 1U << 1; break; - case SDLK_LCTRL: - mask = 1U << 2; break; - case SDLK_RCTRL: - mask = 1U << 3; break; - default: - break; + case SDLK_LALT: + mask = 1U << 0; break; + case SDLK_RALT: + mask = 1U << 1; break; + case SDLK_LCTRL: + mask = 1U << 2; break; + case SDLK_RCTRL: + mask = 1U << 3; break; + default: + break; } if (gain) @@ -1595,371 +1111,257 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(SDLKey keysym, bool gain) return mGrabbyKeyFlags; } +// virtual +void LLWindowSDL::processMiscNativeEvents() +{ +} -void check_vm_bloat() +void LLWindowSDL::gatherInput() { -#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"); - if (fp) - { - static long long last_vm_size = 0; - static long long last_rss_size = 0; - const long long significant_vm_difference = 250 * 1024*1024; - const long long significant_rss_difference = 50 * 1024*1024; - long long this_vm_size = 0; - long long this_rss_size = 0; - - ssize_t res; - size_t dummy; - char *ptr = NULL; - for (int i=0; i<22; ++i) // parse past the values we don't want + // This is for the case where SDL is not driving the main event loop + if(!gSDLMainHandled) + { + SDL_Event event; + + // Handle all outstanding SDL events + while (SDL_PollEvent(&event)) { - res = getdelim(&ptr, &dummy, ' ', fp); - if (-1 == res) - { - LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; - goto finally; - } - free(ptr); - ptr = NULL; + handleEvent(event); } - // 23rd space-delimited entry is vsize - res = getdelim(&ptr, &dummy, ' ', fp); - llassert(ptr); - if (-1 == res) + } + + updateCursor(); + + // This is a good time to stop flashing the icon if our mFlashTimer has + // expired. + if (mFlashing && mFlashTimer.hasExpired()) + { + SDL_FlashWindow(mWindow, SDL_FLASH_CANCEL); + mFlashing = false; + } +} + +SDL_AppResult LLWindowSDL::handleEvent(const SDL_Event& event) +{ + switch(event.type) + { + case SDL_EVENT_MOUSE_MOTION: { - LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; - goto finally; + LLCoordWindow winCoord(llfloor(event.motion.x), llfloor(event.motion.y)); + LLCoordGL openGlCoord; + convertCoords(winCoord, &openGlCoord); + mCallbacks->handleMouseMove(this, openGlCoord, gKeyboard->currentMask(true)); + break; } - this_vm_size = atoll(ptr); - free(ptr); - ptr = NULL; - // 24th space-delimited entry is RSS - res = getdelim(&ptr, &dummy, ' ', fp); - llassert(ptr); - if (-1 == res) + + case SDL_EVENT_MOUSE_WHEEL: { - LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; - goto finally; + if(event.wheel.integer_y != 0) + { + mCallbacks->handleScrollWheel(this, -event.wheel.integer_y); + } + if (event.wheel.integer_x != 0) + { + mCallbacks->handleScrollHWheel(this, -event.wheel.integer_x); + } + break; } - this_rss_size = getpagesize() * atoll(ptr); - free(ptr); - ptr = NULL; - LL_INFOS() << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << LL_ENDL; - - if (llabs(last_vm_size - this_vm_size) > - significant_vm_difference) + case SDL_EVENT_MOUSE_BUTTON_DOWN: { - if (this_vm_size > last_vm_size) + LLCoordWindow winCoord(llfloor(event.button.x), llfloor(event.button.y)); + LLCoordGL openGlCoord; + convertCoords(winCoord, &openGlCoord); + MASK mask = gKeyboard->currentMask(true); + + if (event.button.button == SDL_BUTTON_LEFT) // left + { + if (event.button.clicks == 2) + mCallbacks->handleDoubleClick(this, openGlCoord, mask); + else + mCallbacks->handleMouseDown(this, openGlCoord, mask); + } + else if (event.button.button == SDL_BUTTON_RIGHT) + { + mCallbacks->handleRightMouseDown(this, openGlCoord, mask); + } + else if (event.button.button == SDL_BUTTON_MIDDLE) // middle { - LL_WARNS() << "VM size grew by " << (this_vm_size - last_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask); } else { - LL_INFOS() << "VM size shrank by " << (last_vm_size - this_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + mCallbacks->handleOtherMouseDown(this, openGlCoord, mask, event.button.button); } + + break; } - if (llabs(last_rss_size - this_rss_size) > - significant_rss_difference) + case SDL_EVENT_MOUSE_BUTTON_UP: { - if (this_rss_size > last_rss_size) + LLCoordWindow winCoord(llfloor(event.button.x), llfloor(event.button.y)); + LLCoordGL openGlCoord; + convertCoords(winCoord, &openGlCoord); + MASK mask = gKeyboard->currentMask(true); + + if (event.button.button == SDL_BUTTON_LEFT) // left + { + mCallbacks->handleMouseUp(this, openGlCoord, mask); + } + else if (event.button.button == SDL_BUTTON_RIGHT) // right + { + mCallbacks->handleRightMouseUp(this, openGlCoord, mask); + } + else if (event.button.button == SDL_BUTTON_MIDDLE) // middle { - LL_WARNS() << "RSS size grew by " << (this_rss_size - last_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); } else { - LL_INFOS() << "RSS size shrank by " << (last_rss_size - this_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + mCallbacks->handleOtherMouseUp(this, openGlCoord, mask, event.button.button); } - } - last_rss_size = this_rss_size; - last_vm_size = this_vm_size; - -finally: - if (NULL != ptr) - { - free(ptr); - ptr = NULL; + break; } - fclose(fp); - } -#endif // LL_LINUX -} - - -// virtual -void LLWindowSDL::processMiscNativeEvents() -{ -#if LL_GTK - // Pump GTK events to avoid starvation for: - // * DBUS servicing - // * Anything else which quietly hooks into the default glib/GTK loop - if (ll_try_gtk_init()) - { - // Yuck, Mozilla's GTK callbacks play with the locale - push/pop - // the locale to protect it, as exotic/non-C locales - // causes our code lots of general critical weirdness - // and crashness. (SL-35450) - static std::string saved_locale; - saved_locale = ll_safe_string(setlocale(LC_ALL, NULL)); - // Pump until we've nothing left to do or passed 1/15th of a - // second pumping for this frame. - static LLTimer pump_timer; - pump_timer.reset(); - pump_timer.setTimerExpirySec(1.0f / 15.0f); - do { - // Always do at least one non-blocking pump - gtk_main_iteration_do(false); - } while (gtk_events_pending() && - !pump_timer.hasExpired()); - - setlocale(LC_ALL, saved_locale.c_str() ); - } -#endif // LL_GTK + case SDL_EVENT_KEY_DOWN: + { + mKeyVirtualKey = event.key.key; + mKeyModifiers = event.key.mod; - // hack - doesn't belong here - but this is just for debugging - if (getenv("LL_DEBUG_BLOAT")) - { - check_vm_bloat(); - } -} + if (mKeyVirtualKey == SDLK_RETURN2 || mKeyVirtualKey == SDLK_KP_ENTER) + { + mKeyVirtualKey = SDLK_RETURN; + } -void LLWindowSDL::gatherInput() -{ - const Uint32 CLICK_THRESHOLD = 300; // milliseconds - static int leftClick = 0; - static int rightClick = 0; - static Uint32 lastLeftDown = 0; - static Uint32 lastRightDown = 0; - SDL_Event event; + gKeyboard->handleKeyDown(mKeyVirtualKey, mKeyModifiers); - // Handle all outstanding SDL events - while (SDL_PollEvent(&event)) - { - switch (event.type) - { - case SDL_MOUSEMOTION: + if (mKeyVirtualKey == SDLK_RETURN) { - LLCoordWindow winCoord(event.button.x, event.button.y); - LLCoordGL openGlCoord; - convertCoords(winCoord, &openGlCoord); - MASK mask = gKeyboard->currentMask(true); - mCallbacks->handleMouseMove(this, openGlCoord, mask); - break; + // fix return key not working when capslock, scrolllock or numlock are enabled + mKeyModifiers &= (~(SDL_KMOD_NUM | SDL_KMOD_CAPS | SDL_KMOD_MODE | SDL_KMOD_SCROLL)); + mCallbacks->handleUnicodeChar(mKeyVirtualKey, gKeyboard->currentMask(false)); } - case SDL_KEYDOWN: - mKeyScanCode = event.key.keysym.scancode; - mKeyVirtualKey = event.key.keysym.unicode; - mKeyModifiers = event.key.keysym.mod; - - gKeyboard->handleKeyDown(event.key.keysym.sym, event.key.keysym.mod); // part of the fix for SL-13243 - if (SDLCheckGrabbyKeys(event.key.keysym.sym, true) != 0) + if (SDLCheckGrabbyKeys(mKeyVirtualKey, true) != 0) SDLReallyCaptureInput(true); + break; + } + + case SDL_EVENT_KEY_UP: + { + mKeyVirtualKey = event.key.key; + mKeyModifiers = event.key.mod; - if (event.key.keysym.unicode) + if (mKeyVirtualKey == SDLK_RETURN2 || mKeyVirtualKey == SDLK_KP_ENTER) { - handleUnicodeUTF16(event.key.keysym.unicode, - gKeyboard->currentMask(false)); + mKeyVirtualKey = SDLK_RETURN; } - break; - - case SDL_KEYUP: - mKeyScanCode = event.key.keysym.scancode; - mKeyVirtualKey = event.key.keysym.unicode; - mKeyModifiers = event.key.keysym.mod; - if (SDLCheckGrabbyKeys(event.key.keysym.sym, false) == 0) + gKeyboard->handleKeyUp(mKeyVirtualKey, mKeyModifiers); + if (SDLCheckGrabbyKeys(mKeyVirtualKey, false) == 0) SDLReallyCaptureInput(false); // part of the fix for SL-13243 - - gKeyboard->handleKeyUp(event.key.keysym.sym, event.key.keysym.mod); break; + } - case SDL_MOUSEBUTTONDOWN: - { - bool isDoubleClick = false; - LLCoordWindow winCoord(event.button.x, event.button.y); - LLCoordGL openGlCoord; - convertCoords(winCoord, &openGlCoord); - MASK mask = gKeyboard->currentMask(true); - - if (event.button.button == SDL_BUTTON_LEFT) // SDL doesn't manage double clicking... - { - Uint32 now = SDL_GetTicks(); - if ((now - lastLeftDown) > CLICK_THRESHOLD) - leftClick = 1; - else - { - if (++leftClick >= 2) - { - leftClick = 0; - isDoubleClick = true; - } - } - lastLeftDown = now; - } - else if (event.button.button == SDL_BUTTON_RIGHT) - { - Uint32 now = SDL_GetTicks(); - if ((now - lastRightDown) > CLICK_THRESHOLD) - rightClick = 1; - else - { - if (++rightClick >= 2) - { - rightClick = 0; - isDoubleClick = true; - } - } - lastRightDown = now; - } - - if (event.button.button == SDL_BUTTON_LEFT) // left - { - if (isDoubleClick) - mCallbacks->handleDoubleClick(this, openGlCoord, mask); - else - mCallbacks->handleMouseDown(this, openGlCoord, mask); - } - - else if (event.button.button == SDL_BUTTON_RIGHT) // right - { - mCallbacks->handleRightMouseDown(this, openGlCoord, mask); - } - - else if (event.button.button == SDL_BUTTON_MIDDLE) // middle - { - mCallbacks->handleMiddleMouseDown(this, openGlCoord, mask); - } - else if (event.button.button == 4) // mousewheel up...thanks to X11 for making SDL consider these "buttons". - mCallbacks->handleScrollWheel(this, -1); - else if (event.button.button == 5) // mousewheel down...thanks to X11 for making SDL consider these "buttons". - mCallbacks->handleScrollWheel(this, 1); - - break; - } - - case SDL_MOUSEBUTTONUP: + case SDL_EVENT_TEXT_INPUT: + { + auto string = utf8str_to_wstring(event.text.text); + MASK current_mask = gKeyboard->currentMask(false); + for (auto key : string) { - LLCoordWindow winCoord(event.button.x, event.button.y); - LLCoordGL openGlCoord; - convertCoords(winCoord, &openGlCoord); - MASK mask = gKeyboard->currentMask(true); - - if (event.button.button == SDL_BUTTON_LEFT) // left - mCallbacks->handleMouseUp(this, openGlCoord, mask); - else if (event.button.button == SDL_BUTTON_RIGHT) // right - mCallbacks->handleRightMouseUp(this, openGlCoord, mask); - else if (event.button.button == SDL_BUTTON_MIDDLE) // middle - mCallbacks->handleMiddleMouseUp(this, openGlCoord, mask); - // don't handle mousewheel here... - - break; + mKeyVirtualKey = key; + mCallbacks->handleUnicodeChar(key, current_mask); } + break; + } - case SDL_VIDEOEXPOSE: // VIDEOEXPOSE doesn't specify the damage, but hey, it's OpenGL...repaint the whole thing! - mCallbacks->handlePaint(this, 0, 0, mWindow->w, mWindow->h); - break; - - case SDL_VIDEORESIZE: // *FIX: handle this? - { - LL_INFOS() << "Handling a resize event: " << event.resize.w << - "x" << event.resize.h << LL_ENDL; - - S32 width = llmax(event.resize.w, (S32)mMinWindowWidth); - S32 height = llmax(event.resize.h, (S32)mMinWindowHeight); - - // *FIX: I'm not sure this is necessary! - mWindow = SDL_SetVideoMode(width, height, 32, mSDLFlags); - if (!mWindow) + case SDL_EVENT_WINDOW_EXPOSED: { - // *FIX: More informative dialog? - LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL; - if(mCallbacks->handleCloseRequest(this, false)) - { - // Get the app to initiate cleanup. - mCallbacks->handleQuit(this); - // The app is responsible for calling destroyWindow when done with GL - } - break; + mCallbacks->handlePaint(this, 0, 0, 0, 0); + break; } - mCallbacks->handleResize(this, width, height); - break; - } - case SDL_ACTIVEEVENT: - if (event.active.state & SDL_APPINPUTFOCUS) - { - // Note that for SDL (particularly on X11), keyboard - // and mouse focus are independent things. Here we are - // tracking keyboard focus state changes. - - // We have to do our own state massaging because SDL - // can send us two unfocus events in a row for example, - // which confuses the focus code [SL-24071]. - if (event.active.gain != mHaveInputFocus) - { - mHaveInputFocus = !!event.active.gain; + case SDL_EVENT_WINDOW_RESIZED: + { + LL_INFOS() << "Handling a resize event: " << event.window.data1 << "x" << event.window.data2 << LL_ENDL; + F32 pixel_density = SDL_GetWindowPixelDensity(mWindow); + S32 width = llmax(event.window.data1, (S32)mMinWindowWidth) * pixel_density; + S32 height = llmax(event.window.data2, (S32)mMinWindowHeight) * pixel_density; - if (mHaveInputFocus) - mCallbacks->handleFocus(this); - else - mCallbacks->handleFocusLost(this); - } - } - if (event.active.state & SDL_APPACTIVE) - { - // Change in iconification/minimization state. - if ((!event.active.gain) != mIsMinimized) + mCallbacks->handleResize(this, width, height); + break; + } + case SDL_EVENT_WINDOW_MOUSE_ENTER: + break; + case SDL_EVENT_WINDOW_MOUSE_LEAVE: + mCallbacks->handleMouseLeave(this); + break; + case SDL_EVENT_WINDOW_FOCUS_GAINED: + //SDL_SetWindowKeyboardGrab(mWindow, true); + mCallbacks->handleFocus(this); + break; + case SDL_EVENT_WINDOW_FOCUS_LOST: + mCallbacks->handleFocusLost(this); + //SDL_SetWindowKeyboardGrab(mWindow, false); + break; + case SDL_EVENT_WINDOW_RESTORED: + mCallbacks->handleActivate(this, true); + break; + case SDL_EVENT_WINDOW_MAXIMIZED: + mCallbacks->handleActivate(this, true); + break; + case SDL_EVENT_WINDOW_MINIMIZED: + mCallbacks->handleActivate(this, false); + break; + case SDL_EVENT_WINDOW_DISPLAY_CHANGED: + { + // Update refresh rate when changing monitors + const SDL_DisplayMode* displayMode = SDL_GetCurrentDisplayMode(event.window.data1); + if(displayMode) { - mIsMinimized = (!event.active.gain); - - mCallbacks->handleActivate(this, !mIsMinimized); - LL_INFOS() << "SDL deiconification state switched to " << bool(event.active.gain) << LL_ENDL; + mRefreshRate = ll_round(displayMode->refresh_rate); + mNativeAspectRatio = ((F32)displayMode->w) / ((F32)displayMode->h); } - else + mCallbacks->handleDisplayChanged(); + break; + } + case SDL_EVENT_WINDOW_DISPLAY_SCALE_CHANGED: + { + S32 w, h = 0; + SDL_GetWindowSizeInPixels(mWindow, &w, &h); + mCallbacks->handleDPIChanged(this, getSystemUISize(), w, h); + break; + } + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + { + if(mCallbacks->handleCloseRequest(this, true)) { - LL_INFOS() << "Ignored bogus redundant SDL deiconification state switch to " << bool(event.active.gain) << LL_ENDL; + // Get the app to initiate cleanup. + mCallbacks->handleQuit(this); + // The app is responsible for calling destroyWindow when done with GL } - } - break; - - case SDL_QUIT: - if(mCallbacks->handleCloseRequest(this, true)) - { - // Get the app to initiate cleanup. - mCallbacks->handleQuit(this); - // The app is responsible for calling destroyWindow when done with GL - } - break; - default: - //LL_INFOS() << "Unhandled SDL event type " << event.type << LL_ENDL; - break; + break; } + default: + break; } - updateCursor(); + return SDL_APP_CONTINUE; +} -#if LL_X11 - // This is a good time to stop flashing the icon if our mFlashTimer has - // expired. - if (mFlashing && mFlashTimer.hasExpired()) - { - x11_set_urgent(false); - mFlashing = false; - } -#endif // LL_X11 +// static +SDL_AppResult LLWindowSDL::handleEvents(const SDL_Event& event) +{ + if(!gWindowImplementation) return SDL_APP_CONTINUE; + + return gWindowImplementation->handleEvent(event); } static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty) { - SDL_Cursor *sdlcursor = NULL; + SDL_Cursor *sdlcursor = nullptr; SDL_Surface *bmpsurface; // Load cursor pixel data from BMP file @@ -1968,21 +1370,32 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty { SDL_Surface *cursurface; LL_DEBUGS() << "Loaded cursor file " << filename << " " - << bmpsurface->w << "x" << bmpsurface->h << LL_ENDL; - cursurface = SDL_CreateRGBSurface (SDL_SWSURFACE, - bmpsurface->w, - bmpsurface->h, - 32, - SDL_SwapLE32(0xFFU), - SDL_SwapLE32(0xFF00U), - SDL_SwapLE32(0xFF0000U), - SDL_SwapLE32(0xFF000000U)); - SDL_FillRect(cursurface, NULL, SDL_SwapLE32(0x00000000U)); + << bmpsurface->w << "x" << bmpsurface->h << LL_ENDL; + SDL_PixelFormat pix_format = SDL_GetPixelFormatForMasks(32, + SDL_Swap32LE(0xFFU), + SDL_Swap32LE(0xFF00U), + SDL_Swap32LE(0xFF0000U), + SDL_Swap32LE(0xFF000000U)); + if (pix_format == SDL_PIXELFORMAT_UNKNOWN) + { + return nullptr; + } + + const SDL_PixelFormatDetails* pix_format_details = SDL_GetPixelFormatDetails(pix_format); + if(!pix_format_details) + { + return nullptr; + } + + cursurface = SDL_CreateSurface(bmpsurface->w, + bmpsurface->h, + pix_format); + SDL_FillSurfaceRect(cursurface, nullptr, SDL_Swap32LE(0x00000000U)); // Blit the cursor pixel data onto a 32-bit RGBA surface so we // only have to cope with processing one type of pixel format. - if (0 == SDL_BlitSurface(bmpsurface, NULL, - cursurface, NULL)) + if (SDL_BlitSurface(bmpsurface, nullptr, + cursurface, nullptr)) { // n.b. we already checked that width is a multiple of 8. const int bitmap_bytes = (cursurface->w * cursurface->h) / 8; @@ -1997,33 +1410,33 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty for (i=0; ih; ++i) { for (j=0; jw; ++j) { U8 *pixelp = - ((U8*)cursurface->pixels) - + cursurface->pitch * i - + j*cursurface->format->BytesPerPixel; + ((U8*)cursurface->pixels) + + cursurface->pitch * i + + j*pix_format_details->bytes_per_pixel; U8 srcred = pixelp[0]; U8 srcgreen = pixelp[1]; U8 srcblue = pixelp[2]; bool mask_bit = (srcred != 200) - || (srcgreen != 200) - || (srcblue != 200); + || (srcgreen != 200) + || (srcblue != 200); bool data_bit = mask_bit && (srcgreen <= 80);//not 0x80 unsigned char bit_offset = (cursurface->w/8) * i - + j/8; + + j/8; cursor_data[bit_offset] |= (data_bit) << (7 - (j&7)); cursor_mask[bit_offset] |= (mask_bit) << (7 - (j&7)); } } sdlcursor = SDL_CreateCursor((Uint8*)cursor_data, - (Uint8*)cursor_mask, - cursurface->w, cursurface->h, - hotx, hoty); + (Uint8*)cursor_mask, + cursurface->w, cursurface->h, + hotx, hoty); delete[] cursor_data; delete[] cursor_mask; } else { LL_WARNS() << "CURSOR BLIT FAILURE, cursurface: " << cursurface << LL_ENDL; } - SDL_FreeSurface(cursurface); - SDL_FreeSurface(bmpsurface); + SDL_DestroySurface(cursurface); + SDL_DestroySurface(bmpsurface); } else { LL_WARNS() << "CURSOR LOAD FAILURE " << filename << LL_ENDL; } @@ -2033,12 +1446,6 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty void LLWindowSDL::updateCursor() { - if (ATIbug) { - // cursor-updating is very flaky when this bug is - // present; do nothing. - return; - } - if (mCurrentCursor != mNextCursor) { if (mNextCursor < UI_CURSOR_COUNT) @@ -2050,37 +1457,40 @@ void LLWindowSDL::updateCursor() sdlcursor = mSDLCursors[UI_CURSOR_ARROW]; if (sdlcursor) SDL_SetCursor(sdlcursor); - } else { + + mCurrentCursor = mNextCursor; + } + else + { LL_WARNS() << "Tried to set invalid cursor number " << mNextCursor << LL_ENDL; } - mCurrentCursor = mNextCursor; } } void LLWindowSDL::initCursors() { - int i; // Blank the cursor pointer array for those we may miss. - for (i=0; ibeforeDialog(); - - if (LLWindowSDL::ll_try_gtk_init()) + switch (type) { - GtkWidget *win = NULL; - - LL_INFOS() << "Creating a dialog because we're in windowed mode and GTK is happy." << LL_ENDL; - - GtkDialogFlags flags = GTK_DIALOG_MODAL; - GtkMessageType messagetype; - GtkButtonsType buttons; - switch (type) - { default: case OSMB_OK: - messagetype = GTK_MESSAGE_WARNING; - buttons = GTK_BUTTONS_OK; + oData.flags = SDL_MESSAGEBOX_WARNING; + oData.buttons = btnOk; + oData.numbuttons = 1; break; case OSMB_OKCANCEL: - messagetype = GTK_MESSAGE_QUESTION; - buttons = GTK_BUTTONS_OK_CANCEL; + oData.flags = SDL_MESSAGEBOX_INFORMATION; + oData.buttons = btnOkCancel; + oData.numbuttons = 2; break; case OSMB_YESNO: - messagetype = GTK_MESSAGE_QUESTION; - buttons = GTK_BUTTONS_YES_NO; + oData.flags = SDL_MESSAGEBOX_INFORMATION; + oData.buttons = btnYesNo; + oData.numbuttons = 2; break; - } - win = gtk_message_dialog_new(NULL, flags, messagetype, buttons, "%s", - text.c_str()); - -# if LL_X11 - // Make GTK tell the window manager to associate this - // dialog with our non-GTK SDL window, which should try - // to keep it on top etc. - if (gWindowImplementation && - gWindowImplementation->mSDL_XWindowID != None) - { - gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin - GdkWindow *gdkwin = gdk_window_foreign_new(gWindowImplementation->mSDL_XWindowID); - gdk_window_set_transient_for(GTK_WIDGET(win)->window, - gdkwin); - } -# endif //LL_X11 - - gtk_window_set_position(GTK_WINDOW(win), - GTK_WIN_POS_CENTER_ON_PARENT); - - gtk_window_set_type_hint(GTK_WINDOW(win), - GDK_WINDOW_TYPE_HINT_DIALOG); - - if (!caption.empty()) - gtk_window_set_title(GTK_WINDOW(win), caption.c_str()); - - gint response = GTK_RESPONSE_NONE; - g_signal_connect (win, - "response", - G_CALLBACK (response_callback), - &response); + } - // we should be able to use a gtk_dialog_run(), but it's - // apparently not written to exist in a world without a higher - // gtk_main(), so we manage its signal/destruction outselves. - gtk_widget_show_all (win); - gtk_main(); + if(gWindowImplementation != nullptr) + gWindowImplementation->beforeDialog(); - //LL_INFOS() << "response: " << response << LL_ENDL; - switch (response) - { - case GTK_RESPONSE_OK: rtn = OSBTN_OK; break; - case GTK_RESPONSE_YES: rtn = OSBTN_YES; break; - case GTK_RESPONSE_NO: rtn = OSBTN_NO; break; - case GTK_RESPONSE_APPLY: rtn = OSBTN_OK; break; - case GTK_RESPONSE_NONE: - case GTK_RESPONSE_CANCEL: - case GTK_RESPONSE_CLOSE: - case GTK_RESPONSE_DELETE_EVENT: - default: rtn = OSBTN_CANCEL; - } - } - else + int btn{0}; + if(SDL_ShowMessageBox( &oData, &btn )) { - LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; - LL_INFOS() << "Skipping dialog because we're in fullscreen mode or GTK is not happy." << LL_ENDL; - rtn = OSBTN_OK; + if(gWindowImplementation != nullptr) + gWindowImplementation->afterDialog(); + return btn; } - if(gWindowImplementation != NULL) + if(gWindowImplementation != nullptr) gWindowImplementation->afterDialog(); - return rtn; + return OSBTN_CANCEL; } -static void color_changed_callback(GtkWidget *widget, - gpointer user_data) +bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) { - GtkColorSelection *colorsel = GTK_COLOR_SELECTION(widget); - GdkColor *colorp = (GdkColor*)user_data; - - gtk_color_selection_get_current_color(colorsel, colorp); + return false; } - /* Make the raw keyboard data available - used to poke through to LLQtWebKit so that Qt/Webkit has access to the virtual keycodes etc. that it needs */ LLSD LLWindowSDL::getNativeKeyData() { - LLSD result = LLSD::emptyMap(); + LLSD result = LLSD::emptyMap(); U32 modifiers = 0; // pretend-native modifiers... oh what a tangled web we weave! @@ -2367,140 +1700,21 @@ LLSD LLWindowSDL::getNativeKeyData() // what a plugin under GDK under Qt under SL under SDL under X11 considers // a 'native' modifier mask. this has been sort of reverse-engineered... they *appear* // to match GDK consts, but that may be co-incidence. - modifiers |= (mKeyModifiers & KMOD_LSHIFT) ? 0x0001 : 0; - modifiers |= (mKeyModifiers & KMOD_RSHIFT) ? 0x0001 : 0;// munge these into the same shift - modifiers |= (mKeyModifiers & KMOD_CAPS) ? 0x0002 : 0; - modifiers |= (mKeyModifiers & KMOD_LCTRL) ? 0x0004 : 0; - modifiers |= (mKeyModifiers & KMOD_RCTRL) ? 0x0004 : 0;// munge these into the same ctrl - modifiers |= (mKeyModifiers & KMOD_LALT) ? 0x0008 : 0;// untested - modifiers |= (mKeyModifiers & KMOD_RALT) ? 0x0008 : 0;// untested + modifiers |= (mKeyModifiers & SDL_KMOD_LSHIFT) ? 0x0001 : 0; + modifiers |= (mKeyModifiers & SDL_KMOD_RSHIFT) ? 0x0001 : 0;// munge these into the same shift + modifiers |= (mKeyModifiers & SDL_KMOD_CAPS) ? 0x0002 : 0; + modifiers |= (mKeyModifiers & SDL_KMOD_LCTRL) ? 0x0004 : 0; + modifiers |= (mKeyModifiers & SDL_KMOD_RCTRL) ? 0x0004 : 0;// munge these into the same ctrl + modifiers |= (mKeyModifiers & SDL_KMOD_LALT) ? 0x0008 : 0;// untested + modifiers |= (mKeyModifiers & SDL_KMOD_RALT) ? 0x0008 : 0;// untested // *todo: test ALTs - I don't have a case for testing these. Do you? // *todo: NUM? - I don't care enough right now (and it's not a GDK modifier). - result["scan_code"] = (S32)mKeyScanCode; - result["virtual_key"] = (S32)mKeyVirtualKey; + result["virtual_key"] = (S32)mKeyVirtualKey; + result["virtual_key_win"] = (S32)LLKeyboardSDL::mapSDL2toWin( mKeyVirtualKey ); result["modifiers"] = (S32)modifiers; - - return result; -} - - -bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) -{ - bool rtn = false; - - beforeDialog(); - - if (ll_try_gtk_init()) - { - GtkWidget *win = NULL; - - win = gtk_color_selection_dialog_new(NULL); - -# if LL_X11 - // Get GTK to tell the window manager to associate this - // dialog with our non-GTK SDL window, which should try - // to keep it on top etc. - if (mSDL_XWindowID != None) - { - gtk_widget_realize(GTK_WIDGET(win)); // so we can get its gdkwin - GdkWindow *gdkwin = gdk_window_foreign_new(mSDL_XWindowID); - gdk_window_set_transient_for(GTK_WIDGET(win)->window, - gdkwin); - } -# endif //LL_X11 - - GtkColorSelection *colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG(win)->colorsel); - - GdkColor color, orig_color; - orig_color.pixel = 0; - orig_color.red = guint16(65535 * *r); - orig_color.green= guint16(65535 * *g); - orig_color.blue = guint16(65535 * *b); - color = orig_color; - - gtk_color_selection_set_previous_color (colorsel, &color); - gtk_color_selection_set_current_color (colorsel, &color); - gtk_color_selection_set_has_palette (colorsel, true); - gtk_color_selection_set_has_opacity_control(colorsel, false); - - gint response = GTK_RESPONSE_NONE; - g_signal_connect (win, - "response", - G_CALLBACK (response_callback), - &response); - - g_signal_connect (G_OBJECT (colorsel), "color_changed", - G_CALLBACK (color_changed_callback), - &color); - - gtk_window_set_modal(GTK_WINDOW(win), true); - gtk_widget_show_all(win); - // hide the help button - we don't service it. - gtk_widget_hide(GTK_COLOR_SELECTION_DIALOG(win)->help_button); - gtk_main(); - - if (response == GTK_RESPONSE_OK && - (orig_color.red != color.red - || orig_color.green != color.green - || orig_color.blue != color.blue) ) - { - *r = color.red / 65535.0f; - *g = color.green / 65535.0f; - *b = color.blue / 65535.0f; - rtn = true; - } - } - - afterDialog(); - - return rtn; -} -#else -S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type) -{ - LL_INFOS() << "MSGBOX: " << caption << ": " << text << LL_ENDL; - return 0; -} - -bool LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) -{ - return (false); -} -#endif // LL_GTK - -#if LL_LINUX -// extracted from spawnWebBrowser for clarity and to eliminate -// compiler confusion regarding close(int fd) vs. LLWindow::close() -void exec_cmd(const std::string& cmd, const std::string& arg) -{ - char* const argv[] = {(char*)cmd.c_str(), (char*)arg.c_str(), NULL}; - fflush(NULL); - pid_t pid = fork(); - if (pid == 0) - { // child - // disconnect from stdin/stdout/stderr, or child will - // keep our output pipe undesirably alive if it outlives us. - close(0); - close(1); - close(2); - // end ourself by running the command - execv(cmd.c_str(), argv); /* Flawfinder: ignore */ - // if execv returns at all, there was a problem. - LL_WARNS() << "execv failure when trying to start " << cmd << LL_ENDL; - _exit(1); // _exit because we don't want atexit() clean-up! - } else { - if (pid > 0) - { - // parent - wait for child to die - int childExitStatus; - waitpid(pid, &childExitStatus, 0); - } else { - LL_WARNS() << "fork failure." << LL_ENDL; - } - } + return result; } -#endif // Open a URL with the user's default web browser. // Must begin with protocol identifier. @@ -2525,56 +1739,26 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async) LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL; -#if LL_LINUX -# if LL_X11 - if (mSDL_Display) - { - maybe_lock_display(); - // Just in case - before forking. - XSync(mSDL_Display, False); - maybe_unlock_display(); - } -# endif // LL_X11 - - std::string cmd, arg; - cmd = gDirUtilp->getAppRODataDir(); - cmd += gDirUtilp->getDirDelimiter(); - cmd += "etc"; - cmd += gDirUtilp->getDirDelimiter(); - cmd += "launch_url.sh"; - arg = escaped_url; - exec_cmd(cmd, arg); -#endif // LL_LINUX + if (!SDL_OpenURL(escaped_url.c_str())) + { + LL_WARNS() << "spawn_web_browser failed with error: " << SDL_GetError() << LL_ENDL; + } LL_INFOS() << "spawn_web_browser returning." << LL_ENDL; } - -void *LLWindowSDL::getPlatformWindow() +void* LLWindowSDL::getPlatformWindow() { -#if LL_GTK && LL_LLMOZLIB_ENABLED - if (LLWindowSDL::ll_try_gtk_init()) + void* ret = nullptr; + if (mWindow) { - maybe_lock_display(); - - GtkWidget *owin = gtk_window_new(GTK_WINDOW_POPUP); - // Why a layout widget? A MozContainer would be ideal, but - // it involves exposing Mozilla headers to mozlib-using apps. - // A layout widget with a GtkWindow parent has the desired - // properties of being plain GTK, having a window, and being - // derived from a GtkContainer. - GtkWidget *rtnw = gtk_layout_new(NULL, NULL); - gtk_container_add(GTK_CONTAINER(owin), rtnw); - gtk_widget_realize(rtnw); - GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(rtnw), GTK_NO_WINDOW); - - maybe_unlock_display(); - - return rtnw; +#if LL_WINDOWS + ret = SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr); +#elif LL_DARWIN + ret = SDL_GetPointerProperty(SDL_GetWindowProperties(mWindow), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, nullptr); +#endif } -#endif // LL_GTK && LL_LLMOZLIB_ENABLED - // Unixoid mozilla really needs GTK. - return NULL; + return ret; } void LLWindowSDL::bringToFront() @@ -2582,20 +1766,17 @@ void LLWindowSDL::bringToFront() // This is currently used when we are 'launched' to a specific // map position externally. LL_INFOS() << "bringToFront" << LL_ENDL; -#if LL_X11 - if (mSDL_Display && !mFullscreen) + if (mWindow && !mFullscreen) { - maybe_lock_display(); - XRaiseWindow(mSDL_Display, mSDL_XWindowID); - XSync(mSDL_Display, False); - maybe_unlock_display(); + SDL_RaiseWindow(mWindow); } -#endif // LL_X11 } //static std::vector LLWindowSDL::getDynamicFallbackFontList() { + std::vector 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"); @@ -2612,9 +1793,9 @@ std::vector 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 rtns; - FcFontSet *fs = NULL; - FcPattern *sortpat = NULL; + + FcFontSet *fs = nullptr; + FcPattern *sortpat = nullptr; LL_INFOS() << "Getting system font list from FontConfig..." << LL_ENDL; @@ -2623,7 +1804,7 @@ std::vector LLWindowSDL::getDynamicFallbackFontList() // of languages that can be displayed, but ensures that their // preferred language is rendered from a single consistent font where // possible. - FL_Locale *locale = NULL; + FL_Locale *locale = nullptr; FL_Success success = FL_FindLocale(&locale, FL_MESSAGES); if (success != 0) { @@ -2634,10 +1815,10 @@ std::vector LLWindowSDL::getDynamicFallbackFontList() LL_INFOS("AppInit") << "Variant " << locale->variant << LL_ENDL; LL_INFOS() << "Preferring fonts of language: " - << locale->lang - << LL_ENDL; + << locale->lang + << LL_ENDL; sort_order = "lang=" + std::string(locale->lang) + ":" - + sort_order; + + sort_order; } } FL_FreeLocale(&locale); @@ -2654,8 +1835,7 @@ std::vector LLWindowSDL::getDynamicFallbackFontList() { // Sort the list of system fonts from most-to-least-desirable. FcResult result; - fs = FcFontSort(NULL, sortpat, elide_unicode_coverage, - NULL, &result); + fs = FcFontSort(nullptr, sortpat, elide_unicode_coverage, nullptr, &result); FcPatternDestroy(sortpat); } @@ -2668,10 +1848,7 @@ std::vector LLWindowSDL::getDynamicFallbackFontList() for (int i=0; infont; ++i) { FcChar8 *filename; - if (FcResultMatch == FcPatternGetString(fs->fonts[i], - FC_FILE, 0, - &filename) - && filename) + if (FcResultMatch == FcPatternGetString(fs->fonts[i], FC_FILE, 0, &filename) && filename) { rtns.push_back(std::string((const char*)filename)); if (rtns.size() >= max_font_count_cutoff) @@ -2682,16 +1859,101 @@ std::vector LLWindowSDL::getDynamicFallbackFontList() } LL_DEBUGS() << "Using font list: " << LL_ENDL; - for (std::vector::iterator it = rtns.begin(); - it != rtns.end(); - ++it) + for (auto it = rtns.begin(); it != rtns.end(); ++it) { LL_DEBUGS() << " file: " << *it << LL_ENDL; } + LL_INFOS() << "Using " << rtns.size() << "/" << found_font_count << " system fonts." << LL_ENDL; rtns.push_back(final_fallback); +#endif return rtns; } -#endif // LL_SDL +void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position) +{ + LLCoordWindow win_pos; + convertCoords( position, &win_pos ); + + SDL_Rect r; + r.x = win_pos.mX; + r.y = win_pos.mY; + r.w = 500; + r.h = 16; + + SDL_SetTextInputArea(mWindow, &r, 0); +} + +F32 LLWindowSDL::getSystemUISize() +{ + if(mWindow) + { + F32 scale = SDL_GetWindowDisplayScale(mWindow); + if (scale > 0.0f) + { + return scale; + } + } + return 1.f; +} + +#if LL_DARWIN +// static +U64 LLWindowSDL::getVramSize() +{ + CGLRendererInfoObj info = 0; + GLint vram_megabytes = 0; + int num_renderers = 0; + CGLError the_err = CGLQueryRendererInfo (CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &info, &num_renderers); + if(0 == the_err) + { + // The name, uses, and other platform definitions of gGLManager.mVRAM suggest that this is supposed to be total vram in MB, + // rather than, say, just the texture memory. The two exceptions are: + // 1. LLAppViewer::getViewerInfo() puts the value in a field labeled "TEXTURE_MEMORY" + // 2. For years, this present function used kCGLRPTextureMemoryMegabytes + // Now we use kCGLRPVideoMemoryMegabytes to bring it in line with everything else (except thatone label). + CGLDescribeRenderer (info, 0, kCGLRPVideoMemoryMegabytes, &vram_megabytes); + CGLDestroyRendererInfo (info); + } + else + { + vram_megabytes = 256; + } + + return (U64)vram_megabytes; // return value is in megabytes. +} + +//static +void LLWindowSDL::setUseMultGL(bool use_mult_gl) +{ + bool was_enabled = sUseMultGL; + + sUseMultGL = use_mult_gl; + + if (gGLManager.mInited) + { + CGLContextObj ctx = CGLGetCurrentContext(); + //enable multi-threaded OpenGL (whether or not sUseMultGL actually changed) + if (sUseMultGL) + { + CGLError cgl_err = CGLEnable( ctx, kCGLCEMPEngine); + if (cgl_err != kCGLNoError ) + { + LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; + sUseMultGL = false; + } + else + { + LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; + } + } + else if (was_enabled) + { + CGLDisable( ctx, kCGLCEMPEngine); + LL_INFOS("GLInit") << "Multi-threaded OpenGL disabled." << LL_ENDL; + } + } +} +#endif + diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h index 521d52df30..966999ac12 100644 --- a/indra/llwindow/llwindowsdl.h +++ b/indra/llwindow/llwindowsdl.h @@ -32,141 +32,152 @@ #include "llwindow.h" #include "lltimer.h" -#include "SDL/SDL.h" -#include "SDL/SDL_endian.h" - -#if LL_X11 -// get X11-specific headers for use in low-level stuff like copy-and-paste support -#include "SDL/SDL_syswm.h" -#endif - -// AssertMacros.h does bad things. -#include "fix_macros.h" -#undef verify -#undef require +#include "SDL3/SDL.h" +#include "SDL3/SDL_endian.h" +class LLPreeditor; -class LLWindowSDL : public LLWindow +class LLWindowSDL final : public LLWindow { public: - /*virtual*/ void show(); - /*virtual*/ void hide(); - /*virtual*/ void close(); - /*virtual*/ bool getVisible(); - /*virtual*/ bool getMinimized(); - /*virtual*/ bool getMaximized(); - /*virtual*/ bool maximize(); - /*virtual*/ void minimize(); - /*virtual*/ void restore(); - /*virtual*/ bool getFullscreen(); - /*virtual*/ bool getPosition(LLCoordScreen *position); - /*virtual*/ bool getSize(LLCoordScreen *size); - /*virtual*/ bool getSize(LLCoordWindow *size); - /*virtual*/ bool setPosition(LLCoordScreen position); - /*virtual*/ bool setSizeImpl(LLCoordScreen size); - /*virtual*/ bool setSizeImpl(LLCoordWindow size); - /*virtual*/ bool switchContext(bool fullscreen, const LLCoordScreen &size, bool disable_vsync, const LLCoordScreen * const posp = NULL); - /*virtual*/ bool setCursorPosition(LLCoordWindow position); - /*virtual*/ bool getCursorPosition(LLCoordWindow *position); - /*virtual*/ bool isWrapMouse() const override { return true; } - /*virtual*/ void showCursor(); - /*virtual*/ void hideCursor(); - /*virtual*/ void showCursorFromMouseMove(); - /*virtual*/ void hideCursorUntilMouseMove(); - /*virtual*/ bool isCursorHidden(); - /*virtual*/ void updateCursor(); - /*virtual*/ void captureMouse(); - /*virtual*/ void releaseMouse(); - /*virtual*/ void setMouseClipping( bool b ); - /*virtual*/ void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true); - - /*virtual*/ bool isClipboardTextAvailable(); - /*virtual*/ bool pasteTextFromClipboard(LLWString &dst); - /*virtual*/ bool copyTextToClipboard(const LLWString & src); - - /*virtual*/ bool isPrimaryTextAvailable(); - /*virtual*/ bool pasteTextFromPrimary(LLWString &dst); - /*virtual*/ bool copyTextToPrimary(const LLWString & src); - - /*virtual*/ void flashIcon(F32 seconds); - /*virtual*/ F32 getGamma(); - /*virtual*/ bool setGamma(const F32 gamma); // Set the gamma - /*virtual*/ U32 getFSAASamples(); - /*virtual*/ void setFSAASamples(const U32 samples); - /*virtual*/ bool restoreGamma(); // Restore original gamma table (before updating gamma) - /*virtual*/ ESwapMethod getSwapMethod() { return mSwapMethod; } - /*virtual*/ void processMiscNativeEvents(); - /*virtual*/ void gatherInput(); - /*virtual*/ void swapBuffers(); - /*virtual*/ void restoreGLContext() {}; - - /*virtual*/ void delayInputProcessing() { }; + void show() override; + void hide() override; + void restore() override; + + void close() override; + + bool getVisible() override; + + bool getMinimized() override; + + bool getMaximized() override; + + bool maximize() override; + void minimize() override; + + bool getPosition(LLCoordScreen *position) override; + + bool getSize(LLCoordScreen *size) override; + bool getSize(LLCoordWindow *size) override; + + bool setPosition(LLCoordScreen position) override; + + bool setSizeImpl(LLCoordScreen size) override; + bool setSizeImpl(LLCoordWindow size) override; + + bool switchContext(bool fullscreen, const LLCoordScreen &size, bool enable_vsync, + const LLCoordScreen *const posp = NULL) override; + + bool setCursorPosition(LLCoordWindow position) override; + + bool getCursorPosition(LLCoordWindow *position) override; + bool isWrapMouse() const override { return true; } + void showCursor() override; + void hideCursor() override; + bool isCursorHidden() override; + + void showCursorFromMouseMove() override; + void hideCursorUntilMouseMove() override; + + void updateCursor() override; + + void captureMouse() override; + void releaseMouse() override; + + void setMouseClipping(bool b) override; + + void setMinSize(U32 min_width, U32 min_height, bool enforce_immediately = true) override; + + bool isClipboardTextAvailable() override; + bool pasteTextFromClipboard(LLWString &dst) override; + bool copyTextToClipboard(const LLWString &src) override; + + bool isPrimaryTextAvailable() override; + bool pasteTextFromPrimary(LLWString &dst) override; + bool copyTextToPrimary(const LLWString &src) override; + + void flashIcon(F32 seconds) override; + void maybeStopFlashIcon(); + + F32 getGamma() override; + bool setGamma(const F32 gamma) override; // Set the gamma + bool restoreGamma() override; // Restore original gamma table (before updating gamma) + + U32 getFSAASamples() override; + void setFSAASamples(const U32 samples) override; + + void processMiscNativeEvents() override; + + void gatherInput() override; + + SDL_AppResult handleEvent(const SDL_Event& event); + static SDL_AppResult handleEvents(const SDL_Event& event); + + void swapBuffers() override; + + void delayInputProcessing() override {}; // handy coordinate space conversion routines - /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordWindow *to); - /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordScreen *to); - /*virtual*/ bool convertCoords(LLCoordWindow from, LLCoordGL *to); - /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordWindow *to); - /*virtual*/ bool convertCoords(LLCoordScreen from, LLCoordGL *to); - /*virtual*/ bool convertCoords(LLCoordGL from, LLCoordScreen *to); + bool convertCoords(LLCoordScreen from, LLCoordWindow *to) override; + bool convertCoords(LLCoordWindow from, LLCoordScreen *to) override; + bool convertCoords(LLCoordWindow from, LLCoordGL *to) override; + bool convertCoords(LLCoordGL from, LLCoordWindow *to) override; + bool convertCoords(LLCoordScreen from, LLCoordGL *to) override; + bool convertCoords(LLCoordGL from, LLCoordScreen *to) override; - /*virtual*/ LLWindowResolution* getSupportedResolutions(S32 &num_resolutions); - /*virtual*/ F32 getNativeAspectRatio(); - /*virtual*/ F32 getPixelAspectRatio(); - /*virtual*/ void setNativeAspectRatio(F32 ratio) { mOverrideAspectRatio = ratio; } + LLWindowResolution *getSupportedResolutions(S32 &num_resolutions) override; - /*virtual*/ void beforeDialog(); - /*virtual*/ void afterDialog(); + F32 getNativeAspectRatio() override; + F32 getPixelAspectRatio() override; + void setNativeAspectRatio(F32 ratio) override { mOverrideAspectRatio = ratio; } - /*virtual*/ bool dialogColorPicker(F32 *r, F32 *g, F32 *b); + void beforeDialog() override; + void afterDialog() override; - /*virtual*/ void *getPlatformWindow(); - /*virtual*/ void bringToFront(); + bool dialogColorPicker(F32 *r, F32 *g, F32 *b) override; - /*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async); + void *getPlatformWindow() override; + + void bringToFront() override; + + void setLanguageTextInput(const LLCoordGL& pos) override; + + void spawnWebBrowser(const std::string &escaped_url, bool async) override; + + void setTitle(const std::string title) override; static std::vector getDynamicFallbackFontList(); - // Not great that these are public, but they have to be accessible - // by non-class code and it's better than making them global. -#if LL_X11 - Window mSDL_XWindowID; - Display *mSDL_Display; -#endif - void (*Lock_Display)(void); - void (*Unlock_Display)(void); + void *createSharedContext() override; + void makeContextCurrent(void *context) override; + void destroySharedContext(void *context) override; + void toggleVSync(bool enable_vsync) override; -#if LL_GTK - // Lazily initialize and check the runtime GTK version for goodness. - static bool ll_try_gtk_init(void); -#endif // LL_GTK + F32 getSystemUISize() override; -#if LL_X11 - static Window get_SDL_XWindowID(void); - static Display* get_SDL_Display(void); -#endif // LL_X11 + static std::vector getDisplaysResolutionList(); -protected: - LLWindowSDL(LLWindowCallbacks* callbacks, - const std::string& title, int x, int y, int width, int height, U32 flags, - bool fullscreen, bool clearBg, bool disable_vsync, bool use_gl, - bool ignore_pixel_depth, U32 fsaa_samples); - ~LLWindowSDL(); +#if LL_DARWIN + static U64 getVramSize(); + static void setUseMultGL(bool use_mult_gl); + + static bool sUseMultGL; +#endif - /*virtual*/ bool isValid(); - /*virtual*/ LLSD getNativeKeyData(); +protected: + LLWindowSDL(LLWindowCallbacks *callbacks, + const std::string &title, const std::string& name, int x, int y, int width, int height, U32 flags, + bool fullscreen, bool clearBg, bool enable_vsync, bool use_gl, + bool ignore_pixel_depth, U32 fsaa_samples); - void initCursors(); - void quitCursors(); - void moveWindow(const LLCoordScreen& position,const LLCoordScreen& size); + ~LLWindowSDL(); - // Changes display resolution. Returns true if successful - bool setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); + bool isValid() override; - // Go back to last fullscreen display resolution. - bool setFullscreenResolution(); + LLSD getNativeKeyData() override; - bool shouldPostQuit() { return mPostQuit; } + void initCursors(); + void quitCursors(); protected: // @@ -174,57 +185,49 @@ protected: // // create or re-create the GL context/window. Called from the constructor and switchContext(). - bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool disable_vsync); + bool createContext(int x, int y, int width, int height, int bits, bool fullscreen, bool enable_vsync); void destroyContext(); - void setupFailure(const std::string& text, const std::string& caption, U32 type); - void fixWindowSize(void); - U32 SDLCheckGrabbyKeys(SDLKey keysym, bool gain); + + void setupFailure(const std::string &text, const std::string &caption, U32 type); + bool SDLReallyCaptureInput(bool capture); + U32 SDLCheckGrabbyKeys(U32 keysym, bool gain); // // Platform specific variables // - U32 mGrabbyKeyFlags; - int mReallyCapturedCount; - SDL_Surface * mWindow; - std::string mWindowTitle; - double mOriginalAspectRatio; - bool mNeedsResize; // Constructor figured out the window is too big, it needs a resize. - LLCoordScreen mNeedsResizeSize; - F32 mOverrideAspectRatio; - F32 mGamma; - U32 mFSAASamples; - - int mSDLFlags; + U32 mGrabbyKeyFlags = 0; + S32 mReallyCapturedCount = 0; + SDL_Window *mWindow = nullptr; + SDL_GLContext mContext; + SDL_Cursor *mSDLCursors[UI_CURSOR_COUNT]; - SDL_Cursor* mSDLCursors[UI_CURSOR_COUNT]; - int mHaveInputFocus; /* 0=no, 1=yes, else unknown */ - int mIsMinimized; /* 0=no, 1=yes, else unknown */ + std::string mWindowTitle; + F32 mNativeAspectRatio = 0.0f; + F32 mOverrideAspectRatio = 0.0f; + F32 mGamma = 0.0f; + U32 mFSAASamples = 0; friend class LLWindowManager; private: -#if LL_X11 - void x11_set_urgent(bool urgent); - bool mFlashing; + bool mFlashing = false; LLTimer mFlashTimer; -#endif //LL_X11 + U32 mKeyVirtualKey = 0; + U32 mKeyModifiers = SDL_KMOD_NONE; - U32 mKeyScanCode; - U32 mKeyVirtualKey; - SDLMod mKeyModifiers; + void tryFindFullscreenSize(int &aWidth, int &aHeight); }; - class LLSplashScreenSDL : public LLSplashScreen { public: LLSplashScreenSDL(); virtual ~LLSplashScreenSDL(); - /*virtual*/ void showImpl(); - /*virtual*/ void updateImpl(const std::string& mesg); - /*virtual*/ void hideImpl(); + void showImpl() override; + void updateImpl(const std::string& mesg) override; + void hideImpl() override; }; S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 type); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0d2491609b..0ba86307a2 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -288,7 +288,7 @@ extern bool gRandomizeFramerate; extern bool gPeriodicSlowFrame; extern bool gDebugGL; -#if LL_DARWIN +#if LL_DARWIN || LL_SDL_WINDOW extern bool gHiDPISupport; #endif @@ -571,6 +571,9 @@ static void settings_to_globals() #if LL_DARWIN LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL"); +#endif + +#if LL_DARWIN || LL_SDL_WINDOW gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); #endif } @@ -3380,7 +3383,7 @@ LLSD LLAppViewer::getViewerInfo() const info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance"); info["TEXTURE_MEMORY"] = LLSD::Integer(gGLManager.mVRAM); -#if LL_DARWIN +#if LL_DARWIN || LL_SDL_WINDOW info["HIDPI"] = gHiDPISupport; #endif diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 9366c6f46e..4a96c45c69 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -36,8 +36,18 @@ #include "llviewercontrol.h" #include "llmd5.h" #include "llfindlocale.h" +#include "llversioninfo.h" #include + +#define SDL_MAIN_USE_CALLBACKS +#include + +#include "SDL3/SDL.h" + +#include "llsdl.h" +#include "llwindowsdl.h" + #ifdef LL_GLIB #include #endif @@ -86,9 +96,101 @@ namespace { int gArgC = 0; char **gArgV = NULL; + LLAppViewerLinux* gViewerAppPtr = NULL; void (*gOldTerminateHandler)() = NULL; } +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"); + if (fp) + { + static long long last_vm_size = 0; + static long long last_rss_size = 0; + const long long significant_vm_difference = 250 * 1024*1024; + const long long significant_rss_difference = 50 * 1024*1024; + long long this_vm_size = 0; + long long this_rss_size = 0; + + ssize_t res; + size_t dummy; + char *ptr = nullptr; + for (int i=0; i<22; ++i) // parse past the values we don't want + { + res = getdelim(&ptr, &dummy, ' ', fp); + if (-1 == res) + { + LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; + goto finally; + } + free(ptr); + ptr = nullptr; + } + // 23rd space-delimited entry is vsize + res = getdelim(&ptr, &dummy, ' ', fp); + llassert(ptr); + if (-1 == res) + { + LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; + goto finally; + } + this_vm_size = atoll(ptr); + free(ptr); + ptr = nullptr; + // 24th space-delimited entry is RSS + res = getdelim(&ptr, &dummy, ' ', fp); + llassert(ptr); + if (-1 == res) + { + LL_WARNS() << "Unable to parse " << STATS_FILE << LL_ENDL; + goto finally; + } + this_rss_size = getpagesize() * atoll(ptr); + free(ptr); + ptr = nullptr; + + LL_INFOS() << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << LL_ENDL; + + if (llabs(last_vm_size - this_vm_size) > significant_vm_difference) + { + if (this_vm_size > last_vm_size) + { + LL_WARNS() << "VM size grew by " << (this_vm_size - last_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + } + else + { + LL_INFOS() << "VM size shrank by " << (last_vm_size - this_vm_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + } + } + + if (llabs(last_rss_size - this_rss_size) > significant_rss_difference) + { + if (this_rss_size > last_rss_size) + { + LL_WARNS() << "RSS size grew by " << (this_rss_size - last_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + } + else + { + LL_INFOS() << "RSS size shrank by " << (last_rss_size - this_rss_size)/(1024*1024) << " MB in last frame" << LL_ENDL; + } + } + + last_rss_size = this_rss_size; + last_vm_size = this_vm_size; + +finally: + if (ptr) + { + free(ptr); + ptr = nullptr; + } + fclose(fp); + } +#endif // LL_LINUX +} static void exceptionTerminateHandler() { @@ -102,34 +204,85 @@ static void exceptionTerminateHandler() gOldTerminateHandler(); // call old terminate() handler } -int main( int argc, char **argv ) +SDL_AppResult SDL_AppInit(void **appstate, 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"); + gSDLMainHandled = true; + gArgC = argc; gArgV = argv; - LLAppViewer* viewer_app_ptr = new LLAppViewerLinux(); + gViewerAppPtr = new LLAppViewerLinux(); // install unexpected exception handler gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler); unsetenv( "LD_PRELOAD" ); // Get rid of any preloading, we do not want this to happen during startup of plugins. - bool ok = viewer_app_ptr->init(); + // This needs to be set as early as possible + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_NAME_STRING, LLVersionInfo::getInstance()->getChannel().c_str()); + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_VERSION_STRING, LLVersionInfo::getInstance()->getVersion().c_str()); + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_IDENTIFIER_STRING, "com.secondlife.indra.viewer"); + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_CREATOR_STRING, "Linden Research Inc"); + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Copyright (c) Linden Research, Inc. 2025"); + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_URL_STRING, "https://www.secondlife.com"); + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_TYPE_STRING, "game"); + + bool ok = gViewerAppPtr->init(); if(!ok) { LL_WARNS() << "Application init failed." << LL_ENDL; - return -1; + return SDL_APP_FAILURE; } + return SDL_APP_CONTINUE; +} + +SDL_AppResult SDL_AppIterate(void *appstate) +{ // Run the application main loop - while (! viewer_app_ptr->frame()) - {} + if (!gViewerAppPtr->frame()) + { +#if LL_GLIB + // Pump until we've nothing left to do or passed 1/15th of a + // second pumping for this frame. + static LLTimer pump_timer; + pump_timer.reset(); + pump_timer.setTimerExpirySec(1.0f / 15.0f); + do + { + g_main_context_iteration(g_main_context_default(), false); + } while( g_main_context_pending(g_main_context_default()) && !pump_timer.hasExpired()); +#endif + + // hack - doesn't belong here - but this is just for debugging + if (getenv("LL_DEBUG_BLOAT")) + { + check_vm_bloat(); + } + + return SDL_APP_CONTINUE; + } + + if(LLApp::isError()) + { + return SDL_APP_FAILURE; + } + + return SDL_APP_SUCCESS; +} + +SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) +{ + return LLWindowSDL::handleEvents(*event); +} +void SDL_AppQuit(void *appstate, SDL_AppResult result) +{ if (!LLApp::isError()) { // @@ -137,19 +290,11 @@ int main( int argc, char **argv ) // the assumption is that the error handler is responsible for doing // app cleanup if there was a problem. // - viewer_app_ptr->cleanup(); + gViewerAppPtr->cleanup(); } - delete viewer_app_ptr; - viewer_app_ptr = NULL; - return 0; -} - -LLAppViewerLinux::LLAppViewerLinux() -{ -} -LLAppViewerLinux::~LLAppViewerLinux() -{ + delete gViewerAppPtr; + gViewerAppPtr = nullptr; } bool LLAppViewerLinux::init() @@ -333,63 +478,6 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url) void LLAppViewerLinux::initCrashReporting(bool reportFreeze) { - std::string cmd =gDirUtilp->getExecutableDir(); - cmd += gDirUtilp->getDirDelimiter(); -#if LL_LINUX - cmd += "linux-crash-logger.bin"; -#else -# error Unknown platform -#endif - - std::stringstream pid_str; - pid_str << LLApp::getPid(); - std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, ""); - std::string appname = gDirUtilp->getExecutableFilename(); - std::string grid{ LLGridManager::getInstance()->getGridId() }; - std::string title{ LLAppViewer::instance()->getSecondLifeTitle() }; - std::string pidstr{ pid_str.str() }; - // launch the actual crash logger - const char * cmdargv[] = - {cmd.c_str(), - "-user", - grid.c_str(), - "-name", - title.c_str(), - "-pid", - pidstr.c_str(), - "-dumpdir", - logdir.c_str(), - "-procname", - appname.c_str(), - NULL}; - fflush(NULL); - - pid_t pid = fork(); - if (pid == 0) - { // child - execv(cmd.c_str(), (char* const*) cmdargv); /* Flawfinder: ignore */ - LL_WARNS() << "execv failure when trying to start " << cmd << LL_ENDL; - _exit(1); // avoid atexit() - } - else - { - if (pid > 0) - { - // DO NOT wait for child proc to die; we want - // the logger to outlive us while we quit to - // free up the screen/keyboard/etc. - ////int childExitStatus; - ////waitpid(pid, &childExitStatus, 0); - } - else - { - LL_WARNS() << "fork failure." << LL_ENDL; - } - } - // Sometimes signals don't seem to quit the viewer. Also, we may - // have been called explicitly instead of from a signal handler. - // Make sure we exit so as to not totally confuse the user. - //_exit(1); // avoid atexit(), else we may re-crash in dtors. } bool LLAppViewerLinux::beingDebugged() @@ -420,7 +508,7 @@ bool LLAppViewerLinux::beingDebugged() base += 1; } - if (strcmp(base, "gdb") == 0) + if (strcmp(base, "gdb") == 0 || strcmp(base, "lldb") == 0) { debugged = yes; } @@ -432,18 +520,6 @@ bool LLAppViewerLinux::beingDebugged() return debugged == yes; } -void LLAppViewerLinux::initLoggingAndGetLastDuration() -{ - // Remove the last stack trace, if any - // This file is no longer created, since the move to Google Breakpad - // The code is left here to clean out any old state in the log dir - std::string old_stack_file = - gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); - LLFile::remove(old_stack_file); - - LLAppViewer::initLoggingAndGetLastDuration(); -} - bool LLAppViewerLinux::initParseCommandLine(LLCommandLineParser& clp) { if (!clp.parseCommandLine(gArgC, gArgV)) diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index 460ca721f1..8154d38921 100644 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -33,30 +33,29 @@ class LLCommandLineParser; -class LLAppViewerLinux : public LLAppViewer +class LLAppViewerLinux final : public LLAppViewer { public: - LLAppViewerLinux(); - virtual ~LLAppViewerLinux(); + LLAppViewerLinux() = default; + ~LLAppViewerLinux() override = default; // // Main application logic // - virtual bool init(); // Override to do application initialization + bool init() override; // Override to do application initialization std::string generateSerialNumber(); bool setupSLURLHandler(); protected: - virtual bool beingDebugged(); + bool beingDebugged() override; - virtual bool restoreErrorTrap(); - virtual void initCrashReporting(bool reportFreeze); + bool restoreErrorTrap() override; + void initCrashReporting(bool reportFreeze); - virtual void initLoggingAndGetLastDuration(); - virtual bool initParseCommandLine(LLCommandLineParser& clp); + bool initParseCommandLine(LLCommandLineParser& clp) override; - virtual bool initSLURLHandler(); - virtual bool sendURLToOtherInstance(const std::string& url); + bool initSLURLHandler() override; + bool sendURLToOtherInstance(const std::string& url) override; }; #endif // LL_LLAPPVIEWERLINUX_H diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index e967ff3df2..2dba778e24 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -37,6 +37,10 @@ #include "llviewercontrol.h" #include "llwin32headers.h" +#if LL_SDL_WINDOW +#include "SDL3/SDL.h" +#endif + #if LL_LINUX || LL_DARWIN # include "llfilepicker.h" #endif @@ -65,7 +69,103 @@ bool LLDirPicker::check_local_file_access_enabled() return true; } -#if LL_WINDOWS +#if LL_SDL_WINDOW + +LLDirPicker::LLDirPicker() : + mFileName(NULL), + mLocked(false) +{ + reset(); +} + +LLDirPicker::~LLDirPicker() +{ +} + +void LLDirPicker::reset() +{ +} + +bool LLDirPicker::getDir(std::string* filename, bool blocking) +{ + return false; +} + +std::string LLDirPicker::getDirName() +{ + return {}; +} + +bool LLDirPicker::getDirModeless(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()) + { + return false; + } + + { + struct LLSDLFileUserdata + { + LLSDLFileUserdata(void (*callback_func)(bool, std::string&, void*), void* callback_userdata) + : mCallback(callback_func), mUserdata(callback_userdata) + { + } + void (*mCallback)(bool, std::string&, void*); + void* mUserdata; + }; + + auto sdl_callback = [](void* userdata, const char* const* filelist, int filter) + { + LLSDLFileUserdata* callback_struct = (LLSDLFileUserdata*)userdata; + + auto* callback_func = callback_struct->mCallback; + auto* callback_data = callback_struct->mUserdata; + delete callback_struct; // delete callback container + + std::string rtn; + if (!filelist) + { + LL_WARNS() << "Error during SDL folder picking: " << SDL_GetError() << LL_ENDL; + callback_func(false, rtn, callback_data); + return; + } + else if (!*filelist) + { + LL_INFOS() << "User did not select any folders. Dialog likely cancelled." << LL_ENDL; + callback_func(false, rtn, callback_data); + return; + } + + while (*filelist) { + rtn = std::string(*filelist); + break; + } + callback_func(true, rtn, callback_data); + + }; + + LLSDLFileUserdata* llfilecallback = new LLSDLFileUserdata(callback, userdata); + + SDL_PropertiesID props = SDL_CreateProperties(); + SDL_SetPointerProperty(props, SDL_PROP_FILE_DIALOG_WINDOW_POINTER, SDL_GL_GetCurrentWindow()); + SDL_ShowFileDialogWithProperties(SDL_FILEDIALOG_OPENFOLDER, sdl_callback, llfilecallback, props); + + SDL_DestroyProperties(props); + } + + return true; +} + + +#elif LL_WINDOWS LLDirPicker::LLDirPicker() : mFileName(NULL), @@ -167,6 +267,13 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking) return success; } +bool LLDirPicker::getDirModeless(std::string* filename, + void (*callback)(bool, std::string&, void*), + void* userdata) +{ + return false; +} + std::string LLDirPicker::getDirName() { return mDir; @@ -195,7 +302,6 @@ void LLDirPicker::reset() } -//static bool LLDirPicker::getDir(std::string* filename, bool blocking) { LLFilePicker::ELoadFilter filter=LLFilePicker::FFLOAD_DIRECTORY; @@ -203,6 +309,13 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking) return mFilePicker->getOpenFile(filter, true); } +bool LLDirPicker::getDirModeless(std::string* filename, + void (*callback)(bool, std::string&, void*), + void* userdata) +{ + return false; +} + std::string LLDirPicker::getDirName() { return mFilePicker->getFirstFile(); @@ -240,23 +353,13 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking) return false; } -#if !LL_MESA_HEADLESS - - if (mFilePicker) - { - GtkWindow* picker = mFilePicker->buildFilePicker(false, true, - "dirpicker"); - - if (picker) - { - gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("choose_the_directory").c_str()); - gtk_widget_show_all(GTK_WIDGET(picker)); - gtk_main(); - return (!mFilePicker->getFirstFile().empty()); - } - } -#endif // !LL_MESA_HEADLESS + return false; +} +bool LLDirPicker::getDirModeless(std::string* filename, + void (*callback)(bool, std::string&, void*), + void* userdata) +{ return false; } @@ -290,6 +393,13 @@ bool LLDirPicker::getDir(std::string* filename, bool blocking) return false; } +bool LLDirPicker::getDirModeless(std::string* filename, + void (*callback)(bool, std::string&, void*), + void* userdata) +{ + return false; +} + std::string LLDirPicker::getDirName() { return ""; @@ -303,7 +413,9 @@ std::queue LLDirPickerThread::sDeadQ; void LLDirPickerThread::getFile() { -#if LL_WINDOWS +#if LL_SDL_WINDOW + runModeless(); +#elif LL_WINDOWS start(); #else run(); @@ -333,6 +445,32 @@ void LLDirPickerThread::run() } +void LLDirPickerThread::runModeless() +{ + LLDirPicker picker; + bool result = picker.getDirModeless(&mProposedName, modelessStringCallback, this); + if (!result) + { + LLMutexLock lock(sMutex); + sDeadQ.push(this); + } +} + +void LLDirPickerThread::modelessStringCallback(bool success, + std::string& response, + void* user_data) +{ + LLDirPickerThread* picker = (LLDirPickerThread*)user_data; + { + LLMutexLock lock(sMutex); + if (success) + { + picker->mResponses.push_back(response); + } + sDeadQ.push(picker); + } +} + //static void LLDirPickerThread::initClass() { diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index dc740caab2..c3619f91f5 100644 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -58,6 +58,9 @@ class LLDirPicker { public: bool getDir(std::string* filename, bool blocking = true); + bool getDirModeless(std::string* filename, + void (*callback)(bool, std::string&, void*), + void* userdata); std::string getDirName(); // clear any lists of buffers or whatever, and make sure the dir @@ -116,6 +119,11 @@ public: virtual void run(); + void runModeless(); + static void modelessStringCallback(bool success, + std::string& response, + void* user_data); + virtual void notify(const std::vector& filenames); private: diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp index a8a1e507a8..85c027c84e 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp @@ -81,7 +81,7 @@ bool LLFloaterPreferenceGraphicsAdvanced::postBuild() } } -#if !LL_DARWIN +#if !LL_DARWIN && !LL_SDL_WINDOW LLCheckBoxCtrl *use_HiDPI = getChild("use HiDPI"); use_HiDPI->setVisible(false); #endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 72671c52ad..7dfc5150c4 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5646,11 +5646,6 @@ void* LLViewerWindow::getPlatformWindow() const return mWindow->getPlatformWindow(); } -void* LLViewerWindow::getMediaWindow() const -{ - return mWindow->getMediaWindow(); -} - void LLViewerWindow::focusClient() const { return mWindow->focusClient(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 61aa84394c..00413ce141 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -270,7 +270,6 @@ public: LLWindow* getWindow() const { return mWindow; } void* getPlatformWindow() const; - void* getMediaWindow() const; void focusClient() const; LLCoordGL getLastMouse() const { return mLastMousePoint; } diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 6f13466d75..2b30920265 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1116,6 +1116,9 @@ class LinuxManifest(ViewerManifest): super(LinuxManifest, self).construct() pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') + if "package_dir" in self.args: + pkgdir = self.args['package_dir'] + relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") @@ -1240,7 +1243,7 @@ class LinuxManifest(ViewerManifest): def strip_binaries(self): if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): - print("* Going strip-crazy on the packaged binaries, since this is a RELEASE build") + print("* Going strip-crazy on the packaged binaries, since this is a Release build") # makes some small assumptions about our packaged dir structure self.run_command( ["find"] + @@ -1255,58 +1258,27 @@ class LinuxManifest(ViewerManifest): '!', '-name', '*.json', '!', '-name', 'update_install', '-exec', 'strip', '-S', '{}', ';']) -class Linux_i686_Manifest(LinuxManifest): - address_size = 32 +class Linux_x86_64_Manifest(LinuxManifest): + address_size = 64 def construct(self): - super(Linux_i686_Manifest, self).construct() + super(Linux_x86_64_Manifest, self).construct() pkgdir = os.path.join(self.args['build'], os.pardir, 'packages') + if "package_dir" in self.args: + pkgdir = self.args['package_dir'] + relpkgdir = os.path.join(pkgdir, "lib", "release") - debpkgdir = os.path.join(pkgdir, "lib", "debug") + #debpkgdir = os.path.join(pkgdir, "lib", "debug") with self.prefix(src=relpkgdir, dst="lib"): - self.path("libdb*.so") - self.path("libuuid.so*") - self.path("libSDL-1.2.so.*") - self.path("libdirectfb-1.*.so.*") - self.path("libfusion-1.*.so.*") - self.path("libdirect-1.*.so.*") - self.path("libopenjp2.so*") - self.path("libdirectfb-1.4.so.5") - self.path("libfusion-1.4.so.5") - self.path("libdirect-1.4.so.5*") + self.path("libSDL*.so.*") + self.path("libalut.so*") self.path("libopenal.so*") - self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname - # KLUDGE: As of 2012-04-11, the 'fontconfig' package installs - # libfontconfig.so.1.4.4, along with symlinks libfontconfig.so.1 - # and libfontconfig.so. Before we added support for library-file - # wildcards, though, this self.path() call specifically named - # libfontconfig.so.1.4.4 WITHOUT also copying the symlinks. When I - # (nat) changed the call to self.path("libfontconfig.so.*"), we - # ended up with the libfontconfig.so.1 symlink in the target - # directory as well. But guess what! At least on Ubuntu 10.04, - # certain viewer fonts look terrible with libfontconfig.so.1 - # present in the target directory. Removing that symlink suffices - # to improve them. I suspect that means we actually do better when - # the viewer fails to find our packaged libfontconfig.so*, falling - # back on the system one instead -- but diagnosing and fixing that - # is a bit out of scope for the present project. Meanwhile, this - # particular wildcard specification gets us exactly what the - # previous call did, without having to explicitly state the - # version number. - self.path("libfontconfig.so.*.*") - - # Include libfreetype.so. but have it work as libfontconfig does. - self.path("libfreetype.so.*.*") - try: - self.path("libtcmalloc.so*") #formerly called google perf tools - pass - except: - print("tcmalloc files not found, skipping") - pass + if self.args['discord'] == 'ON': + self.path("libdiscord_partner_sdk.so*") # Vivox runtimes with self.prefix(src=relpkgdir, dst="bin"): @@ -1318,17 +1290,6 @@ class Linux_i686_Manifest(LinuxManifest): self.path("libvivoxsdk.so") self.strip_binaries() - - -class Linux_x86_64_Manifest(LinuxManifest): - address_size = 64 - - def construct(self): - super(Linux_x86_64_Manifest, self).construct() - - # support file for valgrind debug tool - self.path("secondlife-i686.supp") - ################################################################ if __name__ == "__main__": -- cgit v1.3 From e6abebb6aef6bddee45be22e368e9fd8a6b4ec68 Mon Sep 17 00:00:00 2001 From: Rye Date: Tue, 14 Oct 2025 07:43:04 -0400 Subject: Fix up linux feature table and various small build changes Signed-off-by: Rye --- indra/llcommon/llpreprocessor.h | 12 +- indra/newview/featuretable_linux.txt | 648 +++++++++-------------------------- indra/newview/linux_tools/wrapper.sh | 83 +---- indra/newview/llappviewer.cpp | 18 +- indra/newview/viewer_manifest.py | 29 +- 5 files changed, 216 insertions(+), 574 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index b2a9734548..5269fb2282 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -63,7 +63,17 @@ // Figure out differences between compilers -#if defined(__GNUC__) +#if defined(__clang__) + #define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + #ifndef LL_CLANG + #define LL_CLANG 1 + #endif + #ifndef LL_GNUC + #define LL_GNUC 1 + #endif +#elif defined(__GNUC__) #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index d8d4f08429..c53e828020 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,10 +1,10 @@ -version 30 +version 33 // 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 // @@ -28,27 +28,27 @@ version 30 // list all RenderAnisotropic 1 1 -RenderAvatarCloth 1 1 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 350000 RenderAutoMuteSurfaceAreaLimit 1 1000.0 RenderCubeMap 1 1 -RenderDelayVBUpdate 1 0 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderFogRatio 1 4.0 RenderGamma 1 0 RenderGlowResolutionPow 1 9 -RenderGround 1 1 RenderMaxPartCount 1 8192 RenderObjectBump 1 1 -RenderLocalLights 1 1 -RenderReflectionDetail 1 4 +RenderLocalLightCount 1 4096 +RenderTransparentWater 1 1 +RenderReflectionsEnabled 1 1 +RenderReflectionProbeDetail 1 2 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 -RenderTransparentWater 1 1 +RenderTerrainPBRDetail 1 0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTreeLODFactor 1 1.0 RenderVBOEnable 1 1 RenderVBOMappingDisable 1 1 @@ -61,58 +61,38 @@ Disregard128DefaultDrawDistance 1 1 Disregard96DefaultDrawDistance 1 1 RenderCompressTextures 1 1 RenderShaderLightingMaxLevel 1 3 +RenderReflectionProbeLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 -RenderUseAdvancedAtmospherics 1 0 RenderShadowDetail 1 2 -RenderFSAASamples 1 16 +RenderUseStreamVBO 1 1 +RenderFSAAType 1 2 +RenderFSAASamples 1 3 RenderMaxTextureIndex 1 16 +RenderGLContextCoreProfile 1 1 +RenderGLMultiThreadedTextures 1 0 +RenderGLMultiThreadedMedia 1 0 +RenderReflectionProbeResolution 1 128 +RenderScreenSpaceReflections 1 1 RenderMirrors 1 1 - -// -// Low Graphics Settings (fixed function) -// -list LowFixedFunction -RenderAnisotropic 1 0 -RenderAvatarCloth 1 0 -RenderAvatarLODFactor 1 0 -RenderAvatarPhysicsLODFactor 1 0 -RenderAvatarMaxNonImpostors 1 3 -RenderAvatarMaxComplexity 1 25000 -RenderFarClip 1 64 -RenderFlexTimeFactor 1 0 -RenderGlowResolutionPow 1 8 -RenderLocalLights 1 0 -RenderMaxPartCount 1 0 -RenderObjectBump 1 0 -RenderReflectionDetail 1 0 -RenderTerrainDetail 1 0 -RenderTerrainLODFactor 1 1 -RenderTransparentWater 1 0 -RenderTreeLODFactor 1 0 -RenderVolumeLODFactor 1 1.125 -WindLightUseAtmosShaders 1 0 -RenderDeferred 1 0 -RenderDeferredSSAO 1 0 -RenderUseAdvancedAtmospherics 1 0 -RenderShadowDetail 1 0 -WLSkyDetail 1 48 -RenderFSAASamples 1 0 -RenderMirrors 1 0 -RenderHeroProbeResolution 1 256 -RenderHeroProbeDistance 1 4 -RenderHeroProbeUpdateRate 1 6 +RenderHeroProbeResolution 1 2048 +RenderHeroProbeDistance 1 16 +RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderDownScaleMethod 1 0 +RenderCASSharpness 1 1 RenderExposure 1 4 RenderTonemapType 1 1 RenderTonemapMix 1 1 +RenderDisableVintageMode 1 1 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Low Graphics Settings // list Low RenderAnisotropic 1 0 -RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 @@ -120,297 +100,298 @@ RenderAvatarMaxComplexity 1 35000 RenderFarClip 1 64 RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 -RenderLocalLights 1 0 +RenderLocalLightCount 1 8 RenderMaxPartCount 1 0 -RenderObjectBump 1 0 -RenderReflectionDetail 1 0 +RenderTransparentWater 1 0 +RenderReflectionsEnabled 1 0 +RenderReflectionProbeDetail 1 0 RenderTerrainDetail 1 0 RenderTerrainLODFactor 1 1 -RenderTransparentWater 1 0 +RenderTerrainPBRDetail 1 -4 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0 RenderVolumeLODFactor 1 1.125 -WindLightUseAtmosShaders 1 0 -RenderDeferred 1 0 RenderDeferredSSAO 1 0 -RenderUseAdvancedAtmospherics 1 0 RenderShadowDetail 1 0 -WLSkyDetail 1 48 +WLSkyDetail 1 96 +RenderFSAAType 1 0 RenderFSAASamples 1 0 +RenderScreenSpaceReflections 1 0 +RenderReflectionProbeLevel 1 0 RenderMirrors 1 0 RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 4 -RenderHeroProbeUpdateRate 1 6 +RenderHeroProbeUpdateRate 1 6 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 512 +RenderReflectionProbeCount 1 1 // // Medium Low Graphics Settings // list LowMid RenderAnisotropic 1 0 -RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 +RenderAvatarMaxNonImpostors 1 5 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 RenderMaxPartCount 1 2048 -RenderObjectBump 1 1 -RenderLocalLights 1 1 -RenderReflectionDetail 1 0 +RenderLocalLightCount 1 256 +RenderTransparentWater 1 0 +RenderReflectionsEnabled 1 1 +RenderReflectionProbeDetail 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 1.0 -RenderTransparentWater 1 1 +RenderTerrainPBRDetail 1 -1 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 RenderVolumeLODFactor 1 1.125 -WindLightUseAtmosShaders 1 0 -RenderDeferred 1 0 RenderDeferredSSAO 1 0 -RenderUseAdvancedAtmospherics 1 0 RenderShadowDetail 1 0 -WLSkyDetail 1 48 +WLSkyDetail 1 96 +RenderFSAAType 1 0 RenderFSAASamples 1 0 +RenderScreenSpaceReflections 1 0 +RenderReflectionProbeLevel 1 0 RenderMirrors 1 0 RenderHeroProbeResolution 1 256 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 1024 +RenderReflectionProbeCount 1 32 // // Medium Graphics Settings (standard) // list Mid RenderAnisotropic 1 1 -RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarMaxNonImpostors 1 7 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 RenderMaxPartCount 1 4096 -RenderObjectBump 1 1 -RenderLocalLights 1 1 -RenderReflectionDetail 1 0 +RenderLocalLightCount 1 512 +RenderTransparentWater 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 -RenderTransparentWater 1 1 +RenderTerrainPBRDetail 1 0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 -RenderVolumeLODFactor 1 1.125 -WindLightUseAtmosShaders 1 1 -RenderDeferred 1 0 +RenderVolumeLODFactor 1 1.25 RenderDeferredSSAO 1 0 -RenderUseAdvancedAtmospherics 1 0 RenderShadowDetail 1 0 -WLSkyDetail 1 48 -RenderFSAASamples 1 2 +WLSkyDetail 1 96 +RenderFSAAType 1 1 +RenderFSAASamples 1 1 +RenderReflectionsEnabled 1 1 +RenderReflectionProbeDetail 1 0 +RenderScreenSpaceReflections 1 0 +RenderReflectionProbeLevel 1 1 RenderMirrors 1 0 RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 3 RenderHeroProbeConservativeUpdateMultiplier 1 16 +RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 64 // -// Medium High Graphics Settings (deferred enabled) +// Medium High Graphics Settings // list MidHigh RenderAnisotropic 1 1 -RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarMaxNonImpostors 1 9 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 RenderMaxPartCount 1 4096 -RenderObjectBump 1 1 -RenderLocalLights 1 1 -RenderReflectionDetail 1 0 +RenderLocalLightCount 1 1024 +RenderTransparentWater 1 0 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 -RenderTransparentWater 1 1 +RenderTerrainPBRDetail 1 0 +RenderTerrainPBRPlanarSampleCount 1 1 RenderTreeLODFactor 1 0.5 -RenderVolumeLODFactor 1 1.125 -WindLightUseAtmosShaders 1 1 -RenderDeferred 1 1 -RenderUseAdvancedAtmospherics 1 0 +RenderVolumeLODFactor 1 1.375 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 -WLSkyDetail 1 48 -RenderFSAASamples 1 2 +WLSkyDetail 1 96 +RenderFSAAType 1 1 +RenderFSAASamples 1 1 +RenderReflectionsEnabled 1 1 +RenderReflectionProbeDetail 1 1 +RenderScreenSpaceReflections 1 0 +RenderReflectionProbeLevel 1 1 RenderMirrors 1 0 RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 6 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 64 // -// High Graphics Settings (deferred + SSAO) +// High Graphics Settings (SSAO + sun shadows) // list High RenderAnisotropic 1 1 -RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarMaxNonImpostors 1 11 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 RenderMaxPartCount 1 4096 -RenderObjectBump 1 1 -RenderLocalLights 1 1 -RenderReflectionDetail 1 0 +RenderLocalLightCount 1 2048 +RenderTransparentWater 1 1 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 -RenderTransparentWater 1 1 +RenderTerrainPBRDetail 1 0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTreeLODFactor 1 0.5 -RenderVolumeLODFactor 1 1.125 -WindLightUseAtmosShaders 1 1 -RenderDeferred 1 1 +RenderVolumeLODFactor 1 1.5 RenderDeferredSSAO 1 1 -RenderUseAdvancedAtmospherics 1 0 -RenderShadowDetail 1 0 -WLSkyDetail 1 48 +RenderShadowDetail 1 1 +WLSkyDetail 1 96 +RenderFSAAType 1 2 RenderFSAASamples 1 2 +RenderReflectionsEnabled 1 1 +RenderReflectionProbeDetail 1 1 +RenderScreenSpaceReflections 1 0 +RenderReflectionProbeLevel 1 2 RenderMirrors 1 0 RenderHeroProbeResolution 1 512 RenderHeroProbeDistance 1 8 RenderHeroProbeUpdateRate 1 2 RenderHeroProbeConservativeUpdateMultiplier 1 8 +RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 128 // -// High Ultra Graphics Settings (deferred + SSAO + shadows) +// High Ultra Graphics Settings (deferred + SSAO + all shadows) // list HighUltra RenderAnisotropic 1 1 -RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 350000 RenderAvatarPhysicsLODFactor 1 1.0 +RenderAvatarMaxNonImpostors 1 16 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 RenderMaxPartCount 1 4096 -RenderObjectBump 1 1 -RenderLocalLights 1 1 -RenderReflectionDetail 1 0 +RenderLocalLightCount 1 4096 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 0.5 -RenderVolumeLODFactor 1 1.125 -WindLightUseAtmosShaders 1 1 -RenderDeferred 1 1 +RenderVolumeLODFactor 1 1.75 RenderDeferredSSAO 1 1 -RenderUseAdvancedAtmospherics 1 0 RenderShadowDetail 1 2 -WLSkyDetail 1 48 +WLSkyDetail 1 96 +RenderFSAAType 1 2 RenderFSAASamples 1 2 +RenderReflectionsEnabled 1 1 +RenderReflectionProbeDetail 1 1 +RenderScreenSpaceReflections 1 0 +RenderReflectionProbeLevel 1 3 RenderMirrors 1 0 -RenderHeroProbeResolution 1 512 +RenderHeroProbeResolution 1 1024 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Ultra graphics (REALLY PURTY!) // list Ultra RenderAnisotropic 1 1 -RenderAvatarCloth 1 1 RenderAvatarLODFactor 1 1.0 +RenderAvatarMaxNonImpostors 1 16 RenderAvatarPhysicsLODFactor 1 1.0 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 -RenderLocalLights 1 1 +RenderLocalLightCount 1 8192 RenderMaxPartCount 1 8192 -RenderObjectBump 1 1 -RenderReflectionDetail 1 4 RenderTerrainDetail 1 1 RenderTerrainLODFactor 1 2.0 +RenderTerrainPBRDetail 1 0 +RenderTerrainPBRPlanarSampleCount 1 3 RenderTransparentWater 1 1 RenderTreeLODFactor 1 1.0 RenderVolumeLODFactor 1 2.0 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 -RenderDeferred 1 1 RenderDeferredSSAO 1 1 -RenderUseAdvancedAtmospherics 1 0 RenderShadowDetail 1 2 -RenderFSAASamples 1 2 +RenderFSAAType 1 2 +RenderFSAASamples 1 3 +RenderReflectionsEnabled 1 1 +RenderReflectionProbeDetail 1 1 +RenderScreenSpaceReflections 1 0 +RenderReflectionProbeLevel 1 3 RenderMirrors 1 0 -RenderHeroProbeResolution 1 1024 +RenderHeroProbeResolution 1 2048 RenderHeroProbeDistance 1 16 RenderHeroProbeUpdateRate 1 1 RenderHeroProbeConservativeUpdateMultiplier 1 4 +RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 1 256 // // Class Unknown Hardware (unknown) // list Unknown -RenderVBOEnable 1 0 RenderShadowDetail 1 0 -RenderDeferred 1 0 RenderDeferredSSAO 1 0 -RenderUseAdvancedAtmospherics 1 0 - -// -// Class 0 Hardware (just old) -// -list Class0 -RenderVBOEnable 1 1 - -// -// Class 1 Hardware -// -list Class1 -RenderVBOEnable 1 1 - -// -// Class 2 Hardware -// -list Class2 -RenderVBOEnable 1 1 - -// -// Class 3 Hardware -// -list Class3 -RenderVBOEnable 1 1 - -// -// Class 4 Hardware -// -list Class4 -RenderVBOEnable 1 1 - -// -// Class 5 Hardware -// -list Class5 -RenderVBOEnable 1 1 +RenderMirrors 1 0 +RenderDisableVintageMode 1 0 // // VRAM > 512MB @@ -418,340 +399,53 @@ RenderVBOEnable 1 1 list VRAMGT512 RenderCompressTextures 1 0 -// -// No Pixel Shaders available -// -list NoPixelShaders -RenderAvatarCloth 0 0 -RenderReflectionDetail 0 0 -WindLightUseAtmosShaders 0 0 -RenderDeferred 0 0 -RenderDeferredSSAO 0 0 -RenderUseAdvancedAtmospherics 0 0 -RenderShadowDetail 0 0 - -// -// No Vertex Shaders available -// -list NoVertexShaders -RenderAvatarCloth 0 0 -RenderReflectionDetail 0 0 -WindLightUseAtmosShaders 0 0 -RenderDeferred 0 0 -RenderDeferredSSAO 0 0 -RenderUseAdvancedAtmospherics 0 0 -RenderShadowDetail 0 0 - -// -// GL_ARB_map_buffer_range exists -// -list MapBufferRange -RenderVBOMappingDisable 1 1 - - // // "Default" setups for safe, low, medium, high // list safe RenderAnisotropic 1 0 -RenderAvatarCloth 0 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 -RenderObjectBump 0 0 -RenderLocalLights 1 0 +RenderLocalLightCount 1 0 RenderMaxPartCount 1 1024 RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 -RenderReflectionDetail 0 0 -WindLightUseAtmosShaders 0 0 -RenderDeferred 0 0 +RenderTransparentWater 1 0 RenderDeferredSSAO 0 0 -RenderUseAdvancedAtmospherics 0 0 RenderShadowDetail 0 0 - -// -// CPU based feature masks -// - -// 1Ghz or less (equiv) -list CPUSlow -RenderMaxPartCount 1 1024 - -// -// RAM based feature masks -// -list RAM256MB -RenderObjectBump 0 0 - -// -// Graphics card based feature masks -// -list OpenGLPre15 -RenderVBOEnable 1 0 - -list OpenGLPre30 -RenderDeferred 0 0 -RenderMaxTextureIndex 1 1 +RenderReflectionProbeDetail 0 -1 +RenderMirrors 0 0 +RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 2048 +RenderReflectionProbeCount 0 0 list Intel RenderAnisotropic 1 0 -// Avoid some Intel crashes on Linux -RenderCubeMap 0 0 +RenderFSAAType 1 0 RenderFSAASamples 1 0 - -list GeForce2 -RenderAnisotropic 1 0 -RenderMaxPartCount 1 2048 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 1 - -list SiS -UseOcclusion 0 0 - - -list Intel_830M -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_845G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_855GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_865G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_900 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_915GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_915G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_945GM -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_945G -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_950 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_965 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 -UseOcclusion 0 0 - -list Intel_G33 -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Bear_Lake -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Broadwater -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Brookdale -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Montara -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - -list Intel_Springdale -RenderTerrainDetail 1 0 -RenderVBOEnable 1 0 - - -list ATI_FireGL_5200 -RenderVBOEnable 1 0 -WindLightUseAtmosShaders 0 0 - - -list ATI_Mobility_Radeon_7xxx -RenderVBOEnable 0 0 - -list ATI_Radeon_7xxx -RenderVBOEnable 0 0 - -list ATI_All-in-Wonder_Radeon -RenderVBOEnable 0 0 - -list ATI_All-in-Wonder_7500 -RenderVBOEnable 0 0 - -list ATI_Mobility_Radeon_9600 -Disregard96DefaultDrawDistance 1 0 - - -/// tweaked ATI to 96 Draw distance - -list ATI_Radeon_9000 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9200 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9500 -Disregard96DefaultDrawDistance 1 0 -list ATI_Radeon_9600 -Disregard96DefaultDrawDistance 1 0 - -/// tweaked ATI to 128 draw distance - -list ATI_Radeon_X300 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X400 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X500 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X600 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X700 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X1300 -Disregard128DefaultDrawDistance 1 0 -UseStartScreen 0 0 -list ATI_Radeon_X1400 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X1500 -Disregard128DefaultDrawDistance 1 0 -UseStartScreen 0 0 -list ATI_Radeon_X1600 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_X1700 -Disregard128DefaultDrawDistance 1 0 -list ATI_Mobility_Radeon_X1xxx -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_HD_2300 -Disregard128DefaultDrawDistance 1 0 -list ATI_Radeon_HD_2400 -Disregard128DefaultDrawDistance 1 0 -list ATI_ASUS_AH24xx -Disregard128DefaultDrawDistance 1 0 - - -// Avatar hardware skinning causes invisible avatars -// on various ATI chipsets on drivers before 8.2 - -list ATIOldDriver -RenderAvatarCloth 0 0 -// Avoid driver crashes with some features on Linux with old ATI drivers -UseOcclusion 0 0 -WindLightUseAtmosShaders 0 0 - - -/// Tweaked NVIDIA - -list NVIDIA_GeForce_FX_5100 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_5200 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_5500 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_5600 -Disregard96DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_FX_Go5100 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5200 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5300 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5500 -Disregard96DefaultDrawDistance 1 0 -list NVIDIA_GeForce_FX_Go5600 -Disregard96DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_6100 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6200 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6500 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_6600 -Disregard128DefaultDrawDistance 1 0 - -list NVIDIA_G73 -Disregard128DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_Go_6100 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6200 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6500 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6600 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6700 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6800 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 -list NVIDIA_GeForce_Go_6 -RenderVBOEnable 1 0 -Disregard128DefaultDrawDistance 1 0 - -list NVIDIA_GeForce_7000 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7100 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7200 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7300 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7400 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7500 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7600 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7700 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7800 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_7900 -RenderShaderLightingMaxLevel 1 2 - -list NVIDIA_GeForce_Go_7200 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7300 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7300_LE -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7400 -Disregard128DefaultDrawDistance 1 0 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7600 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7700 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7800 -RenderShaderLightingMaxLevel 1 2 -list NVIDIA_GeForce_Go_7900 -RenderShaderLightingMaxLevel 1 2 +RenderGLContextCoreProfile 1 0 +RenderGLMultiThreadedMedia 1 0 +RenderDownScaleMethod 1 0 + +list AMD +RenderGLMultiThreadedTextures 1 0 + +list NVIDIA +RenderGLMultiThreadedMedia 1 1 + +list GL3 +RenderFSAAType 0 0 +RenderFSAASamples 0 0 +RenderReflectionsEnabled 0 0 +RenderReflectionProbeDetail 0 0 +RenderMirrors 0 0 +RenderGLMultiThreadedTextures 0 0 +RenderGLMultiThreadedMedia 0 0 +RenderDisableVintageMode 1 0 +RenderReflectionProbeCount 0 0 + +list TexUnit16orLess +RenderTerrainPBRDetail 1 -1 + +list VaryingVectors16orLess +RenderTerrainPBRPlanarSampleCount 1 1 diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index eb3ead433b..dee6197b05 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -1,49 +1,17 @@ #!/bin/bash -## Here are some configuration options for Linux Client Testers. -## These options are for self-assisted troubleshooting during this beta -## testing phase; you should not usually need to touch them. +## Here are some configuration options for Linux Client Users. ## - Avoids using any FMOD STUDIO audio driver. #export LL_BAD_FMODSTUDIO_DRIVER=x ## - Avoids using any OpenAL audio driver. #export LL_BAD_OPENAL_DRIVER=x -## - Avoids using the FMOD Studio or FMOD Ex PulseAudio audio driver. +## - Avoids using the FMOD Studio PulseAudio audio driver. #export LL_BAD_FMOD_PULSEAUDIO=x -## - Avoids using the FMOD Studio or FMOD Ex ALSA audio driver. +## - Avoids using the FMOD Studio ALSA audio driver. #export LL_BAD_FMOD_ALSA=x -## - Avoids the optional OpenGL extensions which have proven most problematic -## on some hardware. Disabling this option may cause BETTER PERFORMANCE but -## may also cause CRASHES and hangs on some unstable combinations of drivers -## and hardware. -## NOTE: This is now disabled by default. -#export LL_GL_BASICEXT=x - -## - Avoids *all* optional OpenGL extensions. This is the safest and least- -## exciting option. Enable this if you experience stability issues, and -## report whether it helps in the Linux Client Testers forum. -#export LL_GL_NOEXT=x - -## - For advanced troubleshooters, this lets you disable specific GL -## extensions, each of which is represented by a letter a-o. If you can -## narrow down a stability problem on your system to just one or two -## extensions then please post details of your hardware (and drivers) to -## the Linux Client Testers forum along with the minimal -## LL_GL_BLACKLIST which solves your problems. -#export LL_GL_BLACKLIST=abcdefghijklmno - -## - Some ATI/Radeon users report random X server crashes when the mouse -## cursor changes shape. If you suspect that you are a victim of this -## driver bug, try enabling this option and report whether it helps: -#export LL_ATI_MOUSE_CURSOR_BUG=x - -if [ "`uname -m`" = "x86_64" ]; then - echo '64-bit Linux detected.' -fi - - ## Everything below this line is just for advanced troubleshooters. ##------------------------------------------------------------------- @@ -55,32 +23,6 @@ fi #export LL_WRAPPER='gdb --args' #export LL_WRAPPER='valgrind --smc-check=all --error-limit=no --log-file=secondlife.vg --leak-check=full --suppressions=/usr/lib/valgrind/glibc-2.5.supp --suppressions=secondlife-i686.supp' -## - Avoids an often-buggy X feature that doesn't really benefit us anyway. -export SDL_VIDEO_X11_DGAMOUSE=0 - -## - Works around a problem with misconfigured 64-bit systems not finding GL -I386_MULTIARCH="$(dpkg-architecture -ai386 -qDEB_HOST_MULTIARCH 2>/dev/null)" -MULTIARCH_ERR=$? -if [ $MULTIARCH_ERR -eq 0 ]; then - echo 'Multi-arch support detected.' - MULTIARCH_GL_DRIVERS="/usr/lib/${I386_MULTIARCH}/dri" - export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:${MULTIARCH_GL_DRIVERS}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri" -else - export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri" -fi - -## - The 'scim' GTK IM module widely crashes the viewer. Avoid it. -if [ "$GTK_IM_MODULE" = "scim" ]; then - export GTK_IM_MODULE=xim -fi - -## - Automatically work around the ATI mouse cursor crash bug: -## (this workaround is disabled as most fglrx users do not see the bug) -#if lsmod | grep fglrx &>/dev/null ; then -# export LL_ATI_MOUSE_CURSOR_BUG=x -#fi - - ## Nothing worth editing below this line. ##------------------------------------------------------------------- @@ -99,24 +41,7 @@ cd "${RUN_PATH}" ## subprocesses that care. export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" -# if [ -n "$LL_TCMALLOC" ]; then -# tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0' -# all=1 -# for f in $tcmalloc_libs; do -# if [ ! -f $f ]; then -# all=0 -# fi -# done -# if [ $all != 1 ]; then -# echo 'Cannot use tcmalloc libraries: components missing' 1>&2 -# else -# export LD_PRELOAD=$(echo $tcmalloc_libs | tr ' ' :) -# if [ -z "$HEAPCHECK" -a -z "$HEAPPROFILE" ]; then -# export HEAPCHECK=${HEAPCHECK:-normal} -# fi -# fi -#fi - +# Add our library directory export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}" # Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0ba86307a2..a2a7306c60 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -131,15 +131,17 @@ #include "stringize.h" #include "llcoros.h" #include "llexception.h" -#if !LL_LINUX #include "cef/dullahan_version.h" #include "vlc/libvlc_version.h" -#endif // LL_LINUX #if LL_DARWIN #include "llwindowmacosx.h" #endif +#if LL_SDL_WINDOW +#include "llwindowsdl.h" +#endif + // Third party library includes #include #include @@ -1345,6 +1347,8 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { + LL_RECORD_BLOCK_TIME(FTM_FRAME); + LL_PROFILE_GPU_ZONE("Frame"); #ifdef LL_DISCORD { LL_PROFILE_ZONE_NAMED("discord_callbacks"); @@ -1352,8 +1356,6 @@ bool LLAppViewer::doFrame() } #endif - 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) @@ -3413,7 +3415,6 @@ LLSD LLAppViewer::getViewerInfo() const info["VOICE_VERSION"] = LLTrans::getString("NotConnected"); } -#if !LL_LINUX std::ostringstream cef_ver_codec; cef_ver_codec << "Dullahan: "; cef_ver_codec << DULLAHAN_VERSION_MAJOR; @@ -3439,11 +3440,7 @@ LLSD LLAppViewer::getViewerInfo() const cef_ver_codec << CHROME_VERSION_PATCH; info["LIBCEF_VERSION"] = cef_ver_codec.str(); -#else - info["LIBCEF_VERSION"] = "Undefined"; -#endif -#if !LL_LINUX std::ostringstream vlc_ver_codec; vlc_ver_codec << LIBVLC_VERSION_MAJOR; vlc_ver_codec << "."; @@ -3451,9 +3448,6 @@ LLSD LLAppViewer::getViewerInfo() const vlc_ver_codec << "."; vlc_ver_codec << LIBVLC_VERSION_REVISION; info["LIBVLC_VERSION"] = vlc_ver_codec.str(); -#else - info["LIBVLC_VERSION"] = "Undefined"; -#endif S32 packets_in = (S32)LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); if (packets_in > 0) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 2b30920265..01b4e74784 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1146,6 +1146,8 @@ class LinuxManifest(ViewerManifest): # recurses, packaged again self.path("res-sdl") + # We copy ll_icon.BMP in CMakeLists.txt to newview/res-sdl and this will let the above self.path step take care of copying + # the correct branded icon # Get the icons based on the channel type icon_path = self.icon_path() print("DEBUG: icon_path '%s'" % icon_path) @@ -1154,6 +1156,9 @@ class LinuxManifest(ViewerManifest): with self.prefix(dst="res-sdl") : self.path("secondlife_256.BMP","ll_icon.BMP") + with self.prefix(src=os.path.join(self.args['build'], os.pardir, "llwebrtc" ), dst="lib"): + self.path("libllwebrtc.so") + # plugins with self.prefix(dst="bin/llplugin"): with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins')): @@ -1205,12 +1210,15 @@ class LinuxManifest(ViewerManifest): self.path("featuretable_linux.txt") self.path("cube.dae") - with self.prefix(src=pkgdir): + with self.prefix(src=pkgdir, dst="bin"): self.path("ca-bundle.crt") def package_finish(self): installer_name = self.installer_base_name() + # When running as a GitHub Action job, RUNNER_TEMP is defined as the tmp dir + RUNNER_TEMP = os.getenv('RUNNER_TEMP') + self.strip_binaries() # Fix access permissions @@ -1225,8 +1233,18 @@ class LinuxManifest(ViewerManifest): # temporarily move directory tree so that it has the right # name in the tarfile realname = self.get_dst_prefix() - tempname = self.build_path_of(installer_name) - self.run_command(["mv", realname, tempname]) + versionedName = self.build_path_of(installer_name) + + tarName = versionedName + ".tar.xz" + + # If using a github runner we divert packaging a little. Considering this wil be a VM/docker image + # we can just pack the final installer into RUNNER_TEMP and not into the usual stop we'd pick when + # not building a GHA release + if RUNNER_TEMP: + tarName = os.path.join(RUNNER_TEMP, self.package_file) + + self.run_command(["mv", realname, versionedName]) + try: # only create tarball if it's a release build. if self.args['buildtype'].lower() == 'release': @@ -1234,12 +1252,13 @@ class LinuxManifest(ViewerManifest): # security etc. self.run_command(['tar', '-C', self.get_build_prefix(), '--numeric-owner', '-cJf', - tempname + '.tar.xz', installer_name]) + tarName, installer_name]) + self.set_github_output_path('viewer_app', tarName) else: print("Skipping %s.tar.xz for non-Release build (%s)" % \ (installer_name, self.args['buildtype'])) finally: - self.run_command(["mv", tempname, realname]) + self.run_command(["mv", versionedName, realname]) def strip_binaries(self): if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer(): -- cgit v1.3 From 83dae23d29111b1bc51f1924523cced592078069 Mon Sep 17 00:00:00 2001 From: Rye Date: Tue, 14 Oct 2025 07:43:33 -0400 Subject: Disable viewer-manager in linux builds Signed-off-by: Rye --- indra/newview/llappviewer.cpp | 5 +++-- indra/newview/viewer_manifest.py | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a2a7306c60..f2e1326e96 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1113,7 +1113,7 @@ bool LLAppViewer::init() gGLActive = false; -#if LL_RELEASE_FOR_DOWNLOAD +#if LL_RELEASE_FOR_DOWNLOAD && !LL_LINUX // Skip updater if this is a non-interactive instance if (!gSavedSettings.getBOOL("CmdLineSkipUpdater") && !gNonInteractive) { @@ -1171,10 +1171,11 @@ bool LLAppViewer::init() } } else +#endif //LL_RELEASE_FOR_DOWNLOAD { + mUpdaterNotFound = true; LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL; } -#endif //LL_RELEASE_FOR_DOWNLOAD { // Iterate over --leap command-line options. But this is a bit tricky: if diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 01b4e74784..3a9f9c2f28 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1137,11 +1137,11 @@ class LinuxManifest(ViewerManifest): with self.prefix(dst="bin"): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") - self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") + #self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") self.path2basename("../llplugin/slplugin", "SLPlugin") #this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323 - with self.prefix(src="../viewer_components/manager", dst=""): - self.path("*.py") + #with self.prefix(src="../viewer_components/manager", dst=""): + # self.path("*.py") # recurses, packaged again self.path("res-sdl") -- cgit v1.3 From 5a875a61881b4109a0d33caa6039a84372b33a95 Mon Sep 17 00:00:00 2001 From: Rye Date: Tue, 28 Oct 2025 08:00:07 -0400 Subject: Rework anisotropic filtering options into a dropdown with levels for better performance tuning of low end gpu Signed-off-by: Rye --- indra/llrender/llimagegl.cpp | 1 - indra/llrender/llimagegl.h | 1 - indra/llrender/llrender.cpp | 7 ++- indra/llrender/llrender.h | 1 + indra/newview/app_settings/settings.xml | 13 +++++- indra/newview/featuretable.txt | 30 +++++++----- indra/newview/featuretable_linux.txt | 30 +++++++----- indra/newview/featuretable_mac.txt | 29 +++++++----- indra/newview/llappviewer.cpp | 2 +- indra/newview/llfeaturemanager.cpp | 5 +- .../llfloaterpreferencesgraphicsadvanced.cpp | 20 ++++++++ indra/newview/llviewercontrol.cpp | 18 ++++++-- .../en/floater_preferences_graphics_advanced.xml | 54 +++++++++++++++++----- 13 files changed, 155 insertions(+), 56 deletions(-) (limited to 'indra/newview/llappviewer.cpp') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 7757c9a13a..3165cb313b 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -138,7 +138,6 @@ U32 LLImageGL::sUniqueCount = 0; U32 LLImageGL::sBindCount = 0; S32 LLImageGL::sCount = 0; -bool LLImageGL::sGlobalUseAnisotropic = false; F32 LLImageGL::sLastFrameTime = 0.f; LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; bool LLImageGL::sCompressTextures = false; diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 6b4492c09e..773b647d69 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -285,7 +285,6 @@ public: // Global memory statistics static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame - static bool sGlobalUseAnisotropic; static LLImageGL* sDefaultGLTexture ; static bool sAutomatedTest; static bool sCompressTextures; //use GL texture compression diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 970a9f6975..0d7ebd4a25 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -71,6 +71,7 @@ S32 gGLViewport[4]; U32 LLRender::sUICalls = 0; U32 LLRender::sUIVerts = 0; U32 LLTexUnit::sWhiteTexture = 0; +F32 LLRender::sAnisotropicFilteringLevel = 0.f; bool LLRender::sGLCoreProfile = false; bool LLRender::sNsightDebugSupport = false; LLVector2 LLRender::sUIGLScaleFactor = LLVector2(1.f, 1.f); @@ -524,9 +525,11 @@ void LLTexUnit::setTextureFilteringOptionFast(LLTexUnit::eTextureFilterOptions o if (gGLManager.mHasAnisotropic) { - if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) + if (option == TFO_ANISOTROPIC && LLRender::sAnisotropicFilteringLevel > 1.f) { - glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); + F32 aniso_level = llclamp(LLRender::sAnisotropicFilteringLevel, 1.f, gGLManager.mMaxAnisotropy); + glTexParameterf(sGLTextureType[tex_type], GL_TEXTURE_MAX_ANISOTROPY, aniso_level); + } else { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index bc1fb3ce40..4bfc5723ee 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -489,6 +489,7 @@ public: public: static U32 sUICalls; static U32 sUIVerts; + static F32 sAnisotropicFilteringLevel; static bool sGLCoreProfile; static bool sNsightDebugSupport; static LLVector2 sUIGLScaleFactor; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 94c7a97ccc..05e3e7aaa2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7241,7 +7241,7 @@ RenderAnisotropic Comment - Render textures using anisotropic filtering + [OBSOLETE] Render textures using anisotropic filtering Persist 1 Type @@ -7249,6 +7249,17 @@ Value 0 + RenderAnisotropicLevel + + Comment + Anisotropic filtering strength(0(Disable), 2x, 4x, 8x, 16x + Persist + 1 + Type + U32 + Value + 0 + RenderAppleUseMultGL Comment diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 1090dd8ffb..eca58938cf 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 74 +version 75 // 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 @@ -27,7 +27,7 @@ version 74 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 16 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 @@ -92,7 +92,7 @@ RenderReflectionProbeCount 1 256 // Low Graphics Settings // list Low -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 @@ -135,7 +135,7 @@ RenderReflectionProbeCount 1 1 // Medium Low Graphics Settings // list LowMid -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 @@ -178,7 +178,7 @@ RenderReflectionProbeCount 1 32 // Medium Graphics Settings (standard) // list Mid -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -220,7 +220,7 @@ RenderReflectionProbeCount 1 64 // Medium High Graphics Settings // list MidHigh -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -262,7 +262,7 @@ RenderReflectionProbeCount 1 64 // High Graphics Settings (SSAO + sun shadows) // list High -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -301,10 +301,10 @@ RenderMaxTextureResolution 1 2048 RenderReflectionProbeCount 1 128 // -// High Ultra Graphics Settings (deferred + SSAO + all shadows) +// High Ultra Graphics Settings (SSAO + all shadows) // list HighUltra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 350000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -346,7 +346,7 @@ RenderReflectionProbeCount 1 256 // Ultra graphics (REALLY PURTY!) // list Ultra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 8 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarPhysicsLODFactor 1 1.0 @@ -399,11 +399,17 @@ RenderDisableVintageMode 1 0 list VRAMGT512 RenderCompressTextures 1 0 +// +// AF Missing or AF < 2 +// +list AnisotropicMissing +RenderAnisotropicLevel 0 0 + // // "Default" setups for safe, low, medium, high // list safe -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderLocalLightCount 1 0 @@ -419,7 +425,7 @@ RenderMaxTextureResolution 1 2048 RenderReflectionProbeCount 0 0 list Intel -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderFSAAType 1 0 RenderFSAASamples 1 0 RenderGLContextCoreProfile 1 0 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index c53e828020..a160161ef1 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 33 +version 34 // 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 @@ -27,7 +27,7 @@ version 33 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 16 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 @@ -92,7 +92,7 @@ RenderReflectionProbeCount 1 256 // Low Graphics Settings // list Low -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 @@ -135,7 +135,7 @@ RenderReflectionProbeCount 1 1 // Medium Low Graphics Settings // list LowMid -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 @@ -178,7 +178,7 @@ RenderReflectionProbeCount 1 32 // Medium Graphics Settings (standard) // list Mid -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -220,7 +220,7 @@ RenderReflectionProbeCount 1 64 // Medium High Graphics Settings // list MidHigh -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -262,7 +262,7 @@ RenderReflectionProbeCount 1 64 // High Graphics Settings (SSAO + sun shadows) // list High -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -301,10 +301,10 @@ RenderMaxTextureResolution 1 2048 RenderReflectionProbeCount 1 128 // -// High Ultra Graphics Settings (deferred + SSAO + all shadows) +// High Ultra Graphics Settings (SSAO + all shadows) // list HighUltra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 350000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -346,7 +346,7 @@ RenderReflectionProbeCount 1 256 // Ultra graphics (REALLY PURTY!) // list Ultra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 8 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarPhysicsLODFactor 1 1.0 @@ -399,11 +399,17 @@ RenderDisableVintageMode 1 0 list VRAMGT512 RenderCompressTextures 1 0 +// +// AF Missing or AF < 2 +// +list AnisotropicMissing +RenderAnisotropicLevel 0 0 + // // "Default" setups for safe, low, medium, high // list safe -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderLocalLightCount 1 0 @@ -419,7 +425,7 @@ RenderMaxTextureResolution 1 2048 RenderReflectionProbeCount 0 0 list Intel -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderFSAAType 1 0 RenderFSAASamples 1 0 RenderGLContextCoreProfile 1 0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index c3e2dd0c41..b75df5e3f2 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 73 +version 74 // 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 @@ -27,7 +27,7 @@ version 73 // NOTE: All settings are set to the MIN of applied values, including 'all'! // list all -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 16 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 @@ -92,7 +92,7 @@ RenderReflectionProbeCount 1 256 // Low Graphics Settings // list Low -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 @@ -135,7 +135,7 @@ RenderReflectionProbeCount 1 1 // Medium Low Graphics Settings // list LowMid -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 @@ -178,7 +178,7 @@ RenderReflectionProbeCount 1 32 // Medium Graphics Settings (standard) // list Mid -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -220,7 +220,7 @@ RenderReflectionProbeCount 1 64 // Medium High Graphics Settings // list MidHigh -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -262,7 +262,7 @@ RenderReflectionProbeCount 1 64 // High Graphics Settings (SSAO + sun shadows) // list High -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 @@ -304,7 +304,7 @@ RenderReflectionProbeCount 1 128 // High Ultra Graphics Settings (SSAO + all shadows) // list HighUltra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 2 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 350000 @@ -346,7 +346,7 @@ RenderReflectionProbeCount 1 256 // Ultra graphics (REALLY PURTY!) // list Ultra -RenderAnisotropic 1 1 +RenderAnisotropicLevel 1 4 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 @@ -400,11 +400,18 @@ RenderDisableVintageMode 1 0 list VRAMGT512 RenderCompressTextures 1 0 +// +// +// AF Missing or AF < 2 +// +list AnisotropicMissing +RenderAnisotropicLevel 0 0 + // // "Default" setups for safe, low, medium, high // list safe -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderLocalLightCount 1 0 @@ -434,7 +441,7 @@ RenderGLMultiThreadedMedia 1 0 RenderAppleUseMultGL 1 0 list Intel -RenderAnisotropic 1 0 +RenderAnisotropicLevel 1 0 RenderFSAASamples 1 0 RenderGLMultiThreadedTextures 1 0 RenderGLMultiThreadedMedia 1 0 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f2e1326e96..f3970ed1a8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -547,7 +547,7 @@ static void settings_to_globals() LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile"); #endif LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); - LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); + LLRender::sAnisotropicFilteringLevel = static_cast(gSavedSettings.getU32("RenderAnisotropicLevel")); LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR); LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index ac19c08be8..e0a3cf04ec 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -260,7 +260,6 @@ bool LLFeatureManager::loadFeatureTables() // *TODO - if I or anyone else adds something else to the skipped list // make this data driven. Put it in the feature table and parse it // correctly - mSkippedFeatures.insert("RenderAnisotropic"); mSkippedFeatures.insert("RenderGamma"); mSkippedFeatures.insert("RenderVBOEnable"); mSkippedFeatures.insert("RenderFogRatio"); @@ -709,6 +708,10 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("VRAMLT2GB"); } + if (!gGLManager.mHasAnisotropic || 2.f > gGLManager.mMaxAnisotropy) + { + maskFeatures("AnisotropicMissing"); + } if (gGLManager.mGLVersion < 3.99f) { maskFeatures("GL3"); diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp index 85c027c84e..96c2e1e1e4 100644 --- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp @@ -340,6 +340,12 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() tonemapMix->setEnabled(is_not_vintage); exposureSlider->setEnabled(is_not_vintage); cas_slider->setEnabled(is_not_vintage); + + LLComboBox* ctrl_anisotropic = getChild("anisotropic_filter"); + if (!LLFeatureManager::instance().isFeatureAvailable("RenderAnisotropicLevel")) + { + ctrl_anisotropic->setEnabled(false); + } } void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() @@ -384,6 +390,20 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")); + LLComboBox* af_combo = getChild("anisotropic_filter"); + if (2.f > gGLManager.mMaxAnisotropy) { + af_combo->remove("2x"); + } + if (4.f > gGLManager.mMaxAnisotropy) { + af_combo->remove("4x"); + } + if (8.f > gGLManager.mMaxAnisotropy) { + af_combo->remove("8x"); + } + if (16.f > gGLManager.mMaxAnisotropy) { + af_combo->remove("16x"); + } + // now turn off any features that are unavailable disableUnavailableSettings(); } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 75cc76fee6..411eb3a47e 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -293,9 +293,14 @@ static bool handleLUTBufferChanged(const LLSD& newvalue) return true; } -static bool handleAnisotropicChanged(const LLSD& newvalue) +static bool handleAnisotropicFilteringChanged(const LLSD& newval) { - LLImageGL::sGlobalUseAnisotropic = newvalue.asBoolean(); + F32 val = static_cast(newval.asReal()); + if (val > gGLManager.mMaxAnisotropy) + { + val = llclamp(val, 0.f, gGLManager.mMaxAnisotropy); + } + LLRender::sAnisotropicFilteringLevel = val; LLImageGL::dirtyTexOptions(); return true; } @@ -317,6 +322,12 @@ static bool handleVSyncChanged(const LLSD& newvalue) return true; } +static bool validateAnisotropicFiltering(const LLSD& val) +{ + S32 filter_level = val.asInteger(); + return filter_level == 0 || filter_level == 2 || filter_level == 4 || filter_level == 8 || filter_level == 16; +} + static bool handleVolumeLODChanged(const LLSD& newvalue) { LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR); @@ -832,7 +843,8 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); - setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAnisotropicLevel", handleAnisotropicFilteringChanged); + gSavedSettings.getControl("RenderAnisotropicLevel")->getValidateSignal()->connect(boost::bind(&validateAnisotropicFiltering, _2)); setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized); setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); 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 2a18134491..3ba772e8d7 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 @@ -360,17 +360,6 @@ Hardware - - - + + Anisotropic Filtering: + + + + + + + + +